diff --git a/.ci/Jenkinsfile_coverage b/.ci/Jenkinsfile_coverage index 3f4732f15f334..650ef94e1d3da 100644 --- a/.ci/Jenkinsfile_coverage +++ b/.ci/Jenkinsfile_coverage @@ -11,8 +11,11 @@ kibanaPipeline(timeoutMinutes: 240) { 'CODE_COVERAGE=1', // Enables coverage. Needed for multiple ci scripts, such as remote.ts, test/scripts/*.sh, schema.js, etc. ]) { workers.base(name: 'coverage-worker', size: 'l', ramDisk: false, bootstrapped: false) { - kibanaCoverage.runTests() - handleIngestion(TIME_STAMP) + catchError { + kibanaCoverage.runTests() + handleIngestion(TIME_STAMP) + } + handleFail() } } kibanaPipeline.sendMail() @@ -29,4 +32,13 @@ def handleIngestion(timestamp) { kibanaCoverage.uploadCoverageStaticSite(timestamp) } +def handleFail() { + def buildStatus = buildUtils.getBuildStatus() + if(params.NOTIFY_ON_FAILURE && buildStatus != 'SUCCESS' && buildStatus != 'ABORTED') { + slackNotifications.sendFailedBuild( + channel: '#kibana-qa', + username: 'Kibana QA' + ) + } +} diff --git a/.eslintrc.js b/.eslintrc.js index ec5916c9a3ac7..c33f4de15b919 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -225,7 +225,7 @@ module.exports = { '!src/core/server/index.ts', // relative import '!src/core/server/mocks{,.ts}', '!src/core/server/types{,.ts}', - '!src/core/server/test_utils', + '!src/core/server/test_utils{,.ts}', // for absolute imports until fixed in // https://github.com/elastic/kibana/issues/36096 '!src/core/server/*.test.mocks{,.ts}', @@ -587,11 +587,11 @@ module.exports = { }, /** - * SIEM overrides + * Security Solution overrides */ { // front end typescript and javascript files only - files: ['x-pack/plugins/siem/public/**/*.{js,ts,tsx}'], + files: ['x-pack/plugins/security_solution/public/**/*.{js,ts,tsx}'], rules: { 'import/no-nodejs-modules': 'error', 'no-restricted-imports': [ @@ -605,7 +605,7 @@ module.exports = { }, { // typescript only for front and back end - files: ['x-pack/{,legacy/}plugins/siem/**/*.{ts,tsx}'], + files: ['x-pack/{,legacy/}plugins/security_solution/**/*.{ts,tsx}'], rules: { // This will be turned on after bug fixes are complete // '@typescript-eslint/explicit-member-accessibility': 'warn', @@ -640,7 +640,7 @@ module.exports = { // { // // will introduced after the other warns are fixed // // typescript and javascript for front end react performance - // files: ['x-pack/plugins/siem/public/**/!(*.test).{js,ts,tsx}'], + // files: ['x-pack/plugins/security_solution/public/**/!(*.test).{js,ts,tsx}'], // plugins: ['react-perf'], // rules: { // // 'react-perf/jsx-no-new-object-as-prop': 'error', @@ -651,7 +651,7 @@ module.exports = { // }, { // typescript and javascript for front and back end - files: ['x-pack/{,legacy/}plugins/siem/**/*.{js,ts,tsx}'], + files: ['x-pack/{,legacy/}plugins/security_solution/**/*.{js,ts,tsx}'], plugins: ['eslint-plugin-node', 'react'], env: { mocha: true, @@ -758,10 +758,6 @@ module.exports = { 'react/jsx-no-target-blank': 'error', 'react/jsx-fragments': 'error', 'react/jsx-sort-default-props': 'error', - // might be introduced after the other warns are fixed - // 'react/jsx-sort-props': 'error', - // might be introduced after the other warns are fixed - 'react-hooks/exhaustive-deps': 'off', 'require-atomic-updates': 'error', 'symbol-description': 'error', 'vars-on-top': 'error', diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 83f4f90b9204d..472d29ed29413 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -34,9 +34,11 @@ /src/legacy/core_plugins/kibana/public/home/np_ready/ @elastic/kibana-core-ui # App Architecture +/examples/developer_examples/ @elastic/kibana-app-arch /examples/url_generators_examples/ @elastic/kibana-app-arch /examples/url_generators_explorer/ @elastic/kibana-app-arch /packages/kbn-interpreter/ @elastic/kibana-app-arch +/packages/elastic-datemath/ @elastic/kibana-app-arch /src/legacy/core_plugins/embeddable_api/ @elastic/kibana-app-arch /src/legacy/core_plugins/interpreter/ @elastic/kibana-app-arch /src/legacy/core_plugins/kibana_react/ @elastic/kibana-app-arch @@ -139,6 +141,7 @@ /config/kibana.yml @elastic/kibana-platform /x-pack/plugins/features/ @elastic/kibana-platform /x-pack/plugins/licensing/ @elastic/kibana-platform +/x-pack/plugins/global_search/ @elastic/kibana-platform /x-pack/plugins/cloud/ @elastic/kibana-platform /packages/kbn-config-schema/ @elastic/kibana-platform /src/legacy/server/config/ @elastic/kibana-platform @@ -225,12 +228,12 @@ /x-pack/test/plugin_functional/plugins/resolver_test/ @elastic/endpoint-app-team @elastic/siem /x-pack/test/plugin_functional/test_suites/resolver/ @elastic/endpoint-app-team @elastic/siem -# SIEM -/x-pack/plugins/siem/ @elastic/siem @elastic/endpoint-app-team +# Security Solution +/x-pack/plugins/security_solution/ @elastic/siem @elastic/endpoint-app-team /x-pack/test/detection_engine_api_integration @elastic/siem @elastic/endpoint-app-team -/x-pack/test/api_integration/apis/siem @elastic/siem @elastic/endpoint-app-team +/x-pack/test/api_integration/apis/security_solution @elastic/siem @elastic/endpoint-app-team /x-pack/plugins/case @elastic/siem @elastic/endpoint-app-team /x-pack/plugins/lists @elastic/siem @elastic/endpoint-app-team # Security Intelligence And Analytics -/x-pack/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules @elastic/security-intelligence-analytics +/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules @elastic/security-intelligence-analytics diff --git a/.node-version b/.node-version index 5b7269c0a98f3..b61c07ffddbd1 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -10.19.0 +10.21.0 diff --git a/.nvmrc b/.nvmrc index 5b7269c0a98f3..b61c07ffddbd1 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -10.19.0 +10.21.0 diff --git a/.sass-lint.yml b/.sass-lint.yml index db895583eb8a7..eb43af293c670 100644 --- a/.sass-lint.yml +++ b/.sass-lint.yml @@ -4,7 +4,6 @@ files: - 'src/legacy/core_plugins/timelion/**/*.s+(a|c)ss' - 'src/plugins/vis_type_vislib/**/*.s+(a|c)ss' - 'src/plugins/vis_type_xy/**/*.s+(a|c)ss' - - 'x-pack/legacy/plugins/security/**/*.s+(a|c)ss' - 'x-pack/plugins/canvas/**/*.s+(a|c)ss' - 'x-pack/plugins/triggers_actions_ui/**/*.s+(a|c)ss' - 'x-pack/plugins/lens/**/*.s+(a|c)ss' @@ -12,6 +11,7 @@ files: - 'x-pack/legacy/plugins/maps/**/*.s+(a|c)ss' - 'x-pack/plugins/maps/**/*.s+(a|c)ss' - 'x-pack/plugins/spaces/**/*.s+(a|c)ss' + - 'x-pack/plugins/security/**/*.s+(a|c)ss' ignore: - 'x-pack/plugins/canvas/shareable_runtime/**/*.s+(a|c)ss' rules: diff --git a/Jenkinsfile b/Jenkinsfile index f435b18c6d824..b6a36c79f877d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -41,9 +41,10 @@ kibanaPipeline(timeoutMinutes: 155, checkPrChanges: true) { 'xpack-ciGroup9': kibanaPipeline.xpackCiGroupProcess(9), 'xpack-ciGroup10': kibanaPipeline.xpackCiGroupProcess(10), 'xpack-accessibility': kibanaPipeline.functionalTestProcess('xpack-accessibility', './test/scripts/jenkins_xpack_accessibility.sh'), - 'xpack-siemCypress': { processNumber -> - whenChanged(['x-pack/plugins/siem/', 'x-pack/test/siem_cypress/']) { - kibanaPipeline.functionalTestProcess('xpack-siemCypress', './test/scripts/jenkins_siem_cypress.sh')(processNumber) + 'xpack-pageLoadMetrics': kibanaPipeline.functionalTestProcess('xpack-pageLoadMetrics', './test/scripts/jenkins_xpack_page_load_metrics.sh'), + 'xpack-securitySolutionCypress': { processNumber -> + whenChanged(['x-pack/plugins/security_solution/', 'x-pack/test/security_solution_cypress/']) { + kibanaPipeline.functionalTestProcess('xpack-securitySolutionCypress', './test/scripts/jenkins_security_solution_cypress.sh')(processNumber) } }, diff --git a/docs/apm/advanced-queries.asciidoc b/docs/apm/advanced-queries.asciidoc index f89f994e59e57..7b771eb662616 100644 --- a/docs/apm/advanced-queries.asciidoc +++ b/docs/apm/advanced-queries.asciidoc @@ -11,7 +11,7 @@ or, to only show transactions that are slower than a specified time threshold. ==== Example APM app queries * Exclude response times slower than 2000 ms: `transaction.duration.us > 2000000` -* Filter by response status code: `context.response.status_code >= 400` +* Filter by response status code: `context.response.status_code ≥ 400` * Filter by single user ID: `context.user.id : 12` When querying in the APM app, you're merely searching and selecting data from fields in Elasticsearch documents. diff --git a/docs/apm/service-maps.asciidoc b/docs/apm/service-maps.asciidoc index 3a6a96fca9d09..db2f85c54c762 100644 --- a/docs/apm/service-maps.asciidoc +++ b/docs/apm/service-maps.asciidoc @@ -62,9 +62,9 @@ Machine learning jobs can be created to calculate anomaly scores on APM transact When these jobs are active, service maps will display a color-coded anomaly indicator based on the detected anomaly score: [horizontal] -image:apm/images/green-service.png[APM green service]:: Max anomaly score **<=25**. Service is healthy. +image:apm/images/green-service.png[APM green service]:: Max anomaly score **≤25**. Service is healthy. image:apm/images/yellow-service.png[APM yellow service]:: Max anomaly score **26-74**. Anomalous activity detected. Service may be degraded. -image:apm/images/red-service.png[APM red service]:: Max anomaly score **>=75**. Anomalous activity detected. Service is unhealthy. +image:apm/images/red-service.png[APM red service]:: Max anomaly score **≥75**. Anomalous activity detected. Service is unhealthy. [role="screenshot"] image::apm/images/apm-service-map-anomaly.png[Example view of anomaly scores on service maps in the APM app] @@ -92,10 +92,10 @@ Type and subtype are based on `span.type`, and `span.subtype`. Service maps are supported for the following Agent versions: [horizontal] -Go Agent:: >= v1.7.0 -Java Agent:: >= v1.13.0 -.NET Agent:: >= v1.3.0 -Node.js Agent:: >= v3.6.0 -Python Agent:: >= v5.5.0 -Ruby Agent:: >= v3.6.0 -Real User Monitoring (RUM) Agent:: >= v4.7.0 +Go Agent:: ≥ v1.7.0 +Java Agent:: ≥ v1.13.0 +.NET Agent:: ≥ v1.3.0 +Node.js Agent:: ≥ v3.6.0 +Python Agent:: ≥ v5.5.0 +Ruby Agent:: ≥ v3.6.0 +Real User Monitoring (RUM) Agent:: ≥ v4.7.0 diff --git a/docs/dev-tools/console/console.asciidoc b/docs/dev-tools/console/console.asciidoc index caffef7995fbf..9f225986d5df0 100644 --- a/docs/dev-tools/console/console.asciidoc +++ b/docs/dev-tools/console/console.asciidoc @@ -44,7 +44,7 @@ curl -XGET "http://localhost:9200/_search" -d' ---------------------------------- When you paste the command into Console, {kib} automatically converts it -to Console syntax. Alternatively, if you want to want to see Console syntax in cURL, +to Console syntax. Alternatively, if you want to see Console syntax in cURL, click the action icon (image:dev-tools/console/images/wrench.png[]) and select *Copy as cURL*. [float] diff --git a/docs/development/core/public/kibana-plugin-core-public.md b/docs/development/core/public/kibana-plugin-core-public.md index 9e4afe0f5133c..7c7c9729504de 100644 --- a/docs/development/core/public/kibana-plugin-core-public.md +++ b/docs/development/core/public/kibana-plugin-core-public.md @@ -132,6 +132,12 @@ The plugin integrates with the core system via lifecycle events: `setup` | [URLMeaningfulParts](./kibana-plugin-core-public.urlmeaningfulparts.md) | We define our own typings because the current version of @types/node declares properties to be optional "hostname?: string". Although, parse call returns "hostname: null \| string". | | [UserProvidedValues](./kibana-plugin-core-public.userprovidedvalues.md) | Describes the values explicitly set by user. | +## Variables + +| Variable | Description | +| --- | --- | +| [URL\_MAX\_LENGTH](./kibana-plugin-core-public.url_max_length.md) | The max URL length allowed by the current browser. Should be used to display warnings to users when query parameters cause URL to exceed this limit. | + ## Type Aliases | Type Alias | Description | diff --git a/docs/development/core/public/kibana-plugin-core-public.url_max_length.md b/docs/development/core/public/kibana-plugin-core-public.url_max_length.md new file mode 100644 index 0000000000000..993320d51909a --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.url_max_length.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [URL\_MAX\_LENGTH](./kibana-plugin-core-public.url_max_length.md) + +## URL\_MAX\_LENGTH variable + +The max URL length allowed by the current browser. Should be used to display warnings to users when query parameters cause URL to exceed this limit. + +Signature: + +```typescript +URL_MAX_LENGTH: number +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md index 4159247bb7c32..6256709e2ee36 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md @@ -9,7 +9,7 @@ Constructs a new instance of the `IndexPattern` class Signature: ```typescript -constructor(id: string | undefined, getConfig: any, savedObjectsClient: SavedObjectsClientContract, apiClient: IIndexPatternsApiClient, patternCache: any); +constructor(id: string | undefined, getConfig: any, savedObjectsClient: SavedObjectsClientContract, apiClient: IIndexPatternsApiClient, patternCache: PatternCache); ``` ## Parameters @@ -20,5 +20,5 @@ constructor(id: string | undefined, getConfig: any, savedObjectsClient: SavedObj | getConfig | any | | | savedObjectsClient | SavedObjectsClientContract | | | apiClient | IIndexPatternsApiClient | | -| patternCache | any | | +| patternCache | PatternCache | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.core.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.core.md deleted file mode 100644 index 7a7ea43bd3d40..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.core.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [ISearchContext](./kibana-plugin-plugins-data-public.isearchcontext.md) > [core](./kibana-plugin-plugins-data-public.isearchcontext.core.md) - -## ISearchContext.core property - -Signature: - -```typescript -core: CoreStart; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.getsearchstrategy.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.getsearchstrategy.md deleted file mode 100644 index 93ac88d200bb8..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.getsearchstrategy.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [ISearchContext](./kibana-plugin-plugins-data-public.isearchcontext.md) > [getSearchStrategy](./kibana-plugin-plugins-data-public.isearchcontext.getsearchstrategy.md) - -## ISearchContext.getSearchStrategy property - -Signature: - -```typescript -getSearchStrategy: (name: T) => TSearchStrategyProvider; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.md deleted file mode 100644 index 9b89f71434119..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.isearchcontext.md +++ /dev/null @@ -1,19 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [ISearchContext](./kibana-plugin-plugins-data-public.isearchcontext.md) - -## ISearchContext interface - -Signature: - -```typescript -export interface ISearchContext -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [core](./kibana-plugin-plugins-data-public.isearchcontext.core.md) | CoreStart | | -| [getSearchStrategy](./kibana-plugin-plugins-data-public.isearchcontext.getsearchstrategy.md) | <T extends TStrategyTypes>(name: T) => TSearchStrategyProvider<T> | | - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md index 02cc34baf7c45..e818fb009fb19 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md @@ -67,7 +67,6 @@ | [IndexPatternTypeMeta](./kibana-plugin-plugins-data-public.indexpatterntypemeta.md) | | | [IRequestTypesMap](./kibana-plugin-plugins-data-public.irequesttypesmap.md) | | | [IResponseTypesMap](./kibana-plugin-plugins-data-public.iresponsetypesmap.md) | | -| [ISearchContext](./kibana-plugin-plugins-data-public.isearchcontext.md) | | | [ISearchOptions](./kibana-plugin-plugins-data-public.isearchoptions.md) | | | [ISearchStrategy](./kibana-plugin-plugins-data-public.isearchstrategy.md) | Search strategy interface contains a search method that takes in a request and returns a promise that resolves to a response. | | [ISyncSearchRequest](./kibana-plugin-plugins-data-public.isyncsearchrequest.md) | | @@ -114,6 +113,7 @@ | [SearchBar](./kibana-plugin-plugins-data-public.searchbar.md) | | | [SYNC\_SEARCH\_STRATEGY](./kibana-plugin-plugins-data-public.sync_search_strategy.md) | | | [syncQueryStateWithUrl](./kibana-plugin-plugins-data-public.syncquerystatewithurl.md) | Helper to setup syncing of global data with the URL | +| [UI\_SETTINGS](./kibana-plugin-plugins-data-public.ui_settings.md) | | ## Type Aliases @@ -156,5 +156,4 @@ | [TabbedAggRow](./kibana-plugin-plugins-data-public.tabbedaggrow.md) | \* | | [TimefilterContract](./kibana-plugin-plugins-data-public.timefiltercontract.md) | | | [TimeHistoryContract](./kibana-plugin-plugins-data-public.timehistorycontract.md) | | -| [TSearchStrategyProvider](./kibana-plugin-plugins-data-public.tsearchstrategyprovider.md) | Search strategy provider creates an instance of a search strategy with the request handler context bound to it. This way every search strategy can use whatever information they require from the request context. | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.plugin._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.plugin._constructor_.md index 5ec2d491295bf..64108a7c7be33 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.plugin._constructor_.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.plugin._constructor_.md @@ -9,12 +9,12 @@ Constructs a new instance of the `DataPublicPlugin` class Signature: ```typescript -constructor(initializerContext: PluginInitializerContext); +constructor(initializerContext: PluginInitializerContext); ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| initializerContext | PluginInitializerContext | | +| initializerContext | PluginInitializerContext<ConfigSchema> | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.plugin.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.plugin.md index 6cbc1f441c048..0dad92a0a27ca 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.plugin.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.plugin.md @@ -7,14 +7,14 @@ Signature: ```typescript -export declare function plugin(initializerContext: PluginInitializerContext): DataPublicPlugin; +export declare function plugin(initializerContext: PluginInitializerContext): DataPublicPlugin; ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| initializerContext | PluginInitializerContext | | +| initializerContext | PluginInitializerContext<ConfigSchema> | | Returns: diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.tsearchstrategyprovider.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.tsearchstrategyprovider.md deleted file mode 100644 index 3233bb48cea2c..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.tsearchstrategyprovider.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [TSearchStrategyProvider](./kibana-plugin-plugins-data-public.tsearchstrategyprovider.md) - -## TSearchStrategyProvider type - -Search strategy provider creates an instance of a search strategy with the request handler context bound to it. This way every search strategy can use whatever information they require from the request context. - -Signature: - -```typescript -export declare type TSearchStrategyProvider = (context: ISearchContext) => ISearchStrategy; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ui_settings.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ui_settings.md new file mode 100644 index 0000000000000..a48f4920b3d26 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ui_settings.md @@ -0,0 +1,39 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [UI\_SETTINGS](./kibana-plugin-plugins-data-public.ui_settings.md) + +## UI\_SETTINGS variable + +Signature: + +```typescript +UI_SETTINGS: { + META_FIELDS: string; + DOC_HIGHLIGHT: string; + QUERY_STRING_OPTIONS: string; + QUERY_ALLOW_LEADING_WILDCARDS: string; + SEARCH_QUERY_LANGUAGE: string; + SORT_OPTIONS: string; + COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX: string; + COURIER_SET_REQUEST_PREFERENCE: string; + COURIER_CUSTOM_REQUEST_PREFERENCE: string; + COURIER_MAX_CONCURRENT_SHARD_REQUESTS: string; + COURIER_BATCH_SEARCHES: string; + SEARCH_INCLUDE_FROZEN: string; + HISTOGRAM_BAR_TARGET: string; + HISTOGRAM_MAX_BARS: string; + HISTORY_LIMIT: string; + SHORT_DOTS_ENABLE: string; + FORMAT_DEFAULT_TYPE_MAP: string; + FORMAT_NUMBER_DEFAULT_PATTERN: string; + FORMAT_PERCENT_DEFAULT_PATTERN: string; + FORMAT_BYTES_DEFAULT_PATTERN: string; + FORMAT_CURRENCY_DEFAULT_PATTERN: string; + FORMAT_NUMBER_DEFAULT_LOCALE: string; + TIMEPICKER_REFRESH_INTERVAL_DEFAULTS: string; + TIMEPICKER_QUICK_RANGES: string; + INDEXPATTERN_PLACEHOLDER: string; + FILTERS_PINNED_BY_DEFAULT: string; + FILTERS_EDITOR_SUGGEST_VALUES: string; +} +``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.config.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.config.md new file mode 100644 index 0000000000000..49b5f6040fc84 --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.config.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [config](./kibana-plugin-plugins-data-server.config.md) + +## config variable + +Signature: + +```typescript +config: PluginConfigDescriptor +``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md index e756eb9b72905..0efbe8ed4ed64 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md @@ -55,12 +55,14 @@ | Variable | Description | | --- | --- | | [castEsToKbnFieldTypeName](./kibana-plugin-plugins-data-server.castestokbnfieldtypename.md) | Get the KbnFieldType name for an esType string | +| [config](./kibana-plugin-plugins-data-server.config.md) | | | [esFilters](./kibana-plugin-plugins-data-server.esfilters.md) | | | [esKuery](./kibana-plugin-plugins-data-server.eskuery.md) | | | [esQuery](./kibana-plugin-plugins-data-server.esquery.md) | | | [fieldFormats](./kibana-plugin-plugins-data-server.fieldformats.md) | | | [indexPatterns](./kibana-plugin-plugins-data-server.indexpatterns.md) | | | [search](./kibana-plugin-plugins-data-server.search.md) | | +| [UI\_SETTINGS](./kibana-plugin-plugins-data-server.ui_settings.md) | | ## Type Aliases diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin._constructor_.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin._constructor_.md index 454d8a059a252..4a0a159310b9d 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin._constructor_.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin._constructor_.md @@ -9,12 +9,12 @@ Constructs a new instance of the `DataServerPlugin` class Signature: ```typescript -constructor(initializerContext: PluginInitializerContext); +constructor(initializerContext: PluginInitializerContext); ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| initializerContext | PluginInitializerContext | | +| initializerContext | PluginInitializerContext<ConfigSchema> | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.md index b3ba75ce29ab6..1773871d946a2 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.md @@ -9,14 +9,14 @@ Static code to be shared externally Signature: ```typescript -export declare function plugin(initializerContext: PluginInitializerContext): DataServerPlugin; +export declare function plugin(initializerContext: PluginInitializerContext): DataServerPlugin; ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| initializerContext | PluginInitializerContext | | +| initializerContext | PluginInitializerContext<ConfigSchema> | | Returns: diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ui_settings.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ui_settings.md new file mode 100644 index 0000000000000..855cfd11d00ea --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ui_settings.md @@ -0,0 +1,39 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [UI\_SETTINGS](./kibana-plugin-plugins-data-server.ui_settings.md) + +## UI\_SETTINGS variable + +Signature: + +```typescript +UI_SETTINGS: { + META_FIELDS: string; + DOC_HIGHLIGHT: string; + QUERY_STRING_OPTIONS: string; + QUERY_ALLOW_LEADING_WILDCARDS: string; + SEARCH_QUERY_LANGUAGE: string; + SORT_OPTIONS: string; + COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX: string; + COURIER_SET_REQUEST_PREFERENCE: string; + COURIER_CUSTOM_REQUEST_PREFERENCE: string; + COURIER_MAX_CONCURRENT_SHARD_REQUESTS: string; + COURIER_BATCH_SEARCHES: string; + SEARCH_INCLUDE_FROZEN: string; + HISTOGRAM_BAR_TARGET: string; + HISTOGRAM_MAX_BARS: string; + HISTORY_LIMIT: string; + SHORT_DOTS_ENABLE: string; + FORMAT_DEFAULT_TYPE_MAP: string; + FORMAT_NUMBER_DEFAULT_PATTERN: string; + FORMAT_PERCENT_DEFAULT_PATTERN: string; + FORMAT_BYTES_DEFAULT_PATTERN: string; + FORMAT_CURRENCY_DEFAULT_PATTERN: string; + FORMAT_NUMBER_DEFAULT_LOCALE: string; + TIMEPICKER_REFRESH_INTERVAL_DEFAULTS: string; + TIMEPICKER_QUICK_RANGES: string; + INDEXPATTERN_PLACEHOLDER: string; + FILTERS_PINNED_BY_DEFAULT: string; + FILTERS_EDITOR_SUGGEST_VALUES: string; +} +``` diff --git a/docs/images/add-data-fv.png b/docs/images/add-data-fv.png new file mode 100755 index 0000000000000..45313d133822c Binary files /dev/null and b/docs/images/add-data-fv.png differ diff --git a/docs/images/add-data-tutorials.png b/docs/images/add-data-tutorials.png new file mode 100644 index 0000000000000..74deedc57b42e Binary files /dev/null and b/docs/images/add-data-tutorials.png differ diff --git a/docs/infrastructure/infra-ui.asciidoc b/docs/infrastructure/infra-ui.asciidoc index 120a22541717c..96550b4ed5758 100644 --- a/docs/infrastructure/infra-ui.asciidoc +++ b/docs/infrastructure/infra-ui.asciidoc @@ -109,5 +109,5 @@ Depending on the features you have installed and configured, you may also be abl * Select *View APM* to <> in the *APM* app. -* Select *View Uptime* to <> in the *Uptime* app. +* Select *View Uptime* to {uptime-guide}/uptime-app-overview.html[view uptime information] in the *Uptime* app. diff --git a/docs/logs/using.asciidoc b/docs/logs/using.asciidoc index 4f5992f945c7a..eb3025f88ce1b 100644 --- a/docs/logs/using.asciidoc +++ b/docs/logs/using.asciidoc @@ -96,5 +96,5 @@ When the machine learning anomaly detection features are enabled, click *Log rat To see other actions related to the event, click *Actions* in the log event details. Depending on the event and the features you have configured, you may also be able to: -* Select *View status in Uptime* to <> in the *Uptime* app. +* Select *View status in Uptime* to {uptime-guide}/uptime-app-overview.html[view related uptime information] in the *Uptime* app. * Select *View in APM* to <> in the *APM* app. diff --git a/docs/management/managing-remote-clusters.asciidoc b/docs/management/managing-remote-clusters.asciidoc index 00ec5c7d2ddea..51d9f42a0b83e 100644 --- a/docs/management/managing-remote-clusters.asciidoc +++ b/docs/management/managing-remote-clusters.asciidoc @@ -31,6 +31,10 @@ to reproduce indices in the remote cluster on a local cluster. [role="screenshot"] image::images/add_remote_cluster.png[][UI for adding a remote cluster] +To create an index pattern to search across clusters, +use the same syntax that you’d use in a raw cross-cluster search request in {es}: :. +See <> for examples. + [float] [[manage-remote-clusters]] === Manage remote clusters diff --git a/docs/maps/images/fu_gs_select_source_file_upload.png b/docs/maps/images/fu_gs_select_source_file_upload.png index 6939f6a82b297..4fe1162acb29c 100644 Binary files a/docs/maps/images/fu_gs_select_source_file_upload.png and b/docs/maps/images/fu_gs_select_source_file_upload.png differ diff --git a/docs/settings/alert-action-settings.asciidoc b/docs/settings/alert-action-settings.asciidoc index 547b4fdedcec6..e02c7f212277e 100644 --- a/docs/settings/alert-action-settings.asciidoc +++ b/docs/settings/alert-action-settings.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[alert-action-settings-kb]] -=== Alerting and action settings in Kibana +=== Alerting and action settings in {kib} ++++ Alerting and action settings ++++ diff --git a/docs/settings/apm-settings.asciidoc b/docs/settings/apm-settings.asciidoc index b781930485243..f78b0642f7fa3 100644 --- a/docs/settings/apm-settings.asciidoc +++ b/docs/settings/apm-settings.asciidoc @@ -12,7 +12,7 @@ It is enabled by default. [float] [[apm-indices-settings-kb]] -==== APM Indices +==== APM indices // This content is reused in the APM app documentation. // Any changes made in this file will be seen there as well. diff --git a/docs/settings/dev-settings.asciidoc b/docs/settings/dev-settings.asciidoc index c43b96a8668e0..e92e9c2928793 100644 --- a/docs/settings/dev-settings.asciidoc +++ b/docs/settings/dev-settings.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[dev-settings-kb]] -=== Development tools settings in Kibana +=== Development tools settings in {kib} ++++ Development tools settings ++++ @@ -21,7 +21,7 @@ They are enabled by default. [float] [[profiler-settings]] -==== {searchprofiler} Settings +==== {searchprofiler} settings [cols="2*<"] |=== diff --git a/docs/settings/graph-settings.asciidoc b/docs/settings/graph-settings.asciidoc index 8ccff21a26f74..a66785242c19a 100644 --- a/docs/settings/graph-settings.asciidoc +++ b/docs/settings/graph-settings.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[graph-settings-kb]] -=== Graph settings in Kibana +=== Graph settings in {kib} ++++ Graph settings ++++ diff --git a/docs/settings/i18n-settings.asciidoc b/docs/settings/i18n-settings.asciidoc index 6d92e74f17cb2..8f498c507a8c2 100644 --- a/docs/settings/i18n-settings.asciidoc +++ b/docs/settings/i18n-settings.asciidoc @@ -1,12 +1,15 @@ [role="xpack"] [[i18n-settings-kb]] -=== i18n settings in Kibana +=== i18n settings in {kib} +++++ +i18n settings +++++ You do not need to configure any settings to run Kibana in English. [float] [[general-i18n-settings-kb]] -==== General i18n Settings +==== General i18n settings `i18n.locale`:: {kib} supports the following locales: diff --git a/docs/settings/infrastructure-ui-settings.asciidoc b/docs/settings/infrastructure-ui-settings.asciidoc index ed69c27feab72..c29ed567531d5 100644 --- a/docs/settings/infrastructure-ui-settings.asciidoc +++ b/docs/settings/infrastructure-ui-settings.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[infrastructure-ui-settings-kb]] -=== Metrics settings in Kibana +=== Metrics settings in {kib} ++++ Metrics settings ++++ @@ -11,4 +11,4 @@ You do not need to configure any settings to use the Metrics app in {kib}. It is [[general-infra-ui-settings-kb]] ==== General Metrics settings -include::general-infra-logs-ui-settings.asciidoc[] \ No newline at end of file +include::general-infra-logs-ui-settings.asciidoc[] diff --git a/docs/settings/logs-ui-settings.asciidoc b/docs/settings/logs-ui-settings.asciidoc index 5b6dd902091ae..e7321b7f0768c 100644 --- a/docs/settings/logs-ui-settings.asciidoc +++ b/docs/settings/logs-ui-settings.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[logs-ui-settings-kb]] -=== Logs app settings in Kibana +=== Logs settings in {kib} ++++ Logs settings ++++ diff --git a/docs/settings/ml-settings.asciidoc b/docs/settings/ml-settings.asciidoc index 83443636fa633..92d0c0b491ce7 100644 --- a/docs/settings/ml-settings.asciidoc +++ b/docs/settings/ml-settings.asciidoc @@ -1,12 +1,12 @@ [role="xpack"] [[ml-settings-kb]] -=== Machine learning settings in Kibana +=== Machine learning settings in {kib} ++++ Machine learning settings ++++ You do not need to configure any settings to use {kib} {ml-features}. They are -enabled by default. +enabled by default. [[general-ml-settings-kb]] ==== General {ml} settings @@ -26,4 +26,4 @@ enabled by default. [[advanced-ml-settings-kb]] ==== Advanced {ml} settings -Refer to <>. \ No newline at end of file +Refer to <>. diff --git a/docs/settings/monitoring-settings.asciidoc b/docs/settings/monitoring-settings.asciidoc index f180f2c3ecc97..48b5b5eb5d0c0 100644 --- a/docs/settings/monitoring-settings.asciidoc +++ b/docs/settings/monitoring-settings.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[monitoring-settings-kb]] -=== Monitoring settings in Kibana +=== Monitoring settings in {kib} ++++ Monitoring settings ++++ diff --git a/docs/settings/reporting-settings.asciidoc b/docs/settings/reporting-settings.asciidoc index da109331ae0fb..928878fdcdb03 100644 --- a/docs/settings/reporting-settings.asciidoc +++ b/docs/settings/reporting-settings.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[reporting-settings-kb]] -=== Reporting settings in Kibana +=== Reporting settings in {kib} ++++ Reporting settings ++++ diff --git a/docs/settings/security-settings.asciidoc b/docs/settings/security-settings.asciidoc index 8f6905d643139..4eaa4dfa55c4d 100644 --- a/docs/settings/security-settings.asciidoc +++ b/docs/settings/security-settings.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[security-settings-kb]] -=== Security settings in Kibana +=== Security settings in {kib} ++++ Security settings ++++ diff --git a/docs/settings/settings-xkb.asciidoc b/docs/settings/settings-xkb.asciidoc index f9727db838d55..4d594b4113e69 100644 --- a/docs/settings/settings-xkb.asciidoc +++ b/docs/settings/settings-xkb.asciidoc @@ -1,9 +1,9 @@ [role="xpack"] [[settings-xpack-kb]] -== {xpack} Settings in {kib} +== {xpack} settings in {kib} [subs="attributes"] ++++ -{xpack} Settings +{xpack} settings ++++ include::{asciidoc-dir}/../../shared/settings.asciidoc[] diff --git a/docs/settings/telemetry-settings.asciidoc b/docs/settings/telemetry-settings.asciidoc index 33f167b13b310..a5f5d1c44ffac 100644 --- a/docs/settings/telemetry-settings.asciidoc +++ b/docs/settings/telemetry-settings.asciidoc @@ -1,5 +1,5 @@ [[telemetry-settings-kbn]] -=== Telemetry settings in Kibana +=== Telemetry settings in {kib} ++++ Telemetry settings ++++ diff --git a/docs/setup/access.asciidoc b/docs/setup/access.asciidoc index a7374a37ddaec..49aa411e91512 100644 --- a/docs/setup/access.asciidoc +++ b/docs/setup/access.asciidoc @@ -1,5 +1,5 @@ [[access]] -== Accessing Kibana +== Access {kib} Kibana is a web application that you access through port 5601. All you need to do is point your web browser at the machine where Kibana is running and specify the port number. For example, `localhost:5601` or `http://YOURDOMAIN.com:5601`. @@ -13,7 +13,7 @@ If you still don't see any results, it's possible that you don't *have* any docu [float] [[status]] -=== Checking Kibana Status +=== Check {kib} status You can reach the Kibana server's status page by navigating to the status endpoint, for example, `localhost:5601/status`. The status page displays information about the server's resource usage and lists the installed plugins. diff --git a/docs/setup/connect-to-elasticsearch.asciidoc b/docs/setup/connect-to-elasticsearch.asciidoc index 00acb73bd276f..6d6996c2094c6 100644 --- a/docs/setup/connect-to-elasticsearch.asciidoc +++ b/docs/setup/connect-to-elasticsearch.asciidoc @@ -1,44 +1,105 @@ [[connect-to-elasticsearch]] -== Connect Kibana with Elasticsearch +== Add data to {kib} -Before you can start using Kibana, you need to tell it which Elasticsearch indices you want to explore. -The first time you access Kibana, you are prompted to define an _index pattern_ that matches the name of -one or more of your indices. That's it. That's all you need to configure to start using Kibana. You can -add index patterns at any time from the <>. +To start working with your data in {kib}, you can: -TIP: By default, Kibana connects to the Elasticsearch instance running on `localhost`. To connect to a -different Elasticsearch instance, modify the Elasticsearch URL in the `kibana.yml` configuration file and -restart Kibana. For information about using Kibana with your production nodes, see <>. +* Upload a CSV, JSON, or log file with the File Data Visualizer. -To configure the Elasticsearch indices you want to access with Kibana: +* Upload geospatial data with the GeoJSON Upload feature. -. Point your browser at port 5601 to access the Kibana UI. For example, `localhost:5601` or -`http://YOURDOMAIN.com:5601`. -+ -image:images/Start-Page.png[Kibana start page] -+ -. Specify an index pattern that matches the name of one or more of your Elasticsearch indices. The pattern -can include an asterisk (*) to matches zero or more characters in an index's name. When filling out your -index pattern, any matched indices will be displayed. -. Click *Next Step* to select the index field that contains the timestamp you want to use to perform time-based -comparisons. Kibana reads the index mapping to list all of the fields that contain a timestamp. If your -index doesn't have time-based data, choose *I don't want to use the Time Filter* option. -+ -. Click *Create index pattern* to add the index pattern. This first pattern is automatically configured as the default. -When you have more than one index pattern, you can designate which one to use as the default by clicking -on the star icon above the index pattern title from *Management > Index Patterns*. +* Index logs, metrics, events, or application data by setting up a Beats module. + +* Connect {kib} with existing {es} indices. + +If you're not ready to use your own data, you can add a <> +to see all that you can do in {kib}. + +[float] +[[upload-data-kibana]] +=== Upload a CSV, JSON, or log file + +To visualize data in a CSV, JSON, or log file, you can +upload it using the File Data Visualizer. On the home page, +click *Import a CSV, NDSON, or log file*, and then drag your file into the +File Data Visualizer. + +You can upload a file up to 100 MB. This value is configurable up to 1 GB in +<>. + +[role="screenshot"] +image::images/add-data-fv.png[File Data Visualizer] + +The File Data Visualizer uses the {ref}/ml-find-file-structure.html[find_file_structure API] to analyze +the uploaded file and to suggest ingest pipelines and mappings for your data. + +NOTE: This feature is not intended for use as part of a +repeated production process, but rather for the initial exploration of your data. + +[float] +[[upload-geoipdata-kibana]] +=== Upload geospatial data + +To visualize geospatial data in a point or shape file, you can upload it using the <> +feature in *Elastic Maps*, and then use that data as a layer in a map. +The data is also available for use in the broader Kibana ecosystem, for example, +in visualizations and Canvas workpads. +With GeoJSON Upload, you can upload a file up to 50 MB. + +[role="screenshot"] +image::images/fu_gs_select_source_file_upload.png[] -All done! Kibana is now connected to your Elasticsearch data. Kibana displays a read-only list of fields -configured for the matching index. [float] -[[explore]] -=== Start Exploring your Data! -You're ready to dive in to your data: +[[add-data-tutorial-kibana]] +=== Index metrics, log, security, and application data -* Search and browse your data interactively from the <> page. -* Chart and map your data from the <> page. -* Create and view custom dashboards from the <> page. +The built-in data tutorials can help you quickly get up and running with +metrics data, log analytics, security events, and application data. +These tutorials walk you through installing and configuring a +Beats data shipper to periodically collect and send data to {es}. +You can then use the pre-built dashboards to explore and analyze the data. -For a step-by-step introduction to these core Kibana concepts, see the <> tutorial. +You access the tutorials from the home page. +If a tutorial doesn’t exist for your data, go to the {beats-ref}/beats-reference.html[Beats overview] +to learn about other data shippers in the Beats family. + +[role="screenshot"] +image::images/add-data-tutorials.png[Add Data tutorials] + + +[float] +[[connect-to-es]] +=== Connect with {es} indices + +To visualize data in existing {es} indices, you must +create an index pattern that matches the names of the indices that you want to explore. +When you add data with the File Data Visualizer, GeoJSON Upload feature, +or built-in tutorial, an index pattern is created for you. + +. Go to *Stack Management*, and then click *Index Patterns*. + +. Click *Create index pattern*. + +. Specify an index pattern that matches the name of one or more of your Elasticsearch indices. ++ +For example, an index pattern can point to your Apache data from yesterday, +`filebeat-apache-4-3-2022`, or any index that matches the pattern, `filebeat-*`. +Using a wildcard is the more popular approach. + + +. Click *Next Step*, and then select the index field that contains the timestamp you want to use to perform time-based +comparisons. ++ +Kibana reads the index mapping and lists all fields that contain a timestamp. If your +index doesn't have time-based data, choose *I don't want to use the Time Filter*. ++ +You must select a time field to use global time filters on your dashboards. + +. Click *Create index pattern*. ++ +{kib} is now configured to access your {es} indices. +You’ll see a list of fields configured for the matching index. +You can designate your index pattern as the default by clicking the star icon on this page. ++ +When searching in *Discover* and creating visualizations, you choose a pattern +from the index pattern menu to specify the {es} indices that contain the data you want to explore. diff --git a/docs/setup/docker.asciidoc b/docs/setup/docker.asciidoc index e8029ed1bbe9b..fb4cbbada9a33 100644 --- a/docs/setup/docker.asciidoc +++ b/docs/setup/docker.asciidoc @@ -1,5 +1,5 @@ [[docker]] -== Running Kibana on Docker +=== Install Kibana with Docker Docker images for Kibana are available from the Elastic Docker registry. The base image is https://hub.docker.com/_/centos/[centos:7]. @@ -16,7 +16,7 @@ Elastic license levels. [float] [[pull-image]] -=== Pulling the image +=== Pull the image Obtaining Kibana for Docker is as simple as issuing a +docker pull+ command against the Elastic Docker registry. @@ -40,7 +40,7 @@ available under the Apache 2.0 license. To download the images, go to https://www.docker.elastic.co[www.docker.elastic.co]. [float] -=== Running Kibana on Docker for development +=== Run Kibana on Docker for development Kibana can be quickly started and connected to a local Elasticsearch container for development or testing use with the following command: -------------------------------------------- @@ -50,7 +50,7 @@ endif::[] [float] [[configuring-kibana-docker]] -=== Configuring Kibana on Docker +=== Configure Kibana on Docker The Docker images provide several methods for configuring Kibana. The conventional approach is to provide a `kibana.yml` file as described in diff --git a/docs/setup/install.asciidoc b/docs/setup/install.asciidoc index f557dd2280e4c..73036da8f1390 100644 --- a/docs/setup/install.asciidoc +++ b/docs/setup/install.asciidoc @@ -1,13 +1,13 @@ [[install]] -== Installing Kibana +== Install {kib} [float] -=== Hosted Kibana +=== Hosted {kib} If you are running our hosted Elasticsearch Service on Elastic Cloud, you access Kibana with a single click. (You can {ess-trial}[sign up for a free trial] and start exploring data in minutes.) [float] -=== Installing Kibana Yourself +=== Install {kib} yourself NOTE: Starting with version 6.0.0, Kibana only supports 64 bit operating systems. @@ -59,10 +59,12 @@ additional setup instructions. include::install/targz.asciidoc[] +include::install/windows.asciidoc[] + include::install/deb.asciidoc[] include::install/rpm.asciidoc[] -include::install/windows.asciidoc[] +include::{kib-repo-dir}/setup/docker.asciidoc[] include::install/brew.asciidoc[] diff --git a/docs/setup/install/brew-running.asciidoc b/docs/setup/install/brew-running.asciidoc index ba78dd1659d04..d73102b098ec1 100644 --- a/docs/setup/install/brew-running.asciidoc +++ b/docs/setup/install/brew-running.asciidoc @@ -1,6 +1,6 @@ -==== Running Kibana with `brew services` +==== Run {kib} with `brew services` -With Homebrew, Kibana can be started and stopped as follows: +With Homebrew, Kibana can be started and stopped as follows: [source,sh] -------------------------------------------------- diff --git a/docs/setup/install/deb-init.asciidoc b/docs/setup/install/deb-init.asciidoc index 1b92eeadd2efb..6e21b8f97cf7e 100644 --- a/docs/setup/install/deb-init.asciidoc +++ b/docs/setup/install/deb-init.asciidoc @@ -1,4 +1,4 @@ -==== Running Kibana with SysV `init` +==== Run {kib} with SysV `init` Use the `update-rc.d` command to configure Kibana to start automatically when the system boots up: @@ -18,4 +18,3 @@ sudo -i service kibana stop If Kibana fails to start for any reason, it will print the reason for failure to `STDOUT`. Log files can be found in `/var/log/kibana/`. - diff --git a/docs/setup/install/deb.asciidoc b/docs/setup/install/deb.asciidoc index 62ab661d9a66c..8193a088c8b7e 100644 --- a/docs/setup/install/deb.asciidoc +++ b/docs/setup/install/deb.asciidoc @@ -1,15 +1,15 @@ [[deb]] -=== Install Kibana with Debian Package +=== Install {kib} with Debian package The Debian package for Kibana can be <> or from our <>. It can be used to install Kibana on any Debian-based system such as Debian and Ubuntu. -This package is free to use under the Elastic license. It contains open source -and free commercial features and access to paid commercial features. -{stack-ov}/license-management.html[Start a 30-day trial] to try out all of the -paid commercial features. See the -https://www.elastic.co/subscriptions[Subscriptions] page for information about +This package is free to use under the Elastic license. It contains open source +and free commercial features and access to paid commercial features. +{stack-ov}/license-management.html[Start a 30-day trial] to try out all of the +paid commercial features. See the +https://www.elastic.co/subscriptions[Subscriptions] page for information about Elastic license levels. The latest stable version of Kibana can be found on the @@ -17,7 +17,7 @@ link:/downloads/kibana[Download Kibana] page. Other versions can be found on the link:/downloads/past-releases[Past Releases page]. [[deb-key]] -==== Import the Elastic PGP Key +==== Import the Elastic PGP key include::key.asciidoc[] @@ -27,7 +27,7 @@ wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add ------------------------- [[deb-repo]] -==== Installing from the APT repository +==== Install from the APT repository ifeval::["{release-state}"=="unreleased"] @@ -151,9 +151,9 @@ sudo dpkg -i kibana-{version}-amd64.deb <1> Compare the SHA produced by `shasum` with the https://artifacts.elastic.co/downloads/kibana/kibana-{version}-amd64.deb.sha512[published SHA]. -Alternatively, you can download the following package, which contains only -features that are available under the Apache 2.0 license: -https://artifacts.elastic.co/downloads/kibana/kibana-oss-{version}-amd64.deb +Alternatively, you can download the following package, which contains only +features that are available under the Apache 2.0 license: +https://artifacts.elastic.co/downloads/kibana/kibana-oss-{version}-amd64.deb endif::[] @@ -169,7 +169,7 @@ include::deb-init.asciidoc[] include::systemd.asciidoc[] [[deb-configuring]] -==== Configuring Kibana via config file +==== Configure {kib} via the config file Kibana loads its configuration from the `/etc/kibana/kibana.yml` file by default. The format of this config file is explained in @@ -205,7 +205,7 @@ locations for a Debian-based system: | The location of the data files written to disk by Kibana and its plugins | /var/lib/kibana | path.data - + | logs | Logs files location | /var/log/kibana diff --git a/docs/setup/install/rpm-init.asciidoc b/docs/setup/install/rpm-init.asciidoc index 6b3d6d49a4ead..08282635a014f 100644 --- a/docs/setup/install/rpm-init.asciidoc +++ b/docs/setup/install/rpm-init.asciidoc @@ -1,4 +1,4 @@ -==== Running Kibana with SysV `init` +==== Run {kib} with SysV `init` Use the `chkconfig` command to configure Kibana to start automatically when the system boots up: diff --git a/docs/setup/install/rpm.asciidoc b/docs/setup/install/rpm.asciidoc index 77a16e67cf2a4..c3922ffba1efa 100644 --- a/docs/setup/install/rpm.asciidoc +++ b/docs/setup/install/rpm.asciidoc @@ -1,5 +1,5 @@ [[rpm]] -=== Install Kibana with RPM +=== Install {kib} with RPM The RPM for Kibana can be <> or from our <>. It can be used to install @@ -9,11 +9,11 @@ and Oracle Enterprise. NOTE: RPM install is not supported on distributions with old versions of RPM, such as SLES 11 and CentOS 5. Please see <> instead. -This package is free to use under the Elastic license. It contains open source -and free commercial features and access to paid commercial features. -{stack-ov}/license-management.html[Start a 30-day trial] to try out all of the -paid commercial features. See the -https://www.elastic.co/subscriptions[Subscriptions] page for information about +This package is free to use under the Elastic license. It contains open source +and free commercial features and access to paid commercial features. +{stack-ov}/license-management.html[Start a 30-day trial] to try out all of the +paid commercial features. See the +https://www.elastic.co/subscriptions[Subscriptions] page for information about Elastic license levels. The latest stable version of Kibana can be found on the @@ -21,7 +21,7 @@ link:/downloads/kibana[Download Kibana] page. Other versions can be found on the link:/downloads/past-releases[Past Releases page]. [[rpm-key]] -==== Import the Elastic PGP Key +==== Import the Elastic PGP key include::key.asciidoc[] @@ -143,9 +143,9 @@ sudo rpm --install kibana-{version}-x86_64.rpm <1> Compare the SHA produced by `shasum` with the https://artifacts.elastic.co/downloads/kibana/kibana-{version}-x86_64.rpm.sha512[published SHA]. -Alternatively, you can download the following package, which contains only +Alternatively, you can download the following package, which contains only features that are available under the Apache 2.0 license: -https://artifacts.elastic.co/downloads/kibana/kibana-oss-{version}-x86_64.rpm +https://artifacts.elastic.co/downloads/kibana/kibana-oss-{version}-x86_64.rpm endif::[] @@ -160,7 +160,7 @@ include::rpm-init.asciidoc[] include::systemd.asciidoc[] [[rpm-configuring]] -==== Configuring Kibana via config file +==== Configure {kib} via the config file Kibana loads its configuration from the `/etc/kibana/kibana.yml` file by default. The format of this config file is explained in @@ -196,7 +196,7 @@ locations for an RPM-based system: | The location of the data files written to disk by Kibana and its plugins | /var/lib/kibana | path.data - + | logs | Logs files location | /var/log/kibana diff --git a/docs/setup/install/systemd.asciidoc b/docs/setup/install/systemd.asciidoc index 3053972f9e384..6fcb82217affc 100644 --- a/docs/setup/install/systemd.asciidoc +++ b/docs/setup/install/systemd.asciidoc @@ -1,4 +1,4 @@ -==== Running Kibana with `systemd` +==== Run {kib} with `systemd` To configure Kibana to start automatically when the system boots up, run the following commands: diff --git a/docs/setup/install/targz-running.asciidoc b/docs/setup/install/targz-running.asciidoc index dd4fd722e127e..d3813d9811b13 100644 --- a/docs/setup/install/targz-running.asciidoc +++ b/docs/setup/install/targz-running.asciidoc @@ -1,4 +1,4 @@ -==== Running Kibana from the command line +==== Run {kib} from the command line Kibana can be started from the command line as follows: diff --git a/docs/setup/install/targz.asciidoc b/docs/setup/install/targz.asciidoc index 31970888a976b..a53360900657e 100644 --- a/docs/setup/install/targz.asciidoc +++ b/docs/setup/install/targz.asciidoc @@ -1,5 +1,5 @@ [[targz]] -=== Install {kib} from archive on Linux or MacOS +=== Install {kib} from archive on Linux or macOS Kibana is provided for Linux and Darwin as a `.tar.gz` package. These packages are the easiest formats to use when trying out Kibana. @@ -101,7 +101,7 @@ include::targz-running.asciidoc[] [[targz-configuring]] -==== Configuring Kibana via config file +==== Configure {kib} via the config file Kibana loads its configuration from the `$KIBANA_HOME/config/kibana.yml` file by default. The format of this config file is explained in diff --git a/docs/setup/install/windows-running.asciidoc b/docs/setup/install/windows-running.asciidoc index 57d756a07c13d..832284edc8f39 100644 --- a/docs/setup/install/windows-running.asciidoc +++ b/docs/setup/install/windows-running.asciidoc @@ -1,4 +1,4 @@ -==== Running Kibana from the command line +==== Run {kib} from the command line Kibana can be started from the command line as follows: diff --git a/docs/setup/install/windows.asciidoc b/docs/setup/install/windows.asciidoc index db55451f01aae..1cfbaaa0eda2f 100644 --- a/docs/setup/install/windows.asciidoc +++ b/docs/setup/install/windows.asciidoc @@ -1,13 +1,13 @@ [[windows]] -=== Install Kibana on Windows +=== Install {kib} on Windows Kibana can be installed on Windows using the `.zip` package. -This package is free to use under the Elastic license. It contains open source -and free commercial features and access to paid commercial features. -{stack-ov}/license-management.html[Start a 30-day trial] to try out all of the -paid commercial features. See the -https://www.elastic.co/subscriptions[Subscriptions] page for information about +This package is free to use under the Elastic license. It contains open source +and free commercial features and access to paid commercial features. +{stack-ov}/license-management.html[Start a 30-day trial] to try out all of the +paid commercial features. See the +https://www.elastic.co/subscriptions[Subscriptions] page for information about Elastic license levels. The latest stable version of Kibana can be found on the @@ -39,9 +39,9 @@ terminal window, `CD` to the `$KIBANA_HOME` directory, for instance: CD c:\kibana-{version}-windows-x86_64 ---------------------------- -Alternatively, you can download the following package, which contains only +Alternatively, you can download the following package, which contains only features that are available under the Apache 2.0 license: -https://artifacts.elastic.co/downloads/kibana/kibana-oss-{version}-windows-x86_64.zip +https://artifacts.elastic.co/downloads/kibana/kibana-oss-{version}-windows-x86_64.zip endif::[] @@ -49,7 +49,7 @@ endif::[] include::windows-running.asciidoc[] [[windows-configuring]] -==== Configuring Kibana via config file +==== Configure {kib} via the config file Kibana loads its configuration from the `$KIBANA_HOME/config/kibana.yml` file by default. The format of this config file is explained in diff --git a/docs/setup/production.asciidoc b/docs/setup/production.asciidoc index 19f9d64d13623..72f275e237490 100644 --- a/docs/setup/production.asciidoc +++ b/docs/setup/production.asciidoc @@ -1,5 +1,5 @@ [[production]] -== Using Kibana in a production environment +== Use {kib} in a production environment * <> * <> @@ -23,7 +23,7 @@ and an Elasticsearch client node on the same machine. For more information, see [float] [[configuring-kibana-shield]] -=== Using {stack} {security-features} +=== Use {stack} {security-features} You can use {stack} {security-features} to control what {es} data users can access through Kibana. @@ -59,13 +59,13 @@ csp.strict: true [float] [[enabling-ssl]] -=== Enabling SSL +=== Enable SSL See <>. [float] [[load-balancing-es]] -=== Load Balancing Across Multiple Elasticsearch Nodes +=== Load Balancing across multiple {es} nodes If you have multiple nodes in your Elasticsearch cluster, the easiest way to distribute Kibana requests across the nodes is to run an Elasticsearch _Coordinating only_ node on the same machine as Kibana. Elasticsearch Coordinating only nodes are essentially smart load balancers that are part of the cluster. They @@ -145,7 +145,7 @@ bin/kibana -c config/instance2.yml [float] [[high-availability]] -=== High availability across multiple Elasticsearch nodes +=== High availability across multiple {es} nodes Kibana can be configured to connect to multiple Elasticsearch nodes in the same cluster. In situations where a node becomes unavailable, Kibana will transparently connect to an available node and continue operating. Requests to available hosts will be routed in a round robin fashion. diff --git a/docs/setup/secure-settings.asciidoc b/docs/setup/secure-settings.asciidoc index a7ccd3f77405e..10380eb5d8fa4 100644 --- a/docs/setup/secure-settings.asciidoc +++ b/docs/setup/secure-settings.asciidoc @@ -9,7 +9,7 @@ NOTE: All commands here should be run as the user which will run Kibana. [float] [[creating-keystore]] -=== Creating the keystore +=== Create the keystore To create the `kibana.keystore`, use the `create` command: @@ -23,7 +23,7 @@ The file `kibana.keystore` will be created in the directory defined by the [float] [[list-settings]] -=== Listing settings in the keystore +=== List settings in the keystore A list of the settings in the keystore is available with the `list` command: @@ -34,7 +34,7 @@ bin/kibana-keystore list [float] [[add-string-to-keystore]] -=== Adding string settings +=== Add string settings Sensitive string settings, like authentication credentials for Elasticsearch can be added using the `add` command: @@ -65,7 +65,7 @@ cat /file/containing/setting/value | bin/kibana-keystore add the.setting.name.to [float] [[remove-settings]] -=== Removing settings +=== Remove settings To remove a setting from the keystore, use the `remove` command: diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index 1be9d5b1ef35b..c4f5439e25489 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -1,5 +1,5 @@ [[settings]] -== Configuring {kib} +== Configure {kib} The {kib} server reads properties from the `kibana.yml` file on startup. The location of this file differs depending on how you installed {kib}. For example, diff --git a/docs/setup/start-stop.asciidoc b/docs/setup/start-stop.asciidoc index 2fcc440680f12..198bc76bbb400 100644 --- a/docs/setup/start-stop.asciidoc +++ b/docs/setup/start-stop.asciidoc @@ -1,15 +1,15 @@ [[start-stop]] -== Starting and stopping Kibana +== Start and stop {kib} -The method for starting and stopping {kib} varies depending on how you installed -it. +The method for starting and stopping {kib} varies depending on how you installed +it. [float] [[start-start-targz]] === Archive packages (`.tar.gz`) -If you installed {kib} on Linux or Darwin with a `.tar.gz` package, you can -start and stop {kib} from the command line. +If you installed {kib} on Linux or Darwin with a `.tar.gz` package, you can +start and stop {kib} from the command line. [float] include::install/targz-running.asciidoc[] @@ -18,8 +18,8 @@ include::install/targz-running.asciidoc[] [[start-stop-zip]] === Archive packages (`.zip`) -If you installed {kib} on Windows with a `.zip` package, you can -stop and start {kib} from the command line. +If you installed {kib} on Windows with a `.zip` package, you can +stop and start {kib} from the command line. [float] include::install/windows-running.asciidoc[] diff --git a/docs/setup/upgrade.asciidoc b/docs/setup/upgrade.asciidoc index 982f1167f3871..6d69b6921b612 100644 --- a/docs/setup/upgrade.asciidoc +++ b/docs/setup/upgrade.asciidoc @@ -1,15 +1,15 @@ [[upgrade]] -== Upgrading {kib} +== Upgrade {kib} Depending on the {kib} version you're upgrading from, the upgrade process to 7.0 -varies. +varies. -NOTE: {kib} upgrades automatically when starting a new version, as described in +NOTE: {kib} upgrades automatically when starting a new version, as described in <>. Although you do not need to manually back up {kib} before upgrading, we recommend -that you have a backup on hand. You can use +that you have a backup on hand. You can use <> to back up {kib} -data by targeting `.kibana*` indices. If you are using the Reporting plugin, +data by targeting `.kibana*` indices. If you are using the Reporting plugin, you can also target `.reporting*` indices. [float] @@ -23,44 +23,44 @@ Before you upgrade {kib}: * Back up your data with {es} {ref}/modules-snapshots.html[snapshots]. To roll back to an earlier version, you **must** have a backup of your data. * If you are using custom plugins, check that a compatible version is - available. -* Shut down all {kib} nodes. Running more than one {kib} version against the - same Elasticseach index is unsupported. If you upgrade while older {kib} nodes are + available. +* Shut down all {kib} nodes. Running more than one {kib} version against the + same Elasticseach index is unsupported. If you upgrade while older {kib} nodes are running, the upgrade can fail. -To identify the changes you need to make to upgrade, and to enable you to -perform an Elasticsearch rolling upgrade with no downtime, you must upgrade to +To identify the changes you need to make to upgrade, and to enable you to +perform an Elasticsearch rolling upgrade with no downtime, you must upgrade to 6.7 before you upgrade to 7.0. -For a comprehensive overview of the upgrade process, refer to +For a comprehensive overview of the upgrade process, refer to *{stack-ref}/upgrading-elastic-stack.html[Upgrading the Elastic Stack]*. [float] [[upgrade-5x-earlier]] -=== Upgrading from 5.x or earlier -{es} can read indices created in the previous major version. Before you upgrade -to 7.0.0, you must reindex or delete any indices created in 5.x or earlier. -For more information, refer to +=== Upgrade from 5.x or earlier +{es} can read indices created in the previous major version. Before you upgrade +to 7.0.0, you must reindex or delete any indices created in 5.x or earlier. +For more information, refer to {stack-ref}/upgrading-elastic-stack.html#oss-stack-upgrade[Upgrading the Elastic Stack]. -When your reindex is complete, follow the <> -instructions. +When your reindex is complete, follow the <> +instructions. [float] [[upgrade-6x]] -=== Upgrading from 6.x +=== Upgrade from 6.x -The recommended path is to upgrade to 6.8 before upgrading to 7.0. This makes it -easier to identify the required changes, and enables you to use the Upgrade +The recommended path is to upgrade to 6.8 before upgrading to 7.0. This makes it +easier to identify the required changes, and enables you to use the Upgrade Assistant to prepare for your upgrade to 7.0. -TIP: The ability to import {kib} 6.x saved searches, visualizations, and +TIP: The ability to import {kib} 6.x saved searches, visualizations, and dashboards is supported. [float] [[upgrade-67]] -=== Upgrading from 6.8 -To help you prepare for your upgrade to 7.0, 6.8 includes an https://www.elastic.co/guide/en/kibana/6.8/upgrade-assistant.html[Upgrade Assistant] +=== Upgrade from 6.8 +To help you prepare for your upgrade to 7.0, 6.8 includes an https://www.elastic.co/guide/en/kibana/6.8/upgrade-assistant.html[Upgrade Assistant] To access the assistant, go to *Management > 7.0 Upgrade Assistant*. After you have addressed any issues that were identified by the Upgrade @@ -70,4 +70,3 @@ Assistant, <>. include::upgrade/upgrade-standard.asciidoc[] include::upgrade/upgrade-migrations.asciidoc[] - diff --git a/docs/setup/upgrade/upgrade-migrations.asciidoc b/docs/setup/upgrade/upgrade-migrations.asciidoc index 81ff8344c4c5f..cbe56b9e65894 100644 --- a/docs/setup/upgrade/upgrade-migrations.asciidoc +++ b/docs/setup/upgrade/upgrade-migrations.asciidoc @@ -1,10 +1,10 @@ [[upgrade-migrations]] -=== Troubleshooting saved object migrations +=== Migrate saved objects Every time {kib} is upgraded it checks to see if all saved objects, such as dashboards, visualizations, and index patterns, are compatible with the new version. If any objects need to be updated, then the automatic saved object migration process is kicked off. -NOTE: 6.7 includes an https://www.elastic.co/guide/en/kibana/6.7/upgrade-assistant.html[Upgrade Assistant] -to help you prepare for your upgrade to 7.0. To access the assistant, go to *Management > 7.0 Upgrade Assistant*. +NOTE: 6.7 includes an https://www.elastic.co/guide/en/kibana/6.7/upgrade-assistant.html[Upgrade Assistant] +to help you prepare for your upgrade to 7.0. To access the assistant, go to *Management > 7.0 Upgrade Assistant*. [float] [[upgrade-migrations-process]] @@ -46,11 +46,9 @@ The first instance that triggers saved object migrations will run the entire pro [[upgrade-migrations-rolling-back]] ==== Rolling back to a previous version of {kib} -When rolling {kib} back to a previous version, point the `.kibana` alias to -the appropriate {kib} index. When you have the previous version running again, -delete the more recent `.kibana_N` index or indices so that future upgrades are +When rolling {kib} back to a previous version, point the `.kibana` alias to +the appropriate {kib} index. When you have the previous version running again, +delete the more recent `.kibana_N` index or indices so that future upgrades are based on the current {kib} index. You must restart {kib} to re-trigger the migration. WARNING: Rolling back to a previous {kib} version can result in saved object data loss if you had successfully upgraded and made changes to saved objects before rolling back. - - diff --git a/docs/setup/upgrade/upgrade-standard.asciidoc b/docs/setup/upgrade/upgrade-standard.asciidoc index 683383525a3bb..df38427881d65 100644 --- a/docs/setup/upgrade/upgrade-standard.asciidoc +++ b/docs/setup/upgrade/upgrade-standard.asciidoc @@ -1,8 +1,8 @@ [[upgrade-standard]] === Standard upgrade -NOTE: 6.7 includes an https://www.elastic.co/guide/en/kibana/6.7/upgrade-assistant.html[Upgrade Assistant] -to help you prepare for your upgrade to 7.0. To access the assistant, go to *Management > 7.0 Upgrade Assistant*. +NOTE: 6.7 includes an https://www.elastic.co/guide/en/kibana/6.7/upgrade-assistant.html[Upgrade Assistant] +to help you prepare for your upgrade to 7.0. To access the assistant, go to *Management > 7.0 Upgrade Assistant*. [IMPORTANT] =========================================== @@ -13,7 +13,7 @@ necessary remediation steps as per those instructions. =========================================== [float] -==== Upgrading using a `deb` or `rpm` package +==== Upgrade using a `deb` or `rpm` package . Stop the existing {kib} process using the appropriate command for your system. @@ -37,7 +37,7 @@ otherwise {kib} will fail to start. . Start the new {kib} process using the appropriate command for your system. [float] -==== Upgrading using a `zip` or `tar.gz` archive +==== Upgrade using a `zip` or `tar.gz` archive . Extract the `zip` or `tar.gz` archive to a new directory to be sure that you don't overwrite the `config` or `data` directories. + diff --git a/docs/uptime-guide/alerting.asciidoc b/docs/uptime-guide/alerting.asciidoc new file mode 100644 index 0000000000000..bf9e7693fc7a5 --- /dev/null +++ b/docs/uptime-guide/alerting.asciidoc @@ -0,0 +1,33 @@ +[role="xpack"] +[[uptime-alerting]] + +=== Uptime alerting + +The Uptime app integrates with Kibana's {kibana-ref}/alerting-getting-started.html[alerting and actions] +feature. It provides a set of built-in actions and Uptime specific threshold alerts for you to use +and enables central management of all alerts from {kibana-ref}/management.html[Kibana Management]. + +[role="screenshot"] +image::images/create-alert.png[Create alert] + +[float] +==== Monitor status alerts + +To receive alerts when a monitor goes down, use the alerting menu at the top of the +overview page. Use a query in the alert flyout to determine which monitors to check +with your alert. If you already have a query in the overview page search bar it will +be carried over into this box. + +[role="screenshot"] +image::images/monitor-status-alert.png[Create monitor status alert flyout] + +[float] +==== TLS alerts + +Uptime also provides the ability to create an alert that will notify you when one or +more of your monitors have a TLS certificate that will expire within some threshold, +or when its age exceeds a limit. The values for these thresholds are configurable on +the <>. + +[role="screenshot"] +image::images/tls-alert.png[Create TLS alert flyout] diff --git a/docs/uptime-guide/app-overview.asciidoc b/docs/uptime-guide/app-overview.asciidoc new file mode 100644 index 0000000000000..692489a7ad311 --- /dev/null +++ b/docs/uptime-guide/app-overview.asciidoc @@ -0,0 +1,70 @@ +[role="xpack"] +[[uptime-app]] +== Uptime app + +The Uptime app in {kib} enables you to monitor the status of network endpoints via HTTP/S, TCP, and ICMP. +You can explore endpoint status over time, drill down into specific monitors, +and view a high-level snapshot of your environment at any point in time. + +[role="screenshot"] +image::images/uptime-overview.png[Uptime app overview] + +[role="xpack"] +[[uptime-app-overview]] +=== Overview + +The Uptime overview helps you quickly identify and diagnose outages and +other connectivity issues within your network or environment. You can use the date range +selection that is global to the Uptime app, to highlight +an absolute date range, or a relative one, similar to other areas of {kib}. + +[float] +=== Filter bar + +The Filter bar enables you to quickly view specific groups of monitors, or even +an individual monitor if you have defined many. + +This control allows you to use automated filter options, as well as input custom filter +text to select specific monitors by field, URL, ID, and other attributes. + +[role="screenshot"] +image::images/filter-bar.png[Filter bar] + +[float] +=== Snapshot panel + +The Snapshot panel displays the overall +status of the environment you're monitoring or a subset of those monitors. +You can see the total number of detected monitors within the selected +Uptime date range, along with the number of monitors +in an `up` or `down` state, which is based on the last check reported by Heartbeat +for each monitor. + +Next to the counts, there is a histogram displaying the change over time throughout the +selected date range. + +[role="screenshot"] +image::images/snapshot-view.png[Snapshot view] + +[float] +=== Monitor list + +Information about individual monitors is displayed in the monitor list and provides a quick +way to navigate to a more in-depth visualization for interesting hosts or endpoints. + +The information displayed includes the recent status of a host or endpoint, when the monitor was last checked, its +ID and URL, and its IP address. There is also sparkline showing its check status over time. + +[role="screenshot"] +image::images/monitor-list.png[Monitor list] + +[float] +=== Observability integrations + +The Monitor list also contains a menu of available integrations. When Uptime detects Kubernetes or +Docker related host information, it provides links to open the Metrics app or Logs app pre-filtered +for this host. Additionally, to help you quickly determine if these solutions contain data relevant to you, +this feature contains links to filter the other views on the host's IP address. + +[role="screenshot"] +image::images/observability_integrations.png[Observability integrations] diff --git a/docs/uptime-guide/certificates.asciidoc b/docs/uptime-guide/certificates.asciidoc new file mode 100644 index 0000000000000..58db91aa080eb --- /dev/null +++ b/docs/uptime-guide/certificates.asciidoc @@ -0,0 +1,15 @@ +[role="xpack"] +[[uptime-certificates]] + +=== Certificates + +The certificates page enables you to visualize TLS certificate data in your indices. In addition to the +common name, associated monitors, issuer information, and SHA fingerprints, Uptime also assigns a status +derived from the threshold values in the <>. + +Several of the columns on this page are sortable. You can use the search bar at the top of the view +to find values in most of the TLS-related fields in your Uptime indices. Additionally, using the `Alerts` +dropdown at the top of the page you can create a TLS alert. + +[role="screenshot"] +image::images/certificates-page.png[Certificates] diff --git a/docs/uptime-guide/deployment-arch.asciidoc b/docs/uptime-guide/deployment-arch.asciidoc index d8edf290b9a5e..c1b2f596c6665 100644 --- a/docs/uptime-guide/deployment-arch.asciidoc +++ b/docs/uptime-guide/deployment-arch.asciidoc @@ -4,22 +4,24 @@ There are multiple ways to deploy Uptime and Heartbeat. Use the information in this section to determine the best deployment for you. -A guiding principle is that an outage that takes down the service being monitored should not also take down Heartbeat. -You want Heartbeat to be functioning even when your service is not, so the guidelines here help you maximise this possibility. +A guiding principle is that when an outage takes down the service being monitored it should not also take down Heartbeat. +You want Heartbeat to be functioning even when your service is not, so the guidelines here help you maximize this possibility. -Heartbeat is generally run as a centralized service within a data center. +Heartbeat is commonly run as a centralized service within a data center. While it is possible to run it as a separate "sidecar" process paired with each process/container, we recommend against it. Running Heartbeat centrally ensures you will still be able to see monitoring data in the event of an overloaded, disconnected, or otherwise malfunctioning server. -For further redundancy, you may want to deploy multiple Heartbeats across geographic and/or network boundaries to provide more data. - Specify Heartbeat's observer {heartbeat-ref}/configuration-observer-options.html[geo options] to do so. Some examples might be: +For further redundancy, you may want to deploy multiple Heartbeats across geographic and network boundaries to provide more data. +To do so, specify Heartbeat's observer {heartbeat-ref}/configuration-observer-options.html[geo options]. + +Some examples might be: * **A site served from a content delivery network (CDN) with points of presence (POPs) around the globe:** -In this case you may want to have multiple Heartbeat instances at different data centers around the world checking to see if your site is reachable via local CDN POPs. +To check if your site is reachable via CDN POPS, you may want to have multiple Heartbeat instances at different data centers around the world. * **A service within a single data center that is accessed across multiple VPNs:** Set up one Heartbeat instance within the VPN the service operates from, and another within an additional VPN that users access the service from. -Having both instances will help pinpoint network errors in the event of an outage. +Having both instances helps pinpoint network errors in the event of an outage. * **A single service running primarily in a US east coast data center, with a hot failover located in a US west coast data center:** In each data center, run a Heartbeat instance that checks both the local copy of the service and its counterpart across the country. Set up two monitors in each region, one for the local service and one for the remote service. -In the event of a data center failure it will be immediately obvious if the service had a connectivity issue to the outside world or if the failure was only internal. +In the event of a data center failure it will be immediately apparent if the service had a connectivity issue to the outside world or if the failure was only internal. diff --git a/docs/uptime-guide/images/cert-exp.png b/docs/uptime-guide/images/cert-exp.png new file mode 100644 index 0000000000000..cd87668db96dd Binary files /dev/null and b/docs/uptime-guide/images/cert-exp.png differ diff --git a/docs/uptime/images/certificates-page.png b/docs/uptime-guide/images/certificates-page.png similarity index 100% rename from docs/uptime/images/certificates-page.png rename to docs/uptime-guide/images/certificates-page.png diff --git a/docs/uptime/images/check-history.png b/docs/uptime-guide/images/check-history.png similarity index 100% rename from docs/uptime/images/check-history.png rename to docs/uptime-guide/images/check-history.png diff --git a/docs/uptime-guide/images/create-alert.png b/docs/uptime-guide/images/create-alert.png new file mode 100644 index 0000000000000..54a0c400cad4c Binary files /dev/null and b/docs/uptime-guide/images/create-alert.png differ diff --git a/docs/uptime/images/crosshair-example.png b/docs/uptime-guide/images/crosshair-example.png similarity index 100% rename from docs/uptime/images/crosshair-example.png rename to docs/uptime-guide/images/crosshair-example.png diff --git a/docs/uptime/images/filter-bar.png b/docs/uptime-guide/images/filter-bar.png similarity index 100% rename from docs/uptime/images/filter-bar.png rename to docs/uptime-guide/images/filter-bar.png diff --git a/docs/uptime-guide/images/indices.png b/docs/uptime-guide/images/indices.png new file mode 100644 index 0000000000000..4090747b6726c Binary files /dev/null and b/docs/uptime-guide/images/indices.png differ diff --git a/docs/uptime/images/monitor-charts.png b/docs/uptime-guide/images/monitor-charts.png similarity index 100% rename from docs/uptime/images/monitor-charts.png rename to docs/uptime-guide/images/monitor-charts.png diff --git a/docs/uptime/images/monitor-list.png b/docs/uptime-guide/images/monitor-list.png similarity index 100% rename from docs/uptime/images/monitor-list.png rename to docs/uptime-guide/images/monitor-list.png diff --git a/docs/uptime-guide/images/monitor-status-alert.png b/docs/uptime-guide/images/monitor-status-alert.png new file mode 100644 index 0000000000000..847a0f58f02ce Binary files /dev/null and b/docs/uptime-guide/images/monitor-status-alert.png differ diff --git a/docs/uptime/images/observability_integrations.png b/docs/uptime-guide/images/observability_integrations.png similarity index 100% rename from docs/uptime/images/observability_integrations.png rename to docs/uptime-guide/images/observability_integrations.png diff --git a/docs/uptime/images/settings.png b/docs/uptime-guide/images/settings.png similarity index 100% rename from docs/uptime/images/settings.png rename to docs/uptime-guide/images/settings.png diff --git a/docs/uptime/images/snapshot-view.png b/docs/uptime-guide/images/snapshot-view.png similarity index 100% rename from docs/uptime/images/snapshot-view.png rename to docs/uptime-guide/images/snapshot-view.png diff --git a/docs/uptime/images/status-bar.png b/docs/uptime-guide/images/status-bar.png similarity index 100% rename from docs/uptime/images/status-bar.png rename to docs/uptime-guide/images/status-bar.png diff --git a/docs/uptime-guide/images/tls-alert.png b/docs/uptime-guide/images/tls-alert.png new file mode 100644 index 0000000000000..19efe07838903 Binary files /dev/null and b/docs/uptime-guide/images/tls-alert.png differ diff --git a/docs/uptime-guide/images/uptime-overview.png b/docs/uptime-guide/images/uptime-overview.png new file mode 100644 index 0000000000000..25c88b2d14287 Binary files /dev/null and b/docs/uptime-guide/images/uptime-overview.png differ diff --git a/docs/uptime-guide/index.asciidoc b/docs/uptime-guide/index.asciidoc index 09763182fa88f..01a93cb454ea9 100644 --- a/docs/uptime-guide/index.asciidoc +++ b/docs/uptime-guide/index.asciidoc @@ -1,5 +1,3 @@ -// short-version can be: 8, 7, 6, etc. -:short-version: 8 include::{asciidoc-dir}/../../shared/versions/stack/{source_branch}.asciidoc[] include::{asciidoc-dir}/../../shared/attributes.asciidoc[] @@ -12,3 +10,13 @@ include::install.asciidoc[] include::deployment-arch.asciidoc[] +include::app-overview.asciidoc[] + +include::monitor.asciidoc[] + +include::settings.asciidoc[] + +include::certificates.asciidoc[] + +include::alerting.asciidoc[] + diff --git a/docs/uptime-guide/install.asciidoc b/docs/uptime-guide/install.asciidoc index 0ed1270ca92ce..05b9c6665562f 100644 --- a/docs/uptime-guide/install.asciidoc +++ b/docs/uptime-guide/install.asciidoc @@ -29,7 +29,7 @@ first see the https://www.elastic.co/support/matrix[Elastic Support Matrix] for [[install-elasticsearch]] === Step 1: Install Elasticsearch -Install an Elasticsearch cluster, start it up, and make sure it's running. +Install an {es} cluster, start it up, and make sure it's running. . Verify that your system meets the https://www.elastic.co/support/matrix#matrix_jvm[minimum JVM requirements] for {es}. @@ -39,7 +39,7 @@ https://www.elastic.co/support/matrix#matrix_jvm[minimum JVM requirements] for { [[install-kibana]] === Step 2: Install Kibana -Install Kibana, start it up, and open up the web interface: +Install {kib}, start it up, and open up the web interface: . {stack-gs}/get-started-elastic-stack.html#install-kibana[Install Kibana]. . {stack-gs}/get-started-elastic-stack.html#_launch_the_kibana_web_interface[Launch the Kibana Web Interface]. @@ -48,27 +48,27 @@ Install Kibana, start it up, and open up the web interface: === Step 3: Install and configure Heartbeat Uptime requires the setup of monitors in Heartbeat. -These monitors provide the data you'll be visualizing in the {kibana-ref}/xpack-uptime.html[Uptime UI]. +These monitors provide the data you'll be visualizing in the {kibana-ref}/xpack-uptime.html[Uptime app]. -See the *Setup Instructions* in Kibana for instructions on installing and configuring Heartbeat. +For instructions on installing and configuring Heartbeat, see the *Setup Instructions* in {kib}. Additional information is available in {heartbeat-ref}/heartbeat-configuration.html[Configure Heartbeat]. [role="screenshot"] image::images/uptime-setup.png[Installation instructions on the Uptime page in Kibana] [[setup-security]] -=== Step 4: Setup Security +=== Step 4: Set up Security Secure your installation by following the {heartbeat-ref}/securing-heartbeat.html[Secure Heartbeat] documentation. [float] ==== Important considerations -* Make sure you're using the same major versions of Heartbeat and Kibana. +* Make sure you're using the same major versions of Heartbeat and {kib}. -* Index patterns tell Kibana which Elasticsearch indices you want to explore. -The Uptime UI requires a +heartbeat-{short-version}*+ index pattern. -If you have configured a different index pattern, you can use {ref}/indices-aliases.html[index aliases] to ensure data is recognized by the UI. +* Index patterns tell {kib} which {es} indices you want to explore. +The Uptime app requires a +heartbeat-{major-version-only}*+ index pattern. +If you have configured a different index pattern, you can use {ref}/indices-aliases.html[index aliases] to ensure data is recognized by the Uptime app. After you install and configure Heartbeat, -the {kibana-ref}/xpack-uptime.html[Uptime UI] will automatically populate with the Heartbeat monitors. +the {kibana-ref}/xpack-uptime.html[Uptime app] is automatically populated with the Heartbeat monitors. diff --git a/docs/uptime-guide/monitor.asciidoc b/docs/uptime-guide/monitor.asciidoc new file mode 100644 index 0000000000000..bb5d315cf63eb --- /dev/null +++ b/docs/uptime-guide/monitor.asciidoc @@ -0,0 +1,59 @@ +[role="xpack"] +[[uptime-monitor]] +=== Monitor + +The Monitor page helps you gain insights into the performance +of a specific network endpoint. A detailed visualization of +the monitor's request duration over time, as well as the `up`/`down` +status over time, is displayed. By configuring Machine Learning jobs +on this page, you can also also detect anomalies in response time data. + + +==== Status panel + +The Status panel displays a quick summary of the latest information +regarding your monitor. You can view its latest status, click a link to +visit the targeted URL, see its most recent request duration, and determine the +amount of time that has elapsed since the last check. + +When two Heartbeat instances are configured in different geographic locations +the map will show each location as a pinpoint on the map, along with the +amount of time elapsed since data was last received from that location. + +[role="screenshot"] +image::images/status-bar.png[Status bar] + + +[float] +==== Monitor charts + +The Monitor charts visualize information over the time specified in the +date range. These charts help you gain insights into how quickly requests are being resolved +by the targeted endpoint, and give you a sense of how frequently a host or endpoint +was down in your selected timespan. + +[role="screenshot"] +image::images/monitor-charts.png[Monitor charts] + +The Monitor duration chart displays request duration information for your monitor. +The area surrounding the line is the range of request time for the corresponding +bucket. The line is the average time. In the upper right hand of this panel +you can enable Anomaly detection using Machine Learning. When response times change +in an unexpected way the time range in which they occurred are highlighted with a color. + +The pings over time chart is a graphical representation of the check statuses over time. +Hover over the charts to display crosshairs with specific numeric data. + +[role="screenshot"] +image::images/crosshair-example.png[Chart crosshair] + +[float] +==== Check history + +The Check history table lists the total count of this monitor's checks for the selected +date range. To help find recent problems on a per-check basis, you can filter the checks +by status and location. This table can help you gain some insight into more granular details +about recent individual data points that Heartbeat is logging about your host or endpoint. + +[role="screenshot"] +image::images/check-history.png[Check history view] diff --git a/docs/uptime-guide/overview.asciidoc b/docs/uptime-guide/overview.asciidoc index c6bd71b1f5574..ab230b27f8cda 100644 --- a/docs/uptime-guide/overview.asciidoc +++ b/docs/uptime-guide/overview.asciidoc @@ -2,10 +2,14 @@ [[uptime-overview]] == Elastic Uptime overview -Elastic Uptime allows you to monitor the availability and response times of applications and services in real time and to detect problems before they affect users. +++++ +Overview +++++ -Elastic Uptime can help you to understand uptime and response time characteristics for your services and applications. -It can be deployed both inside and outside your organization's network, so you can analyze problems from multiple vantage points. +Elastic Uptime enables you to monitor the availability and response times of applications and services in real time and to detect problems before they affect users. + +Elastic Uptime helps you to understand uptime and response time characteristics for your services and applications. +It can be deployed both inside and outside your organization's network, so that you can analyze problems from multiple vantage points. Elastic Uptime uses these components: *Heartbeat*, *Elasticsearch* and *Kibana*. @@ -37,13 +41,11 @@ The {kibana-ref}/xpack-uptime.html[Elasticsearch Uptime app] in Kibana provides // ++ In diagram, should be Uptime app, not Uptime UI, possibly even Elastic Uptime? Also applies to Metrics/Logging/APM. // ++ Need more whitespace around components. -image::images/uptime-simple-deployment.png[Uptime simple deployment] - In this simple deployment, a single instance of Heartbeat is deployed at a single monitoring location to monitor a single service. The Heartbeat instance sends the monitoring data to Elasticsearch. Then you can use the Uptime app in Kibana to view the data from Heartbeat and determine the status of the service. -image::images/uptime-multi-deployment.png[Uptime multiple server deployment] +image::images/uptime-simple-deployment.png[Uptime simple deployment] In this deployment, two instances of Heartbeat are deployed at two different monitoring locations. Both instances monitor the same service. @@ -51,3 +53,5 @@ The Heartbeat instances send the monitoring data to Elasticsearch. As before, you can use the Uptime app in Kibana to view the Heartbeat data and determine the status of the service. When a failure occurs, the multiple monitoring locations enable you to pinpoint the area in which the failure has occurred. +image::images/uptime-multi-deployment.png[Uptime multiple server deployment] + diff --git a/docs/uptime-guide/settings.asciidoc b/docs/uptime-guide/settings.asciidoc new file mode 100644 index 0000000000000..59f9af631bfa7 --- /dev/null +++ b/docs/uptime-guide/settings.asciidoc @@ -0,0 +1,51 @@ +[role="xpack"] +[[uptime-settings]] + +=== Settings + +The Uptime settings page lets you change which Heartbeat indices are displayed +by the uptime app. Users must have the 'all' permission to modify items on this page. +Uptime settings apply to the current space only. Use different settings in different +spaces to segment different uptime use cases and domains. + +==== Indices + +Imagine your organization has one team for internal IT services, and another +for public services. Each team operates independently and is only responsible for its +own services. In this scenario, you might set up separate Heartbeat instances for each team, +writing out to index patterns named `it-heartbeat-\*`, and `external-heartbeat-\*`. You would +create separate roles and users for each in Elasticsearch, each with access to their own spaces, +named `it` and `external` respectively. Within each space you would navigate to the settings page +and set the correct index pattern to match only the indices that space is allowed to access. + +Note: The pattern set here only restricts what the Uptime app shows. Users may still be able +to manually query Elasticsearch for data outside this pattern. + +[role="screenshot"] +image::images/indices.png[Heartbeat indices] + +See the {kibana-ref}/uptime-security.html[Uptime security] and {heartbeat-ref}/securing-heartbeat.html[Heartbeat security] +docs for more information. + +==== Certificate thresholds + +You can modify settings in this section to control how Uptime will visualize your TLS values in +the <>. These settings also determine which certificates will be +selected by any TLS alert you define. + +There are two fields, `age` and `expiration`. Use the `age` threshold to specify when Uptime should warn +you about certificates that have been valid for too long. Use the `expiration` threshold to specify when Uptime should warn you +about certificates that have approaching expiration dates. + +For example, a common security requirement is to make sure that none of your organization's TLS certificates have been +valid for longer than one year. Modifying the `Age limit` field's value to 365 days will help you keep track of which +certificates you may want to refresh. + +Likewise, to see which of your TLS certificates are close to expiring ahead of time, specify +an `Expiration threshold` on this page. When the count of a certificate's remaining valid days falls +below this threshold, Uptime will consider it in a warning state. When you define a TLS alert, you receive a +notification from Uptime about the certificate. + +[role="screenshot"] +image::images/cert-exp.png[Certification expiration thresholds] + diff --git a/docs/uptime/alerting.asciidoc b/docs/uptime/alerting.asciidoc deleted file mode 100644 index 24f7628e960f9..0000000000000 --- a/docs/uptime/alerting.asciidoc +++ /dev/null @@ -1,30 +0,0 @@ -[role="xpack"] -[[uptime-alerting]] - -== Uptime alerting - -The Uptime app integrates with Kibana's {kibana-ref}/alerting-getting-started.html[alerting and actions] -feature. It provides a set of built-in actions and Uptime specific threshold alerts for you to use -and enables central management of all alerts from <>. - -[float] -=== Monitor status alerts - -To receive alerts when a monitor goes down, use the alerting menu at the top of the -overview page. Use a query in the alert flyout to determine which monitors to check -with your alert. If you already have a query in the overview page search bar it will -be carried over into this box. - -[role="screenshot"] -image::uptime/images/monitor-status-alert-flyout.png[Create monitor status alert flyout] - -[float] -=== TLS alerts - -Uptime also provides the ability to create an alert that will notify you when one or -more of your monitors have a TLS certificate that will expire within some threshold, -or when its age exceeds a limit. The values for these thresholds are configurable on -the <>. - -[role="screenshot"] -image::uptime/images/tls-alert-flyout.png[Create TLS alert flyout] diff --git a/docs/uptime/certificates.asciidoc b/docs/uptime/certificates.asciidoc deleted file mode 100644 index cc604d7196648..0000000000000 --- a/docs/uptime/certificates.asciidoc +++ /dev/null @@ -1,15 +0,0 @@ -[role="xpack"] -[[uptime-certificates]] - -== Certificates - -[role="screenshot"] -image::uptime/images/certificates-page.png[Certificates] - -The certificates page allows you to visualize TLS certificate data in your indices. In addition to the -common name, associated monitors, issuer information, and SHA fingerprints, Uptime also assigns a status -derived from the threshold values in the <>. - -Several of the columns on this page are sortable. You can use the search bar at the top of the view -to find values in most of the TLS-related fields in your Uptime indices. Additionally, you can -create a TLS alert using the `Alerts` dropdown at the top of the page. diff --git a/docs/uptime/images/monitor-status-alert-flyout.png b/docs/uptime/images/monitor-status-alert-flyout.png deleted file mode 100644 index 407e69fc5e86e..0000000000000 Binary files a/docs/uptime/images/monitor-status-alert-flyout.png and /dev/null differ diff --git a/docs/uptime/images/tls-alert-flyout.png b/docs/uptime/images/tls-alert-flyout.png deleted file mode 100644 index 07c725c858a00..0000000000000 Binary files a/docs/uptime/images/tls-alert-flyout.png and /dev/null differ diff --git a/docs/uptime/images/uptime-overview.png b/docs/uptime/images/uptime-overview.png new file mode 100644 index 0000000000000..25c88b2d14287 Binary files /dev/null and b/docs/uptime/images/uptime-overview.png differ diff --git a/docs/uptime/index.asciidoc b/docs/uptime/index.asciidoc index c44ef366eaaa4..66c9e9357420f 100644 --- a/docs/uptime/index.asciidoc +++ b/docs/uptime/index.asciidoc @@ -1,25 +1,19 @@ +[chapter] [role="xpack"] [[xpack-uptime]] = Uptime -[partintro] --- -Uptime allows you to monitor the status of network endpoints via HTTP/S, TCP, and ICMP. +The Uptime app in {kib} enables you to monitor the status of network endpoints via HTTP/S, TCP, and ICMP. You can explore endpoint status over time, drill down into specific monitors, -and easily view a high-level snapshot of your environment at any point in time. +and view a high-level snapshot of your environment at any point in time. + +[role="screenshot"] +image::images/uptime-overview.png[Uptime app overview] + +[float] +=== Get started To get started with Elastic Uptime, refer to {uptime-guide}/install-uptime.html[Install Uptime]. -* <> -* <> -* <> -* <> -* <> --- -include::overview.asciidoc[] -include::monitor.asciidoc[] -include::settings.asciidoc[] -include::certificates.asciidoc[] -include::alerting.asciidoc[] diff --git a/docs/uptime/monitor.asciidoc b/docs/uptime/monitor.asciidoc deleted file mode 100644 index 8a4be1f11a721..0000000000000 --- a/docs/uptime/monitor.asciidoc +++ /dev/null @@ -1,59 +0,0 @@ -[role="xpack"] -[[uptime-monitor]] -== Monitor - -The Monitor page will help you get further insight into the performance -of a specific network endpoint. You'll see a detailed visualization of -the monitor's request duration over time, as well as the `up`/`down` -status over time. You can also also detect anomalies in response time data -by configuring Machine Learning jobs on this page. - -[float] -=== Status panel - -[role="screenshot"] -image::uptime/images/status-bar.png[Status bar] - -The Status panel displays a quick summary of the latest information -regarding your monitor. You can view its latest status, click a link to -visit the targeted URL, see its most recent request duration, and determine the -amount of time that has elapsed since the last check. - -When two Heartbeat instances are configured in different geographic locations -the map will show each location as a pinpoint on the map, along with the -amount of time elapsed since data was last received from that location. - - -[float] -=== Monitor charts - -[role="screenshot"] -image::uptime/images/monitor-charts.png[Monitor charts] - -The Monitor charts visualize information over the time specified in the -date range. These charts can help you gain insight into how quickly requests are being resolved -by the targeted endpoint, and give you a sense of how frequently a host or endpoint -was down in your selected timespan. - -The Monitor duration chart displays request duration information for your monitor. -The area surrounding the line is the range of request time for the corresponding -bucket. The line is the average time. Anomaly detection using Machine Learning -can be configured in the upper right hand of this panel. When response times change -in an unexpected way the time range in which they occurred will be given filled with a color. - -The pings over time chart is a graphical representation of the check statuses over time. -Hover over the charts to display crosshairs with more specific numeric data. - -[role="screenshot"] -image::uptime/images/crosshair-example.png[Chart crosshair] - -[float] -=== Check history - -[role="screenshot"] -image::uptime/images/check-history.png[Check history view] - -The Check history displays the total count of this monitor's checks for the selected -date range. You can additionally filter the checks by status and location to help find recent problems -on a per-check basis. This table can help you gain some insight into more granular details -about recent individual data points Heartbeat is logging about your host or endpoint. diff --git a/docs/uptime/overview.asciidoc b/docs/uptime/overview.asciidoc deleted file mode 100644 index b449beddd240c..0000000000000 --- a/docs/uptime/overview.asciidoc +++ /dev/null @@ -1,62 +0,0 @@ -[role="xpack"] -[[uptime-overview]] - -== Overview - -The Uptime overview is intended to help you quickly identify and diagnose outages and -other connectivity issues within your network or environment. There is a date range -selection that is global to the Uptime UI; you can use this selection to highlight -an absolute date range, or a relative one, similar to other areas of Kibana. - -[float] -=== Filter bar - -[role="screenshot"] -image::uptime/images/filter-bar.png[Filter bar] - -The filter bar is designed to let you quickly view specific groups of monitors, or even -an individual monitor, if you have defined many. - -This control allows you to use automated filter options, as well as input custom filter -text to select specific monitors by field, URL, ID, and other attributes. - -[float] -=== Snapshot panel - -[role="screenshot"] -image::uptime/images/snapshot-view.png[Snapshot view] - -This panel is intended to quickly give you a sense of the overall -status of the environment you're monitoring, or a subset of those monitors. -Here, you can see the total number of detected monitors within the selected -Uptime date range. In addition to the total, the counts for the number of monitors -in an `up` or `down` state are displayed, based on the last check reported by Heartbeat -for each monitor. - -Next to the counts, there is a histogram displaying the change over time throughout the -selected date range. - -[float] -=== Monitor list - -[role="screenshot"] -image::uptime/images/monitor-list.png[Monitor list] - -The Monitor list displays information at the level of individual monitors. -The data shown here will flesh out your individual monitors, and provide a quick -way to navigate to a more in-depth visualization for interesting hosts or endpoints. - -This table includes information like the most recent status, when the monitor was last checked, its -ID and URL, its IP address, and a dedicated sparkline showing its check status over time. - -[float] -=== Observability integrations - -[role="screenshot"] -image::uptime/images/observability_integrations.png[Observability integrations] - -The Monitor list also contains a menu of possible integrations. If Uptime detects Kubernetes or -Docker related host information, it will provide links to open the Metrics app or Logs app pre-filtered -for this host. Additionally, this feature supplies links to simply filter the other views on the host's -IP address, to help you quickly determine if these other solutions contain data relevant to your current -interest. diff --git a/docs/uptime/settings.asciidoc b/docs/uptime/settings.asciidoc deleted file mode 100644 index 131772609cb59..0000000000000 --- a/docs/uptime/settings.asciidoc +++ /dev/null @@ -1,48 +0,0 @@ -[role="xpack"] -[[uptime-settings]] - -== Settings - -[role="screenshot"] -image::uptime/images/settings.png[Settings page] - -=== Indices - -The Uptime settings page lets you change which Heartbeat indices are displayed -by the uptime app. Users must have the 'all' permission to modify items on this page. -Uptime settings apply to the current space only. Use different settings in different -spaces to segment different uptime use cases and domains. - -As an example, imagine your organization has one team for internal IT services, and another -for public services. Each team operates independently and is only responsible for its -own services. In this scenario, you might set up separate Heartbeat instances for each team, -writing out to index patterns named `it-heartbeat-\*`, and `external-heartbeat-\*`. You would -create separate roles and users for each in Elasticsearch, each with access to their own spaces, -named `it` and `external` respectively. Within each space you would navigate to the settings page -and set the correct index pattern to match only the indices that space is allowed to access. - -Note that the pattern set here only restricts what the Uptime app shows. Users may still be able -to manually query Elasticsearch for data outside this pattern! - -See the <> -and {heartbeat-ref}/securing-heartbeat.html[Heartbeat security] -docs for more information. - -=== Certificate thresholds - -You can modify settings in this section to control how Uptime will visualize your TLS values in the Certificates page. -These settings also determine which certificates will be selected by any TLS alert you define. - -There are two fields, `age` and `expiration`. Use the `age` threshold to specify when Uptime should warn -you about certificates that have been valid for too long. Use the `expiration` threshold to make Uptime warn you -about certificates that have approaching expiration dates. - -For example, a common security requirement is to make sure that none of your organization's TLS certificates have been -valid for longer than one year. Modifying the `Age limit` field's value to 365 days will help you keep track of which -certificates you may want to refresh. - -Likewise, to see which of your TLS certificates are close to expiring ahead of time, specify -an `Expiration threshold` on this page. When the count of a certificate's remaining valid days falls -below this threshold, Uptime will consider it in a warning state. If you have defined a TLS alert, you will -receive a notification from Uptime about the certificate. - diff --git a/docs/user/monitoring/configuring-monitoring.asciidoc b/docs/user/monitoring/configuring-monitoring.asciidoc index 776a76b24c4ec..7bcddcac923b2 100644 --- a/docs/user/monitoring/configuring-monitoring.asciidoc +++ b/docs/user/monitoring/configuring-monitoring.asciidoc @@ -1,20 +1,20 @@ [role="xpack"] [[configuring-monitoring]] -== Configuring monitoring in {kib} +== Configure monitoring in {kib} ++++ -Configuring monitoring +Configure monitoring ++++ -If you enable the {monitor-features} in your cluster, there are two methods to +If you enable the {monitor-features} in your cluster, there are two methods to collect metrics about {kib}: * <> * <> -You can also use {kib} to +You can also use {kib} to <>. -To learn about monitoring in general, see +To learn about monitoring in general, see {ref}/monitor-elasticsearch-cluster.html[Monitor a cluster]. include::monitoring-metricbeat.asciidoc[] diff --git a/docs/user/monitoring/monitoring-kibana.asciidoc b/docs/user/monitoring/monitoring-kibana.asciidoc index bb619ac79e143..ba55e2d16c150 100644 --- a/docs/user/monitoring/monitoring-kibana.asciidoc +++ b/docs/user/monitoring/monitoring-kibana.asciidoc @@ -1,45 +1,45 @@ [role="xpack"] [[monitoring-kibana]] -=== Collecting monitoring data using legacy collectors +=== Collect monitoring data using legacy collectors ++++ Legacy collection methods ++++ -If you enable the Elastic {monitor-features} in your cluster, you can -optionally collect metrics about {kib}. +If you enable the Elastic {monitor-features} in your cluster, you can +optionally collect metrics about {kib}. -The following method involves sending the metrics to the production cluster, -which ultimately routes them to the monitoring cluster. For the recommended -method, see <>. +The following method involves sending the metrics to the production cluster, +which ultimately routes them to the monitoring cluster. For the recommended +method, see <>. -To learn about monitoring in general, see -{ref}/monitor-elasticsearch-cluster.html[Monitor a cluster]. +To learn about monitoring in general, see +{ref}/monitor-elasticsearch-cluster.html[Monitor a cluster]. . Set the `xpack.monitoring.collection.enabled` setting to `true` on each -node in the production cluster. By default, it is is disabled (`false`). -+ +node in the production cluster. By default, it is is disabled (`false`). ++ -- -NOTE: You can specify this setting in either the `elasticsearch.yml` on each -node or across the cluster as a dynamic cluster setting. If {es} -{security-features} are enabled, you must have `monitor` cluster privileges to +NOTE: You can specify this setting in either the `elasticsearch.yml` on each +node or across the cluster as a dynamic cluster setting. If {es} +{security-features} are enabled, you must have `monitor` cluster privileges to view the cluster settings and `manage` cluster privileges to change them. -- ** To update the cluster settings in {kib}: -... Open {kib} in your web browser. +... Open {kib} in your web browser. + -- -By default, if you are running {kib} locally, go to `http://localhost:5601/`. +By default, if you are running {kib} locally, go to `http://localhost:5601/`. -If {es} {security-features} are enabled, log in. +If {es} {security-features} are enabled, log in. -- ... In the side navigation, click *Stack Monitoring*. If data collection is -disabled, you are prompted to turn it on. +disabled, you are prompted to turn it on. -** From the Console or command line, set `xpack.monitoring.collection.enabled` +** From the Console or command line, set `xpack.monitoring.collection.enabled` to `true` on the production cluster. + + -- @@ -57,13 +57,13 @@ PUT _cluster/settings } ---------------------------------- -For more information, see {ref}/monitoring-settings.html[Monitoring settings in {es}] +For more information, see {ref}/monitoring-settings.html[Monitoring settings in {es}] and {ref}/cluster-update-settings.html[Cluster update settings]. -- . Verify that `monitoring.enabled` and -`monitoring.kibana.collection.enabled` are set to `true` in the -`kibana.yml` file. These are the default values. For +`monitoring.kibana.collection.enabled` are set to `true` in the +`kibana.yml` file. These are the default values. For more information, see <>. . Identify where to send monitoring data. {kib} automatically @@ -72,13 +72,13 @@ in the `kibana.yml` file. This property has a default value of `http://localhost:9200`. + + -- -[TIP] +[TIP] =============================== -In production environments, we strongly recommend using a separate cluster -(referred to as the _monitoring cluster_) to store the data. Using a separate -monitoring cluster prevents production cluster outages from impacting your -ability to access your monitoring data. It also prevents monitoring activities -from impacting the performance of your production cluster. +In production environments, we strongly recommend using a separate cluster +(referred to as the _monitoring cluster_) to store the data. Using a separate +monitoring cluster prevents production cluster outages from impacting your +ability to access your monitoring data. It also prevents monitoring activities +from impacting the performance of your production cluster. If {security} is enabled on the production cluster, use an HTTPS URL such as `https://:9200` in this setting. @@ -97,4 +97,4 @@ used when {kib} sends monitoring data to the production cluster. . <>. -. <>. +. <>. diff --git a/docs/user/monitoring/monitoring-metricbeat.asciidoc b/docs/user/monitoring/monitoring-metricbeat.asciidoc index 61aeaf21d3a4b..f2b32ba1de5dd 100644 --- a/docs/user/monitoring/monitoring-metricbeat.asciidoc +++ b/docs/user/monitoring/monitoring-metricbeat.asciidoc @@ -1,19 +1,19 @@ [role="xpack"] [[monitoring-metricbeat]] -=== Collecting {kib} monitoring data with {metricbeat} +=== Collect {kib} monitoring data with {metricbeat} [subs="attributes"] ++++ -Collecting monitoring data with {metricbeat} +Collect monitoring data with {metricbeat} ++++ -In 6.4 and later, you can use {metricbeat} to collect data about {kib} -and ship it to the monitoring cluster, rather than routing it through the -production cluster as described in <>. +In 6.4 and later, you can use {metricbeat} to collect data about {kib} +and ship it to the monitoring cluster, rather than routing it through the +production cluster as described in <>. image::user/monitoring/images/metricbeat.png[Example monitoring architecture] -To learn about monitoring in general, see -{ref}/monitor-elasticsearch-cluster.html[Monitor a cluster]. +To learn about monitoring in general, see +{ref}/monitor-elasticsearch-cluster.html[Monitor a cluster]. //NOTE: The tagged regions are re-used in the Stack Overview. @@ -21,46 +21,46 @@ To learn about monitoring in general, see + -- // tag::disable-kibana-collection[] -Add the following setting in the {kib} configuration file (`kibana.yml`): +Add the following setting in the {kib} configuration file (`kibana.yml`): [source,yaml] ---------------------------------- monitoring.kibana.collection.enabled: false ---------------------------------- -Leave the `monitoring.enabled` set to its default value (`true`). +Leave the `monitoring.enabled` set to its default value (`true`). // end::disable-kibana-collection[] -For more information, see +For more information, see <>. -- . <>. -. Set the `xpack.monitoring.collection.enabled` setting to `true` on +. Set the `xpack.monitoring.collection.enabled` setting to `true` on each node in the production cluster. By default, it is disabled (`false`). + -- -NOTE: You can specify this setting in either the `elasticsearch.yml` on each -node or across the cluster as a dynamic cluster setting. If {es} -{security-features} are enabled, you must have `monitor` cluster privileges to +NOTE: You can specify this setting in either the `elasticsearch.yml` on each +node or across the cluster as a dynamic cluster setting. If {es} +{security-features} are enabled, you must have `monitor` cluster privileges to view the cluster settings and `manage` cluster privileges to change them. -- ** In {kib}: -... Open {kib} in your web browser. +... Open {kib} in your web browser. + -- -If you are running {kib} locally, go to `http://localhost:5601/`. +If you are running {kib} locally, go to `http://localhost:5601/`. -If the Elastic {security-features} are enabled, log in. +If the Elastic {security-features} are enabled, log in. -- ... In the side navigation, click *Stack Monitoring*. If data collection is -disabled, you are prompted to turn it on. +disabled, you are prompted to turn it on. -** From the Console or command line, set `xpack.monitoring.collection.enabled` +** From the Console or command line, set `xpack.monitoring.collection.enabled` to `true` on the production cluster. + + -- @@ -78,7 +78,7 @@ PUT _cluster/settings } ---------------------------------- -For more information, see {ref}/monitoring-settings.html[Monitoring settings in {es}] +For more information, see {ref}/monitoring-settings.html[Monitoring settings in {es}] and {ref}/cluster-update-settings.html[Cluster update settings]. -- @@ -89,7 +89,7 @@ same server as {kib}. + -- // tag::enable-kibana-module[] -For example, to enable the default configuration in the `modules.d` directory, +For example, to enable the default configuration in the `modules.d` directory, run the following command: ["source","sh",subs="attributes,callouts"] @@ -97,9 +97,9 @@ run the following command: metricbeat modules enable kibana-xpack ---------------------------------------------------------------------- -For more information, see -{metricbeat-ref}/configuration-metricbeat.html[Specify which modules to run] and -{metricbeat-ref}/metricbeat-module-kibana.html[{kib} module]. +For more information, see +{metricbeat-ref}/configuration-metricbeat.html[Specify which modules to run] and +{metricbeat-ref}/metricbeat-module-kibana.html[{kib} module]. // end::enable-kibana-module[] -- @@ -130,15 +130,15 @@ access it via HTTPS. For example, use a `hosts` setting like // end::configure-kibana-module[] // tag::remote-monitoring-user[] -If the Elastic {security-features} are enabled, you must also provide a user -ID and password so that {metricbeat} can collect metrics successfully: +If the Elastic {security-features} are enabled, you must also provide a user +ID and password so that {metricbeat} can collect metrics successfully: -.. Create a user on the production cluster that has the -`remote_monitoring_collector` {ref}/built-in-roles.html[built-in role]. -Alternatively, use the `remote_monitoring_user` +.. Create a user on the production cluster that has the +`remote_monitoring_collector` {ref}/built-in-roles.html[built-in role]. +Alternatively, use the `remote_monitoring_user` {ref}/built-in-users.html[built-in user]. -.. Add the `username` and `password` settings to the {kib} module configuration +.. Add the `username` and `password` settings to the {kib} module configuration file. // end::remote-monitoring-user[] -- @@ -156,19 +156,19 @@ the following command: ---------------------------------------------------------------------- metricbeat modules disable system ---------------------------------------------------------------------- -// end::disable-system-module[] +// end::disable-system-module[] -- . Identify where to send the monitoring data. + + -- -TIP: In production environments, we strongly recommend using a separate cluster -(referred to as the _monitoring cluster_) to store the data. Using a separate -monitoring cluster prevents production cluster outages from impacting your -ability to access your monitoring data. It also prevents monitoring activities +TIP: In production environments, we strongly recommend using a separate cluster +(referred to as the _monitoring cluster_) to store the data. Using a separate +monitoring cluster prevents production cluster outages from impacting your +ability to access your monitoring data. It also prevents monitoring activities from impacting the performance of your production cluster. -For example, specify the {es} output information in the {metricbeat} +For example, specify the {es} output information in the {metricbeat} configuration file (`metricbeat.yml`): [source,yaml] @@ -176,13 +176,13 @@ configuration file (`metricbeat.yml`): output.elasticsearch: # Array of hosts to connect to. hosts: ["http://es-mon-1:9200", "http://es-mon2:9200"] <1> - + # Optional protocol and basic auth credentials. #protocol: "https" #username: "elastic" #password: "changeme" ---------------------------------- -<1> In this example, the data is stored on a monitoring cluster with nodes +<1> In this example, the data is stored on a monitoring cluster with nodes `es-mon-1` and `es-mon-2`. If you configured the monitoring cluster to use encrypted communications, you @@ -192,22 +192,22 @@ must access it via HTTPS. For example, use a `hosts` setting like IMPORTANT: The {es} {monitor-features} use ingest pipelines, therefore the cluster that stores the monitoring data must have at least one ingest node. -If the {es} {security-features} are enabled on the monitoring cluster, you -must provide a valid user ID and password so that {metricbeat} can send metrics -successfully: +If the {es} {security-features} are enabled on the monitoring cluster, you +must provide a valid user ID and password so that {metricbeat} can send metrics +successfully: -.. Create a user on the monitoring cluster that has the -`remote_monitoring_agent` {ref}/built-in-roles.html[built-in role]. -Alternatively, use the `remote_monitoring_user` +.. Create a user on the monitoring cluster that has the +`remote_monitoring_agent` {ref}/built-in-roles.html[built-in role]. +Alternatively, use the `remote_monitoring_user` {ref}/built-in-users.html[built-in user]. -.. Add the `username` and `password` settings to the {es} output information in +.. Add the `username` and `password` settings to the {es} output information in the {metricbeat} configuration file. -For more information about these configuration options, see +For more information about these configuration options, see {metricbeat-ref}/elasticsearch-output.html[Configure the {es} output]. -- -. {metricbeat-ref}/metricbeat-starting.html[Start {metricbeat}]. +. {metricbeat-ref}/metricbeat-starting.html[Start {metricbeat}]. -. <>. +. <>. diff --git a/docs/user/monitoring/viewing-metrics.asciidoc b/docs/user/monitoring/viewing-metrics.asciidoc index 0a5535e6e1a91..48dd2be9ee6a2 100644 --- a/docs/user/monitoring/viewing-metrics.asciidoc +++ b/docs/user/monitoring/viewing-metrics.asciidoc @@ -1,96 +1,96 @@ [role="xpack"] [[monitoring-data]] -=== Viewing monitoring data in {kib} +=== View monitoring data in {kib} ++++ -Viewing monitoring data +View monitoring data ++++ -After you collect monitoring data for one or more products in the {stack}, you -can configure {kib} to retrieve that information and display it in on the +After you collect monitoring data for one or more products in the {stack}, you +can configure {kib} to retrieve that information and display it in on the *Stack Monitoring* page. At a minimum, you must have monitoring data for the {es} production cluster. Once that data exists, {kib} can display monitoring data for other products in the cluster. -. Identify where to retrieve monitoring data from. +. Identify where to retrieve monitoring data from. + -- -The cluster that contains the monitoring data is referred to -as the _monitoring cluster_. +The cluster that contains the monitoring data is referred to +as the _monitoring cluster_. -TIP: If the monitoring data is stored on a *dedicated* monitoring cluster, it is -accessible even when the cluster you're monitoring is not. If you have at least -a gold license, you can send data from multiple clusters to the same monitoring -cluster and view them all through the same instance of {kib}. +TIP: If the monitoring data is stored on a *dedicated* monitoring cluster, it is +accessible even when the cluster you're monitoring is not. If you have at least +a gold license, you can send data from multiple clusters to the same monitoring +cluster and view them all through the same instance of {kib}. -By default, data is retrieved from the cluster specified in the +By default, data is retrieved from the cluster specified in the `elasticsearch.hosts` value in the `kibana.yml` file. If you want to retrieve it from a different cluster, set `monitoring.ui.elasticsearch.hosts`. -To learn more about typical monitoring architectures, -see {ref}/how-monitoring-works.html[How monitoring works] and +To learn more about typical monitoring architectures, +see {ref}/how-monitoring-works.html[How monitoring works] and {ref}/monitoring-production.html[Monitoring in a production environment]. -- . Verify that `monitoring.ui.enabled` is set to `true`, which is the -default value, in the `kibana.yml` file. For more information, see +default value, in the `kibana.yml` file. For more information, see <>. -. If the Elastic {security-features} are enabled on the monitoring cluster, you -must provide a user ID and password so {kib} can retrieve the data. +. If the Elastic {security-features} are enabled on the monitoring cluster, you +must provide a user ID and password so {kib} can retrieve the data. -.. Create a user that has the `monitoring_user` +.. Create a user that has the `monitoring_user` {ref}/built-in-roles.html[built-in role] on the monitoring cluster. -.. Add the `monitoring.ui.elasticsearch.username` and +.. Add the `monitoring.ui.elasticsearch.username` and `monitoring.ui.elasticsearch.password` settings in the `kibana.yml` file. If these settings are omitted, {kib} uses the `elasticsearch.username` and -`elasticsearch.password` setting values. For more +`elasticsearch.password` setting values. For more information, see {kibana-ref}/using-kibana-with-security.html[Configuring security in {kib}]. -. (Optional) Configure {kib} to encrypt communications between the {kib} server -and the monitoring cluster. See <>. +. (Optional) Configure {kib} to encrypt communications between the {kib} server +and the monitoring cluster. See <>. -. If the Elastic {security-features} are enabled on the {kib} server, only users -that have the authority to access {kib} indices and to read the monitoring indices -can use the monitoring dashboards. +. If the Elastic {security-features} are enabled on the {kib} server, only users +that have the authority to access {kib} indices and to read the monitoring indices +can use the monitoring dashboards. + -- -NOTE: These users must exist on the monitoring cluster. If you are accessing a -remote monitoring cluster, you must use credentials that are valid on both the +NOTE: These users must exist on the monitoring cluster. If you are accessing a +remote monitoring cluster, you must use credentials that are valid on both the {kib} server and the monitoring cluster. -- -.. Create users that have the `monitoring_user` and `kibana_admin` +.. Create users that have the `monitoring_user` and `kibana_admin` {ref}/built-in-roles.html[built-in roles]. -. Open {kib} in your web browser. +. Open {kib} in your web browser. + -- -By default, if you are running {kib} locally, go to `http://localhost:5601/`. +By default, if you are running {kib} locally, go to `http://localhost:5601/`. -If the Elastic {security-features} are enabled, log in. +If the Elastic {security-features} are enabled, log in. -- -. In the side navigation, click *Stack Monitoring*. +. In the side navigation, click *Stack Monitoring*. + -- -If data collection is disabled, you are prompted to turn on data collection. -If {es} {security-features} are enabled, you must have `manage` cluster -privileges to turn on data collection. +If data collection is disabled, you are prompted to turn on data collection. +If {es} {security-features} are enabled, you must have `manage` cluster +privileges to turn on data collection. -NOTE: If you are using a separate monitoring cluster, you do not need to turn on -data collection. The dashboards appear when there is data in the monitoring -cluster. +NOTE: If you are using a separate monitoring cluster, you do not need to turn on +data collection. The dashboards appear when there is data in the monitoring +cluster. -- You'll see cluster alerts that require your attention and a summary of the available monitoring metrics for {es}, Logstash, {kib}, and Beats. To view additional information, click the -Overview, Nodes, Indices, or Instances links. See <>. +Overview, Nodes, Indices, or Instances links. See <>. [role="screenshot"] image::images/monitoring-dashboard.png[Monitoring dashboard] diff --git a/docs/user/security/securing-communications/index.asciidoc b/docs/user/security/securing-communications/index.asciidoc index 3bdc59b90b3fd..0509c6b13d54a 100644 --- a/docs/user/security/securing-communications/index.asciidoc +++ b/docs/user/security/securing-communications/index.asciidoc @@ -1,7 +1,7 @@ [[configuring-tls]] -=== Encrypting communications in {kib} +=== Encrypt communications in {kib} ++++ -Encrypting communications +Encrypt communications ++++ Secure Sockets Layer (SSL) and Transport Layer Security (TLS) provide encryption for data-in-transit. While these terms are often used @@ -14,7 +14,7 @@ contains a public key and has an associated -- but separate -- private key; thes supports certificates and private keys in PEM or PKCS#12 format. [[configuring-tls-browser-kib]] -==== Encrypting traffic between the browser and {kib} +==== Encrypt traffic between the browser and {kib} NOTE: You do not need to enable the {es} {security-features} for this type of encryption. @@ -106,7 +106,7 @@ server.ssl.enabled: true After making these changes, you must always access {kib} via HTTPS. For example, https://.com. [[configuring-tls-kib-es]] -==== Encrypting traffic between {kib} and {es} +==== Encrypt traffic between {kib} and {es} NOTE: To perform this step, you must {ref}/configuring-security.html[enable the {es} {security-features}] or you must have a proxy that provides an HTTPS endpoint for {es}. diff --git a/docs/user/security/securing-kibana.asciidoc b/docs/user/security/securing-kibana.asciidoc index f4178bacb111e..33c81961fcd7b 100644 --- a/docs/user/security/securing-kibana.asciidoc +++ b/docs/user/security/securing-kibana.asciidoc @@ -1,8 +1,8 @@ [role="xpack"] [[using-kibana-with-security]] -== Configuring security in {kib} +== Configure security in {kib} ++++ -Configuring security +Configure security ++++ {kib} users have to log in when {security} is enabled on your cluster. You diff --git a/docs/user/setup.asciidoc b/docs/user/setup.asciidoc index 53e2de66c5287..31e7d157d1bc7 100644 --- a/docs/user/setup.asciidoc +++ b/docs/user/setup.asciidoc @@ -1,5 +1,5 @@ [[setup]] -= Set Up Kibana += Set up Kibana [partintro] -- @@ -48,11 +48,9 @@ the patch version. include::{kib-repo-dir}/setup/install.asciidoc[] -include::{kib-repo-dir}/setup/start-stop.asciidoc[] - include::{kib-repo-dir}/setup/settings.asciidoc[] -include::{kib-repo-dir}/setup/docker.asciidoc[] +include::{kib-repo-dir}/setup/start-stop.asciidoc[] include::{kib-repo-dir}/setup/access.asciidoc[] diff --git a/examples/alerting_example/kibana.json b/examples/alerting_example/kibana.json index 2b6389649cef9..6c04218ca45e2 100644 --- a/examples/alerting_example/kibana.json +++ b/examples/alerting_example/kibana.json @@ -4,6 +4,6 @@ "kibanaVersion": "kibana", "server": true, "ui": true, - "requiredPlugins": ["triggers_actions_ui", "charts", "data", "alerts", "actions"], + "requiredPlugins": ["triggers_actions_ui", "charts", "data", "alerts", "actions", "developerExamples"], "optionalPlugins": [] } diff --git a/examples/alerting_example/public/plugin.tsx b/examples/alerting_example/public/plugin.tsx index 524ff18bd434e..f0635a1071f64 100644 --- a/examples/alerting_example/public/plugin.tsx +++ b/examples/alerting_example/public/plugin.tsx @@ -17,7 +17,7 @@ * under the License. */ -import { Plugin, CoreSetup, AppMountParameters } from 'kibana/public'; +import { Plugin, CoreSetup, AppMountParameters, AppNavLinkStatus } from '../../../src/core/public'; import { PluginSetupContract as AlertingSetup } from '../../../x-pack/plugins/alerts/public'; import { ChartsPluginStart } from '../../../src/plugins/charts/public'; import { TriggersAndActionsUIPublicPluginSetup } from '../../../x-pack/plugins/triggers_actions_ui/public'; @@ -25,6 +25,7 @@ import { DataPublicPluginStart } from '../../../src/plugins/data/public'; import { getAlertType as getAlwaysFiringAlertType } from './alert_types/always_firing'; import { getAlertType as getPeopleInSpaceAlertType } from './alert_types/astros'; import { registerNavigation } from './alert_types'; +import { DeveloperExamplesSetup } from '../../developer_examples/public'; export type Setup = void; export type Start = void; @@ -32,6 +33,7 @@ export type Start = void; export interface AlertingExamplePublicSetupDeps { alerts: AlertingSetup; triggers_actions_ui: TriggersAndActionsUIPublicPluginSetup; + developerExamples: DeveloperExamplesSetup; } export interface AlertingExamplePublicStartDeps { @@ -44,11 +46,12 @@ export interface AlertingExamplePublicStartDeps { export class AlertingExamplePlugin implements Plugin { public setup( core: CoreSetup, - { alerts, triggers_actions_ui }: AlertingExamplePublicSetupDeps + { alerts, triggers_actions_ui, developerExamples }: AlertingExamplePublicSetupDeps ) { core.application.register({ id: 'AlertingExample', title: 'Alerting Example', + navLinkStatus: AppNavLinkStatus.hidden, async mount(params: AppMountParameters) { const [coreStart, depsStart] = await core.getStartServices(); const { renderApp } = await import('./application'); @@ -60,6 +63,21 @@ export class AlertingExamplePlugin implements Plugin Promise<{ num: number }>; @@ -27,6 +28,7 @@ export interface ExplorerService { export interface BfetchExplorerSetupPlugins { bfetch: BfetchPublicSetup; + developerExamples: DeveloperExamplesSetup; } export interface BfetchExplorerStartPlugins { @@ -36,9 +38,9 @@ export interface BfetchExplorerStartPlugins { export class BfetchExplorerPlugin implements Plugin { public setup( core: CoreSetup, - plugins: BfetchExplorerSetupPlugins + { bfetch, developerExamples }: BfetchExplorerSetupPlugins ) { - const double = plugins.bfetch.batchedFunction<{ num: number }, { num: number }>({ + const double = bfetch.batchedFunction<{ num: number }, { num: number }>({ url: '/bfetch_explorer/double', }); @@ -49,8 +51,25 @@ export class BfetchExplorerPlugin implements Plugin { core.application.register({ id: 'bfetch-explorer', title: 'bfetch explorer', + navLinkStatus: AppNavLinkStatus.hidden, mount: mount(core, explorer), }); + + developerExamples.register({ + appId: 'bfetch-explorer', + title: 'bfetch', + description: + 'bfetch is a service that allows to batch HTTP requests and streams responses back.', + links: [ + { + label: 'README', + href: 'https://github.com/elastic/kibana/blob/master/src/plugins/bfetch/README.md', + iconType: 'logoGithub', + size: 's', + target: '_blank', + }, + ], + }); } public start() {} diff --git a/examples/demo_search/public/async_demo_search_strategy.ts b/examples/demo_search/public/async_demo_search_strategy.ts index 7a3f33ce05a75..862324002840c 100644 --- a/examples/demo_search/public/async_demo_search_strategy.ts +++ b/examples/demo_search/public/async_demo_search_strategy.ts @@ -17,53 +17,27 @@ * under the License. */ -import { Observable } from 'rxjs'; -import { - ISearchContext, - TSearchStrategyProvider, - ISearchStrategy, -} from '../../../src/plugins/data/public'; - -import { ASYNC_DEMO_SEARCH_STRATEGY, IAsyncDemoResponse } from '../common'; +import { Observable, from } from 'rxjs'; +import { CoreSetup } from 'kibana/public'; +import { flatMap } from 'rxjs/operators'; +import { ISearch } from '../../../src/plugins/data/public'; import { ASYNC_SEARCH_STRATEGY } from '../../../x-pack/plugins/data_enhanced/public'; +import { ASYNC_DEMO_SEARCH_STRATEGY, IAsyncDemoResponse } from '../common'; +import { DemoDataSearchStartDependencies } from './types'; -/** - * This demo search strategy provider simply provides a shortcut for calling the DEMO_ASYNC_SEARCH_STRATEGY - * on the server side, without users having to pass it in explicitly, and it takes advantage of the - * already registered ASYNC_SEARCH_STRATEGY that exists on the client. - * - * so instead of callers having to do: - * - * ``` - * search( - * { ...request, serverStrategy: DEMO_ASYNC_SEARCH_STRATEGY }, - * options, - * ASYNC_SEARCH_STRATEGY - * ) as Observable, - *``` - - * They can instead just do - * - * ``` - * search(request, options, DEMO_ASYNC_SEARCH_STRATEGY); - * ``` - * - * and are ensured type safety in regard to the request and response objects. - * - * @param context - context supplied by other plugins. - * @param search - a search function to access other strategies that have already been registered. - */ -export const asyncDemoClientSearchStrategyProvider: TSearchStrategyProvider = ( - context: ISearchContext -): ISearchStrategy => { - const asyncStrategyProvider = context.getSearchStrategy(ASYNC_SEARCH_STRATEGY); - const { search } = asyncStrategyProvider(context); - return { - search: (request, options) => { - return search( - { ...request, serverStrategy: ASYNC_DEMO_SEARCH_STRATEGY }, - options - ) as Observable; - }, +export function asyncDemoClientSearchStrategyProvider(core: CoreSetup) { + const search: ISearch = (request, options) => { + return from(core.getStartServices()).pipe( + flatMap((startServices) => { + const asyncStrategy = (startServices[1] as DemoDataSearchStartDependencies).data.search.getSearchStrategy( + ASYNC_SEARCH_STRATEGY + ); + return asyncStrategy.search( + { ...request, serverStrategy: ASYNC_DEMO_SEARCH_STRATEGY }, + options + ) as Observable; + }) + ); }; -}; + return { search }; +} diff --git a/examples/demo_search/public/demo_search_strategy.ts b/examples/demo_search/public/demo_search_strategy.ts index 8dc2779a8544c..d56d827a5c0f8 100644 --- a/examples/demo_search/public/demo_search_strategy.ts +++ b/examples/demo_search/public/demo_search_strategy.ts @@ -17,11 +17,12 @@ * under the License. */ -import { Observable } from 'rxjs'; -import { ISearchContext, SYNC_SEARCH_STRATEGY } from '../../../src/plugins/data/public'; -import { TSearchStrategyProvider, ISearchStrategy } from '../../../src/plugins/data/public'; - +import { Observable, from } from 'rxjs'; +import { flatMap } from 'rxjs/operators'; +import { CoreSetup } from 'kibana/public'; +import { ISearch, SYNC_SEARCH_STRATEGY } from '../../../src/plugins/data/public'; import { DEMO_SEARCH_STRATEGY, IDemoResponse } from '../common'; +import { DemoDataSearchStartDependencies } from './types'; /** * This demo search strategy provider simply provides a shortcut for calling the DEMO_SEARCH_STRATEGY @@ -31,7 +32,7 @@ import { DEMO_SEARCH_STRATEGY, IDemoResponse } from '../common'; * so instead of callers having to do: * * ``` - * context.search( + * data.search.search( * { ...request, serverStrategy: DEMO_SEARCH_STRATEGY }, * options, * SYNC_SEARCH_STRATEGY @@ -41,24 +42,24 @@ import { DEMO_SEARCH_STRATEGY, IDemoResponse } from '../common'; * They can instead just do * * ``` - * context.search(request, options, DEMO_SEARCH_STRATEGY); + * data.search.search(request, options, DEMO_SEARCH_STRATEGY); * ``` * * and are ensured type safety in regard to the request and response objects. - * - * @param context - context supplied by other plugins. - * @param search - a search function to access other strategies that have already been registered. */ -export const demoClientSearchStrategyProvider: TSearchStrategyProvider = ( - context: ISearchContext -): ISearchStrategy => { - const syncStrategyProvider = context.getSearchStrategy(SYNC_SEARCH_STRATEGY); - const { search } = syncStrategyProvider(context); - return { - search: (request, options) => { - return search({ ...request, serverStrategy: DEMO_SEARCH_STRATEGY }, options) as Observable< - IDemoResponse - >; - }, +export function demoClientSearchStrategyProvider(core: CoreSetup) { + const search: ISearch = (request, options) => { + return from(core.getStartServices()).pipe( + flatMap((startServices) => { + const syncStrategy = (startServices[1] as DemoDataSearchStartDependencies).data.search.getSearchStrategy( + SYNC_SEARCH_STRATEGY + ); + return syncStrategy.search( + { ...request, serverStrategy: DEMO_SEARCH_STRATEGY }, + options + ) as Observable; + }) + ); }; -}; + return { search }; +} diff --git a/examples/demo_search/public/plugin.ts b/examples/demo_search/public/plugin.ts index a2539cc7a21c5..5d074c19903e2 100644 --- a/examples/demo_search/public/plugin.ts +++ b/examples/demo_search/public/plugin.ts @@ -17,7 +17,6 @@ * under the License. */ -import { DataPublicPluginSetup } from '../../../src/plugins/data/public'; import { Plugin, CoreSetup } from '../../../src/core/public'; import { DEMO_SEARCH_STRATEGY, @@ -29,10 +28,7 @@ import { } from '../common'; import { demoClientSearchStrategyProvider } from './demo_search_strategy'; import { asyncDemoClientSearchStrategyProvider } from './async_demo_search_strategy'; - -interface DemoDataSearchSetupDependencies { - data: DataPublicPluginSetup; -} +import { DemoDataSearchSetupDependencies, DemoDataSearchStartDependencies } from './types'; /** * Add the typescript mappings for our search strategy to the request and @@ -55,16 +51,13 @@ declare module '../../../src/plugins/data/public' { } } -export class DemoDataPlugin implements Plugin { - public setup(core: CoreSetup, deps: DemoDataSearchSetupDependencies) { - deps.data.search.registerSearchStrategyProvider( - DEMO_SEARCH_STRATEGY, - demoClientSearchStrategyProvider - ); - deps.data.search.registerSearchStrategyProvider( - ASYNC_DEMO_SEARCH_STRATEGY, - asyncDemoClientSearchStrategyProvider - ); +export class DemoDataPlugin + implements Plugin { + public setup(core: CoreSetup, { data }: DemoDataSearchSetupDependencies) { + const demoClientSearchStrategy = demoClientSearchStrategyProvider(core); + const asyncDemoClientSearchStrategy = asyncDemoClientSearchStrategyProvider(core); + data.search.registerSearchStrategy(DEMO_SEARCH_STRATEGY, demoClientSearchStrategy); + data.search.registerSearchStrategy(ASYNC_DEMO_SEARCH_STRATEGY, asyncDemoClientSearchStrategy); } public start() {} diff --git a/examples/demo_search/public/types.ts b/examples/demo_search/public/types.ts new file mode 100644 index 0000000000000..64725da7df870 --- /dev/null +++ b/examples/demo_search/public/types.ts @@ -0,0 +1,28 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { DataPublicPluginStart, DataPublicPluginSetup } from '../../../src/plugins/data/public'; + +export interface DemoDataSearchSetupDependencies { + data: DataPublicPluginSetup; +} + +export interface DemoDataSearchStartDependencies { + data: DataPublicPluginStart; +} diff --git a/examples/developer_examples/README.md b/examples/developer_examples/README.md new file mode 100644 index 0000000000000..1a57838c43d24 --- /dev/null +++ b/examples/developer_examples/README.md @@ -0,0 +1,36 @@ +## Developer examples + +Owner: Kibana application architecture team + +The developer examples app is a landing page where developers go to search for working, tested examples of various developer +services. Add your a link to your example using the developerExamples `register` function offered on the `setup` contract: + +```ts + setup(core, { developerExamples }) { + developerExamples.register({ + appId: 'myFooExampleApp', + title: 'Foo services', + description: `Foo services let you do bar and zed.`, + links: [ + { + label: 'README', + href: 'https://github.com/elastic/kibana/tree/master/src/plugins/foo/README.md', + iconType: 'logoGithub', + target: '_blank', + size: 's', + }, + ], + image: img, + }); + } +``` + +Run Kibana with developer examples via: + +``` +yarn start --run-examples +``` + +Then navigate to "Developer examples": + + diff --git a/examples/developer_examples/kibana.json b/examples/developer_examples/kibana.json new file mode 100644 index 0000000000000..8c9ec2e4dcbfc --- /dev/null +++ b/examples/developer_examples/kibana.json @@ -0,0 +1,9 @@ +{ + "id": "developerExamples", + "version": "0.0.1", + "kibanaVersion": "kibana", + "server": false, + "ui": true, + "requiredPlugins": [], + "optionalPlugins": [] +} diff --git a/examples/developer_examples/navigation.png b/examples/developer_examples/navigation.png new file mode 100644 index 0000000000000..ac72f697e5db0 Binary files /dev/null and b/examples/developer_examples/navigation.png differ diff --git a/examples/developer_examples/public/app.tsx b/examples/developer_examples/public/app.tsx new file mode 100644 index 0000000000000..2ce21bae75e21 --- /dev/null +++ b/examples/developer_examples/public/app.tsx @@ -0,0 +1,117 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React, { useState } from 'react'; +import ReactDOM from 'react-dom'; + +import { + EuiText, + EuiPageContent, + EuiCard, + EuiPageContentHeader, + EuiFlexGroup, + EuiFlexItem, + EuiFieldSearch, + EuiListGroup, + EuiHighlight, + EuiLink, + EuiButtonIcon, +} from '@elastic/eui'; +import { AppMountParameters } from '../../../src/core/public'; +import { ExampleDefinition } from './types'; + +interface Props { + examples: ExampleDefinition[]; + navigateToApp: (appId: string) => void; + getUrlForApp: (appId: string) => string; +} + +function DeveloperExamples({ examples, navigateToApp, getUrlForApp }: Props) { + const [search, setSearch] = useState(''); + + const lcSearch = search.toLowerCase(); + const filteredExamples = !lcSearch + ? examples + : examples.filter((def) => { + if (def.description.toLowerCase().indexOf(lcSearch) >= 0) return true; + if (def.title.toLowerCase().indexOf(lcSearch) >= 0) return true; + return false; + }); + + return ( + + + +

Developer examples

+

+ The following examples showcase services and APIs that are available to developers. + setSearch(e.target.value)} + isClearable={true} + aria-label="Search developer examples" + /> +

+
+
+ + {filteredExamples.map((def) => ( + + + {def.description} + + } + title={ + + { + navigateToApp(def.appId); + }} + > + + {def.title} + + + + window.open(getUrlForApp(def.appId), '_blank', 'noopener, noreferrer') + } + > + Open in new tab + + + } + image={def.image} + footer={def.links ? : undefined} + /> + + ))} + +
+ ); +} + +export const renderApp = (props: Props, element: AppMountParameters['element']) => { + ReactDOM.render(, element); + + return () => ReactDOM.unmountComponentAtNode(element); +}; diff --git a/examples/developer_examples/public/index.ts b/examples/developer_examples/public/index.ts new file mode 100644 index 0000000000000..616fb011e3705 --- /dev/null +++ b/examples/developer_examples/public/index.ts @@ -0,0 +1,24 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { DeveloperExamplesPlugin } from './plugin'; + +export const plugin = () => new DeveloperExamplesPlugin(); + +export { DeveloperExamplesSetup } from './plugin'; diff --git a/examples/developer_examples/public/plugin.ts b/examples/developer_examples/public/plugin.ts new file mode 100644 index 0000000000000..a0aa601660f37 --- /dev/null +++ b/examples/developer_examples/public/plugin.ts @@ -0,0 +1,68 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + CoreSetup, + Plugin, + AppMountParameters, + DEFAULT_APP_CATEGORIES, +} from '../../../src/core/public'; + +import { ExampleDefinition } from './types'; + +export interface DeveloperExamplesSetup { + register: (def: ExampleDefinition) => void; +} + +export class DeveloperExamplesPlugin implements Plugin { + private examplesRegistry: ExampleDefinition[] = []; + + public setup(core: CoreSetup) { + const examples = this.examplesRegistry; + core.application.register({ + id: 'developerExamples', + title: 'Developer examples', + order: -2000, + category: DEFAULT_APP_CATEGORIES.kibana, + async mount(params: AppMountParameters) { + const { renderApp } = await import('./app'); + const [coreStart] = await core.getStartServices(); + return renderApp( + { + examples, + navigateToApp: (appId: string) => coreStart.application.navigateToApp(appId), + getUrlForApp: (appId: string) => coreStart.application.getUrlForApp(appId), + }, + params.element + ); + }, + }); + + const api: DeveloperExamplesSetup = { + register: (def) => { + this.examplesRegistry.push(def); + }, + }; + return api; + } + + public start() {} + + public stop() {} +} diff --git a/examples/developer_examples/public/types.ts b/examples/developer_examples/public/types.ts new file mode 100644 index 0000000000000..0ef359ef64a23 --- /dev/null +++ b/examples/developer_examples/public/types.ts @@ -0,0 +1,34 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { EuiListGroupItemProps } from '@elastic/eui'; + +export interface ExampleDefinition { + /** + * The application id that is the landing page for the example. + */ + appId: string; + title: string; + description: string; + image?: string; + /** + * Any additional links you want to show, for example to the github README. + */ + links?: EuiListGroupItemProps[]; +} diff --git a/examples/developer_examples/tsconfig.json b/examples/developer_examples/tsconfig.json new file mode 100644 index 0000000000000..d508076b33199 --- /dev/null +++ b/examples/developer_examples/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./target", + "skipLibCheck": true + }, + "include": [ + "index.ts", + "public/**/*.ts", + "public/**/*.tsx", + "server/**/*.ts", + "../../typings/**/*", + ], + "exclude": [] +} diff --git a/examples/embeddable_explorer/kibana.json b/examples/embeddable_explorer/kibana.json index 3e4b074fb6b12..aa14549d0460f 100644 --- a/examples/embeddable_explorer/kibana.json +++ b/examples/embeddable_explorer/kibana.json @@ -4,6 +4,6 @@ "kibanaVersion": "kibana", "server": false, "ui": true, - "requiredPlugins": ["uiActions", "inspector", "embeddable", "embeddableExamples"], + "requiredPlugins": ["uiActions", "inspector", "embeddable", "embeddableExamples", "developerExamples"], "optionalPlugins": [] } diff --git a/examples/embeddable_explorer/public/embeddables.png b/examples/embeddable_explorer/public/embeddables.png new file mode 100644 index 0000000000000..90b287962d248 Binary files /dev/null and b/examples/embeddable_explorer/public/embeddables.png differ diff --git a/examples/embeddable_explorer/public/plugin.tsx b/examples/embeddable_explorer/public/plugin.tsx index bba1b1748e207..2a5023d2dd63a 100644 --- a/examples/embeddable_explorer/public/plugin.tsx +++ b/examples/embeddable_explorer/public/plugin.tsx @@ -16,12 +16,13 @@ * specific language governing permissions and limitations * under the License. */ - -import { Plugin, CoreSetup, AppMountParameters } from 'kibana/public'; import { EmbeddableExamplesStart } from 'examples/embeddable_examples/public/plugin'; +import { Plugin, CoreSetup, AppMountParameters, AppNavLinkStatus } from '../../../src/core/public'; import { UiActionsService } from '../../../src/plugins/ui_actions/public'; import { EmbeddableStart } from '../../../src/plugins/embeddable/public'; import { Start as InspectorStart } from '../../../src/plugins/inspector/public'; +import { DeveloperExamplesSetup } from '../../developer_examples/public'; +import img from './embeddables.png'; interface StartDeps { uiActions: UiActionsService; @@ -30,11 +31,16 @@ interface StartDeps { embeddableExamples: EmbeddableExamplesStart; } +interface SetupDeps { + developerExamples: DeveloperExamplesSetup; +} + export class EmbeddableExplorerPlugin implements Plugin { - public setup(core: CoreSetup) { + public setup(core: CoreSetup, { developerExamples }: SetupDeps) { core.application.register({ id: 'embeddableExplorer', title: 'Embeddable explorer', + navLinkStatus: AppNavLinkStatus.hidden, async mount(params: AppMountParameters) { const [coreStart, depsStart] = await core.getStartServices(); const { renderApp } = await import('./app'); @@ -55,6 +61,25 @@ export class EmbeddableExplorerPlugin implements Plugin) { + public setup( + core: CoreSetup, + { developerExamples }: SetupDeps + ) { core.application.register({ id: 'searchExplorer', title: 'Search Explorer', + navLinkStatus: AppNavLinkStatus.hidden, async mount(params: AppMountParameters) { const [coreStart, depsStart] = await core.getStartServices(); const { renderApp } = await import('./application'); return renderApp(coreStart, depsStart, params); }, }); + + developerExamples.register({ + appId: 'searchExplorer', + title: 'Data search strategy services', + description: `Data search services can be used to query Elasticsearch in away that supports background search + and partial results, when available. It also automatically incorporates settings such as requestTimeout and includeFrozen. + Use the provided ES search strategy, or register your own. + `, + links: [ + { + label: 'README', + href: + 'https://github.com/elastic/kibana/blob/master/src/plugins/data/public/search/README.md', + iconType: 'logoGithub', + size: 's', + target: '_blank', + }, + ], + }); } public start() {} diff --git a/examples/state_containers_examples/kibana.json b/examples/state_containers_examples/kibana.json index 581b399e3ffba..66da207cb4e77 100644 --- a/examples/state_containers_examples/kibana.json +++ b/examples/state_containers_examples/kibana.json @@ -4,6 +4,6 @@ "kibanaVersion": "kibana", "server": true, "ui": true, - "requiredPlugins": ["navigation", "data"], + "requiredPlugins": ["navigation", "data", "developerExamples"], "optionalPlugins": [] } diff --git a/examples/state_containers_examples/public/plugin.ts b/examples/state_containers_examples/public/plugin.ts index 38ebf315789c0..a4cf7dfd798f3 100644 --- a/examples/state_containers_examples/public/plugin.ts +++ b/examples/state_containers_examples/public/plugin.ts @@ -17,15 +17,21 @@ * under the License. */ -import { AppMountParameters, CoreSetup, Plugin } from 'kibana/public'; +import { AppMountParameters, CoreSetup, Plugin, AppNavLinkStatus } from '../../../src/core/public'; import { AppPluginDependencies } from './with_data_services/types'; import { PLUGIN_ID, PLUGIN_NAME } from '../common'; +import { DeveloperExamplesSetup } from '../../developer_examples/public'; + +interface SetupDeps { + developerExamples: DeveloperExamplesSetup; +} export class StateContainersExamplesPlugin implements Plugin { - public setup(core: CoreSetup) { + public setup(core: CoreSetup, { developerExamples }: SetupDeps) { core.application.register({ id: 'stateContainersExampleBrowserHistory', title: 'State containers example - browser history routing', + navLinkStatus: AppNavLinkStatus.hidden, async mount(params: AppMountParameters) { const { renderApp, History } = await import('./todo/app'); return renderApp(params, { @@ -38,6 +44,7 @@ export class StateContainersExamplesPlugin implements Plugin { core.application.register({ id: 'stateContainersExampleHashHistory', title: 'State containers example - hash history routing', + navLinkStatus: AppNavLinkStatus.hidden, async mount(params: AppMountParameters) { const { renderApp, History } = await import('./todo/app'); return renderApp(params, { @@ -51,6 +58,7 @@ export class StateContainersExamplesPlugin implements Plugin { core.application.register({ id: PLUGIN_ID, title: PLUGIN_NAME, + navLinkStatus: AppNavLinkStatus.hidden, async mount(params: AppMountParameters) { // Load application bundle const { renderApp } = await import('./with_data_services/application'); @@ -60,6 +68,62 @@ export class StateContainersExamplesPlugin implements Plugin { return renderApp(coreStart, depsStart as AppPluginDependencies, params); }, }); + + developerExamples.register({ + appId: 'stateContainersExampleBrowserHistory', + title: 'State containers using browser history', + description: `An example todo app that uses browser history and state container utilities like createStateContainerReactHelpers, + createStateContainer, createKbnUrlStateStorage, createSessionStorageStateStorage, + syncStates and getStateFromKbnUrl to keep state in sync with the URL. Change some parameters, navigate away and then back, and the + state should be preserved.`, + links: [ + { + label: 'README', + href: + 'https://github.com/elastic/kibana/tree/master/src/plugins/kibana_utils/docs/state_containers/README.md', + iconType: 'logoGithub', + size: 's', + target: '_blank', + }, + ], + }); + + developerExamples.register({ + appId: 'stateContainersExampleHashHistory', + title: 'State containers using hash history', + description: `An example todo app that uses hash history and state container utilities like createStateContainerReactHelpers, + createStateContainer, createKbnUrlStateStorage, createSessionStorageStateStorage, + syncStates and getStateFromKbnUrl to keep state in sync with the URL. Change some parameters, navigate away and then back, and the + state should be preserved.`, + links: [ + { + label: 'README', + href: + 'https://github.com/elastic/kibana/tree/master/src/plugins/kibana_utils/docs/state_containers/README.md', + iconType: 'logoGithub', + size: 's', + target: '_blank', + }, + ], + }); + + developerExamples.register({ + appId: PLUGIN_ID, + title: 'Sync state from a query bar with the url', + description: `Shows how to use data.syncQueryStateWitUrl in combination with state container utilities from kibana_utils to + show a query bar that stores state in the url and is kept in sync. + `, + links: [ + { + label: 'README', + href: + 'https://github.com/elastic/kibana/blob/master/src/plugins/data/public/query/state_sync/README.md', + iconType: 'logoGithub', + size: 's', + target: '_blank', + }, + ], + }); } public start() {} diff --git a/examples/state_containers_examples/public/with_data_services/application.tsx b/examples/state_containers_examples/public/with_data_services/application.tsx index 67a2a8b791ae5..d09b77fbf25ee 100644 --- a/examples/state_containers_examples/public/with_data_services/application.tsx +++ b/examples/state_containers_examples/public/with_data_services/application.tsx @@ -27,7 +27,7 @@ import { createKbnUrlStateStorage } from '../../../../src/plugins/kibana_utils/p export const renderApp = ( { notifications, http }: CoreStart, { navigation, data }: AppPluginDependencies, - { appBasePath, element, history }: AppMountParameters + { element, history }: AppMountParameters ) => { const kbnUrlStateStorage = createKbnUrlStateStorage({ useHash: false, history }); diff --git a/examples/state_containers_examples/public/with_data_services/components/app.tsx b/examples/state_containers_examples/public/with_data_services/components/app.tsx index baf627fd62a32..04bdb53efa502 100644 --- a/examples/state_containers_examples/public/with_data_services/components/app.tsx +++ b/examples/state_containers_examples/public/with_data_services/components/app.tsx @@ -78,14 +78,7 @@ const { useContainer: useAppStateContainer, } = createStateContainerReactHelpers>(); -const App = ({ - notifications, - http, - navigation, - data, - history, - kbnUrlStateStorage, -}: StateDemoAppDeps) => { +const App = ({ navigation, data, history, kbnUrlStateStorage }: StateDemoAppDeps) => { const appStateContainer = useAppStateContainer(); const appState = useAppState(); diff --git a/examples/ui_actions_explorer/kibana.json b/examples/ui_actions_explorer/kibana.json index e88739a9e44d6..f57072e89b06d 100644 --- a/examples/ui_actions_explorer/kibana.json +++ b/examples/ui_actions_explorer/kibana.json @@ -4,6 +4,6 @@ "kibanaVersion": "kibana", "server": false, "ui": true, - "requiredPlugins": ["uiActions", "uiActionsExamples"], + "requiredPlugins": ["uiActions", "uiActionsExamples", "developerExamples"], "optionalPlugins": [] } diff --git a/examples/ui_actions_explorer/public/plugin.tsx b/examples/ui_actions_explorer/public/plugin.tsx index de86b51aee3a8..670138b43b9c4 100644 --- a/examples/ui_actions_explorer/public/plugin.tsx +++ b/examples/ui_actions_explorer/public/plugin.tsx @@ -17,8 +17,8 @@ * under the License. */ -import { Plugin, CoreSetup, AppMountParameters } from 'kibana/public'; -import { UiActionsStart, UiActionsSetup } from 'src/plugins/ui_actions/public'; +import { UiActionsStart, UiActionsSetup } from '../../../src/plugins/ui_actions/public'; +import { Plugin, CoreSetup, AppMountParameters, AppNavLinkStatus } from '../../../src/core/public'; import { PHONE_TRIGGER, USER_TRIGGER, @@ -39,6 +39,8 @@ import { ACTION_VIEW_IN_MAPS, ACTION_PHONE_USER, } from './actions/actions'; +import { DeveloperExamplesSetup } from '../../developer_examples/public'; +import image from './ui_actions.png'; interface StartDeps { uiActions: UiActionsStart; @@ -46,6 +48,7 @@ interface StartDeps { interface SetupDeps { uiActions: UiActionsSetup; + developerExamples: DeveloperExamplesSetup; } declare module '../../../src/plugins/ui_actions/public' { @@ -66,7 +69,7 @@ declare module '../../../src/plugins/ui_actions/public' { } export class UiActionsExplorerPlugin implements Plugin { - public setup(core: CoreSetup<{ uiActions: UiActionsStart }>, deps: SetupDeps) { + public setup(core: CoreSetup, deps: SetupDeps) { deps.uiActions.registerTrigger({ id: COUNTRY_TRIGGER, }); @@ -98,6 +101,7 @@ export class UiActionsExplorerPlugin implements Plugin { - public setup(core: CoreSetup) { +interface SetupDeps { + developerExamples: DeveloperExamplesSetup; +} + +export class AccessLinksExplorerPlugin implements Plugin { + public setup(core: CoreSetup, { developerExamples }: SetupDeps) { core.application.register({ id: 'urlGeneratorsExplorer', title: 'Access links explorer', + navLinkStatus: AppNavLinkStatus.hidden, async mount(params: AppMountParameters) { const depsStart = (await core.getStartServices())[1]; const { renderApp } = await import('./app'); @@ -40,6 +45,26 @@ export class AccessLinksExplorerPlugin implements Plugin { type SchemaType = TypeOf; - let foo: SchemaType = { + expectType({ required: 'foo', - }; - foo = { + }); + expectType({ required: 'hello', optional: undefined, - }; - foo = { + }); + expectType({ required: 'hello', optional: 'bar', - }; + }); +}); + +describe('#extends', () => { + it('allows to extend an existing schema by adding new properties', () => { + const origin = schema.object({ + initial: schema.string(), + }); + + const extended = origin.extends({ + added: schema.number(), + }); + + expect(() => { + extended.validate({ initial: 'foo' }); + }).toThrowErrorMatchingInlineSnapshot( + `"[added]: expected value of type [number] but got [undefined]"` + ); + + expect(() => { + extended.validate({ initial: 'foo', added: 42 }); + }).not.toThrowError(); - expect(foo).toBeDefined(); + expectType>({ + added: 12, + initial: 'foo', + }); + }); + + it('allows to extend an existing schema by removing properties', () => { + const origin = schema.object({ + string: schema.string(), + number: schema.number(), + }); + + const extended = origin.extends({ number: undefined }); + + expect(() => { + extended.validate({ string: 'foo', number: 12 }); + }).toThrowErrorMatchingInlineSnapshot(`"[number]: definition for this key is missing"`); + + expect(() => { + extended.validate({ string: 'foo' }); + }).not.toThrowError(); + + expectType>({ + string: 'foo', + }); + }); + + it('allows to extend an existing schema by overriding an existing properties', () => { + const origin = schema.object({ + string: schema.string(), + mutated: schema.number(), + }); + + const extended = origin.extends({ + mutated: schema.string(), + }); + + expect(() => { + extended.validate({ string: 'foo', mutated: 12 }); + }).toThrowErrorMatchingInlineSnapshot( + `"[mutated]: expected value of type [string] but got [number]"` + ); + + expect(() => { + extended.validate({ string: 'foo', mutated: 'bar' }); + }).not.toThrowError(); + + expectType>({ + string: 'foo', + mutated: 'bar', + }); + }); + + it('properly infer the type from optional properties', () => { + const origin = schema.object({ + original: schema.maybe(schema.string()), + mutated: schema.maybe(schema.number()), + removed: schema.maybe(schema.string()), + }); + + const extended = origin.extends({ + removed: undefined, + mutated: schema.string(), + }); + + expect(() => { + extended.validate({ original: 'foo' }); + }).toThrowErrorMatchingInlineSnapshot( + `"[mutated]: expected value of type [string] but got [undefined]"` + ); + expect(() => { + extended.validate({ original: 'foo' }); + }).toThrowErrorMatchingInlineSnapshot( + `"[mutated]: expected value of type [string] but got [undefined]"` + ); + expect(() => { + extended.validate({ original: 'foo', mutated: 'bar' }); + }).not.toThrowError(); + + expectType>({ + original: 'foo', + mutated: 'bar', + }); + expectType>({ + mutated: 'bar', + }); + }); + + it(`allows to override the original schema's options`, () => { + const origin = schema.object( + { + initial: schema.string(), + }, + { defaultValue: { initial: 'foo' } } + ); + + const extended = origin.extends( + { + added: schema.number(), + }, + { defaultValue: { initial: 'bar', added: 42 } } + ); + + expect(extended.validate(undefined)).toEqual({ initial: 'bar', added: 42 }); + }); }); diff --git a/packages/kbn-config-schema/src/types/object_type.ts b/packages/kbn-config-schema/src/types/object_type.ts index fee2d02c1bfb9..431b6e905bcd4 100644 --- a/packages/kbn-config-schema/src/types/object_type.ts +++ b/packages/kbn-config-schema/src/types/object_type.ts @@ -24,6 +24,8 @@ import { ValidationError } from '../errors'; export type Props = Record>; +export type NullableProps = Record | undefined | null>; + export type TypeOf> = RT['type']; type OptionalProperties = Pick< @@ -47,6 +49,24 @@ export type ObjectResultType

= Readonly< { [K in keyof RequiredProperties

]: TypeOf } >; +type DefinedProperties = Pick< + Base, + { + [Key in keyof Base]: undefined extends Base[Key] ? never : null extends Base[Key] ? never : Key; + }[keyof Base] +>; + +type ExtendedProps

= Omit & + { [K in keyof DefinedProperties]: NP[K] }; + +type ExtendedObjectType

= ObjectType< + ExtendedProps +>; + +type ExtendedObjectTypeOptions

= ObjectTypeOptions< + ExtendedProps +>; + interface UnknownOptions { /** * Options for dealing with unknown keys: @@ -61,10 +81,13 @@ export type ObjectTypeOptions

= TypeOptions extends Type> { - private props: Record; + private props: P; + private options: ObjectTypeOptions

; + private propSchemas: Record; - constructor(props: P, { unknowns = 'forbid', ...typeOptions }: ObjectTypeOptions

= {}) { + constructor(props: P, options: ObjectTypeOptions

= {}) { const schemaKeys = {} as Record; + const { unknowns = 'forbid', ...typeOptions } = options; for (const [key, value] of Object.entries(props)) { schemaKeys[key] = value.getSchema(); } @@ -77,7 +100,93 @@ export class ObjectType

extends Type> .options({ stripUnknown: { objects: unknowns === 'ignore' } }); super(schema, typeOptions); - this.props = schemaKeys; + this.props = props; + this.propSchemas = schemaKeys; + this.options = options; + } + + /** + * Return a new `ObjectType` instance extended with given `newProps` properties. + * Original properties can be deleted from the copy by passing a `null` or `undefined` value for the key. + * + * @example + * How to add a new key to an object schema + * ```ts + * const origin = schema.object({ + * initial: schema.string(), + * }); + * + * const extended = origin.extends({ + * added: schema.number(), + * }); + * ``` + * + * How to remove an existing key from an object schema + * ```ts + * const origin = schema.object({ + * initial: schema.string(), + * toRemove: schema.number(), + * }); + * + * const extended = origin.extends({ + * toRemove: undefined, + * }); + * ``` + * + * How to override the schema's options + * ```ts + * const origin = schema.object({ + * initial: schema.string(), + * }, { defaultValue: { initial: 'foo' }}); + * + * const extended = origin.extends({ + * added: schema.number(), + * }, { defaultValue: { initial: 'foo', added: 'bar' }}); + * + * @remarks + * `extends` only support extending first-level properties. It's currently not possible to perform deep/nested extensions. + * + * ```ts + * const origin = schema.object({ + * foo: schema.string(), + * nested: schema.object({ + * a: schema.string(), + * b: schema.string(), + * }), + * }); + * + * const extended = origin.extends({ + * nested: schema.object({ + * c: schema.string(), + * }), + * }); + * + * // TypeOf is `{ foo: string; nested: { c: string } }` + * ``` + */ + public extends( + newProps: NP, + newOptions?: ExtendedObjectTypeOptions + ): ExtendedObjectType { + const extendedProps = Object.entries({ + ...this.props, + ...newProps, + }).reduce((memo, [key, value]) => { + if (value !== null && value !== undefined) { + return { + ...memo, + [key]: value, + }; + } + return memo; + }, {} as ExtendedProps); + + const extendedOptions = { + ...this.options, + ...newOptions, + } as ExtendedObjectTypeOptions; + + return new ObjectType(extendedProps, extendedOptions); } protected handleError(type: string, { reason, value }: Record) { @@ -95,10 +204,10 @@ export class ObjectType

extends Type> } validateKey(key: string, value: any) { - if (!this.props[key]) { + if (!this.propSchemas[key]) { throw new Error(`${key} is not a valid part of this schema`); } - const { value: validatedValue, error } = this.props[key].validate(value); + const { value: validatedValue, error } = this.propSchemas[key].validate(value); if (error) { throw new ValidationError(error as any, key); } diff --git a/packages/kbn-dev-utils/package.json b/packages/kbn-dev-utils/package.json index 08b2e5b226967..5000d8b7490be 100644 --- a/packages/kbn-dev-utils/package.json +++ b/packages/kbn-dev-utils/package.json @@ -13,7 +13,7 @@ "axios": "^0.19.0", "chalk": "^2.4.2", "dedent": "^0.7.0", - "execa": "^4.0.0", + "execa": "^4.0.2", "exit-hook": "^2.2.0", "getopts": "^2.2.5", "load-json-file": "^6.2.0", diff --git a/packages/kbn-dev-utils/src/tooling_log/index.ts b/packages/kbn-dev-utils/src/tooling_log/index.ts index f8009a255f010..acf944f23a816 100644 --- a/packages/kbn-dev-utils/src/tooling_log/index.ts +++ b/packages/kbn-dev-utils/src/tooling_log/index.ts @@ -19,5 +19,5 @@ export { ToolingLog } from './tooling_log'; export { ToolingLogTextWriter, ToolingLogTextWriterConfig } from './tooling_log_text_writer'; -export { pickLevelFromFlags, parseLogLevel, LogLevel } from './log_levels'; +export { pickLevelFromFlags, parseLogLevel, LogLevel, ParsedLogLevel } from './log_levels'; export { ToolingLogCollectingWriter } from './tooling_log_collecting_writer'; diff --git a/packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts b/packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts index 7e79077032156..fd59ebe5c46dc 100644 --- a/packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts +++ b/packages/kbn-dev-utils/src/tooling_log/tooling_log_collecting_writer.ts @@ -18,13 +18,14 @@ */ import { ToolingLogTextWriter } from './tooling_log_text_writer'; +import { LogLevel } from './log_levels'; export class ToolingLogCollectingWriter extends ToolingLogTextWriter { messages: string[] = []; - constructor() { + constructor(level: LogLevel = 'verbose') { super({ - level: 'verbose', + level, writeTo: { write: (msg) => { // trim trailing new line diff --git a/packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts b/packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts index b8c12433a0ebb..28ccc60428ae3 100644 --- a/packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts +++ b/packages/kbn-dev-utils/src/tooling_log/tooling_log_text_writer.ts @@ -47,7 +47,7 @@ export interface ToolingLogTextWriterConfig { function shouldWriteType(level: ParsedLogLevel, type: MessageTypes) { if (type === 'write') { - return true; + return level.name !== 'silent'; } return Boolean(level.flags[type === 'success' ? 'info' : type]); diff --git a/packages/kbn-es/package.json b/packages/kbn-es/package.json index 8b964d8399904..271b4a3dc661b 100644 --- a/packages/kbn-es/package.json +++ b/packages/kbn-es/package.json @@ -11,7 +11,7 @@ "chalk": "^2.4.2", "dedent": "^0.7.0", "del": "^5.1.0", - "execa": "^4.0.0", + "execa": "^4.0.2", "getopts": "^2.2.4", "glob": "^7.1.2", "node-fetch": "^2.6.0", diff --git a/packages/kbn-monaco/README.md b/packages/kbn-monaco/README.md new file mode 100644 index 0000000000000..c5d7dd7dbfed5 --- /dev/null +++ b/packages/kbn-monaco/README.md @@ -0,0 +1,5 @@ +# @kbn/monaco + +A customized version of monaco that is automatically configured the way we want it to be when imported as `@kbn/monaco`. Additionally, imports to this package are automatically shared with all plugins using `@kbn/ui-shared-deps`. + +Includes custom xjson language support. The `es_ui_shared` plugin has an example of how to use it, in the future we will likely expose helpers from this package to make using it everywhere a little more seamless. \ No newline at end of file diff --git a/packages/kbn-monaco/package.json b/packages/kbn-monaco/package.json new file mode 100644 index 0000000000000..170c014e6e326 --- /dev/null +++ b/packages/kbn-monaco/package.json @@ -0,0 +1,27 @@ +{ + "name": "@kbn/monaco", + "version": "1.0.0", + "private": true, + "main": "./target/index.js", + "license": "Apache-2.0", + "scripts": { + "build": "node ./scripts/build.js", + "kbn:bootstrap": "yarn build --dev" + }, + "dependencies": { + "regenerator-runtime": "^0.13.3", + "monaco-editor": "~0.17.0" + }, + "devDependencies": { + "@kbn/babel-preset": "1.0.0", + "@kbn/dev-utils": "1.0.0", + "babel-loader": "^8.0.6", + "css-loader": "^3.4.2", + "del": "^5.1.0", + "raw-loader": "3.1.0", + "supports-color": "^7.0.0", + "typescript": "3.7.2", + "webpack": "^4.41.5", + "webpack-cli": "^3.3.10" + } +} diff --git a/packages/kbn-monaco/scripts/build.js b/packages/kbn-monaco/scripts/build.js new file mode 100644 index 0000000000000..c5540e3c956c8 --- /dev/null +++ b/packages/kbn-monaco/scripts/build.js @@ -0,0 +1,64 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const path = require('path'); +const del = require('del'); +const supportsColor = require('supports-color'); +const { run } = require('@kbn/dev-utils'); + +const TARGET_BUILD_DIR = path.resolve(__dirname, '../target'); +const ROOT_DIR = path.resolve(__dirname, '../'); +const WEBPACK_CONFIG_PATH = path.resolve(ROOT_DIR, 'webpack.config.js'); + +run( + async ({ procRunner, log, flags }) => { + log.info('Deleting old output'); + + await del(TARGET_BUILD_DIR); + + const cwd = ROOT_DIR; + const env = { ...process.env }; + if (supportsColor.stdout) { + env.FORCE_COLOR = 'true'; + } + + await procRunner.run('worker', { + cmd: 'webpack', + args: ['--config', WEBPACK_CONFIG_PATH, flags.dev ? '--env.dev' : '--env.prod'], + wait: true, + env, + cwd, + }); + + await procRunner.run('tsc ', { + cmd: 'tsc', + args: [], + wait: true, + env, + cwd, + }); + + log.success('Complete'); + }, + { + flags: { + boolean: ['dev'], + }, + } +); diff --git a/packages/kbn-monaco/src/index.ts b/packages/kbn-monaco/src/index.ts new file mode 100644 index 0000000000000..9213a1bfe1327 --- /dev/null +++ b/packages/kbn-monaco/src/index.ts @@ -0,0 +1,25 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { monaco } from './monaco'; +export { XJsonLang } from './xjson'; + +/* eslint-disable-next-line @kbn/eslint/module_migration */ +import * as BarePluginApi from 'monaco-editor/esm/vs/editor/editor.api'; +export { BarePluginApi }; diff --git a/packages/kbn-ui-shared-deps/monaco.ts b/packages/kbn-monaco/src/monaco.ts similarity index 96% rename from packages/kbn-ui-shared-deps/monaco.ts rename to packages/kbn-monaco/src/monaco.ts index 42801c69a3e2c..a40b2212ef0e2 100644 --- a/packages/kbn-ui-shared-deps/monaco.ts +++ b/packages/kbn-monaco/src/monaco.ts @@ -17,6 +17,8 @@ * under the License. */ +/* eslint-disable @kbn/eslint/module_migration */ + import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'; import 'monaco-editor/esm/vs/base/common/worker/simpleWorker'; diff --git a/packages/kbn-monaco/src/xjson/README.md b/packages/kbn-monaco/src/xjson/README.md new file mode 100644 index 0000000000000..8652d0bd776d2 --- /dev/null +++ b/packages/kbn-monaco/src/xjson/README.md @@ -0,0 +1,28 @@ +# README + +This folder contains the language definitions for XJSON used by the Monaco editor. + +## Summary of contents + +Note: All source code. + +### ./worker + +The worker proxy and worker instantiation code used in both the main thread and the worker thread. + +### ./lexer_rules + +Contains the Monarch-specific language tokenization rules for XJSON. Each set of rules registers itself against monaco. + +### ./constants.ts + +Contains the unique language ID. + +### ./language + +Takes care of global setup steps for the language (like registering it against Monaco) and exports a way to load up +the grammar parser. + +### ./worker_proxy_service + +A stateful mechanism for holding a reference to the Monaco-provided proxy getter. diff --git a/packages/kbn-monaco/src/xjson/constants.ts b/packages/kbn-monaco/src/xjson/constants.ts new file mode 100644 index 0000000000000..dc107abff4ffe --- /dev/null +++ b/packages/kbn-monaco/src/xjson/constants.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const ID = 'xjson'; diff --git a/packages/kbn-monaco/src/xjson/grammar.ts b/packages/kbn-monaco/src/xjson/grammar.ts new file mode 100644 index 0000000000000..e95059f9ece2d --- /dev/null +++ b/packages/kbn-monaco/src/xjson/grammar.ts @@ -0,0 +1,213 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export enum AnnoTypes { + error = 'error', + warning = 'warning', +} + +/* eslint-disable */ + +export const createParser = () => { + 'use strict'; + let at: any, + annos: any[], // annotations + ch: any, + text: any, + value: any, + escapee: any = { + '"': '"', + '\\': '\\', + '/': '/', + b: '\b', + f: '\f', + n: '\n', + r: '\r', + t: ' ', + }, + error = function (m: string) { + throw { + at: at, + text: m, + message: m, + }; + }, + warning = function (m: string, idx: number) { + annos.push({ + type: AnnoTypes.warning, + at: idx, + text: m, + }); + }, + reset = function (newAt: number) { + ch = text.charAt(newAt); + at = newAt + 1; + }, + next = function (c?: string) { + return ( + c && c !== ch && error("Expected '" + c + "' instead of '" + ch + "'"), + (ch = text.charAt(at)), + (at += 1), + ch + ); + }, + nextUpTo = function (upTo: any, errorMessage: string) { + let currentAt = at, + i = text.indexOf(upTo, currentAt); + if (i < 0) { + error(errorMessage || "Expected '" + upTo + "'"); + } + reset(i + upTo.length); + return text.substring(currentAt, i); + }, + peek = function (c: string) { + return text.substr(at, c.length) === c; // nocommit - double check + }, + number = function () { + var number, + string = ''; + for ('-' === ch && ((string = '-'), next('-')); ch >= '0' && '9' >= ch; ) + (string += ch), next(); + if ('.' === ch) for (string += '.'; next() && ch >= '0' && '9' >= ch; ) string += ch; + if ('e' === ch || 'E' === ch) + for ( + string += ch, next(), ('-' === ch || '+' === ch) && ((string += ch), next()); + ch >= '0' && '9' >= ch; + + ) + (string += ch), next(); + return (number = +string), isNaN(number) ? (error('Bad number'), void 0) : number; + }, + string = function () { + let hex: any, + i: any, + uffff: any, + string = ''; + if ('"' === ch) { + if (peek('""')) { + // literal + next('"'); + next('"'); + return nextUpTo('"""', 'failed to find closing \'"""\''); + } else { + for (; next(); ) { + if ('"' === ch) return next(), string; + if ('\\' === ch) + if ((next(), 'u' === ch)) { + for ( + uffff = 0, i = 0; + 4 > i && ((hex = parseInt(next(), 16)), isFinite(hex)); + i += 1 + ) + uffff = 16 * uffff + hex; + string += String.fromCharCode(uffff); + } else { + if ('string' != typeof escapee[ch]) break; + string += escapee[ch]; + } + else string += ch; + } + } + } + error('Bad string'); + }, + white = function () { + for (; ch && ' ' >= ch; ) next(); + }, + word = function () { + switch (ch) { + case 't': + return next('t'), next('r'), next('u'), next('e'), !0; + case 'f': + return next('f'), next('a'), next('l'), next('s'), next('e'), !1; + case 'n': + return next('n'), next('u'), next('l'), next('l'), null; + } + error("Unexpected '" + ch + "'"); + }, + array = function () { + var array: any[] = []; + if ('[' === ch) { + if ((next('['), white(), ']' === ch)) return next(']'), array; + for (; ch; ) { + if ((array.push(value()), white(), ']' === ch)) return next(']'), array; + next(','), white(); + } + } + error('Bad array'); + }, + object = function () { + var key, + object: any = {}; + if ('{' === ch) { + if ((next('{'), white(), '}' === ch)) return next('}'), object; + for (; ch; ) { + let latchKeyStart = at; + if ( + ((key = string()), + white(), + next(':'), + Object.hasOwnProperty.call(object, key) && + warning('Duplicate key "' + key + '"', latchKeyStart), + (object[key] = value()), + white(), + '}' === ch) + ) + return next('}'), object; + next(','), white(); + } + } + error('Bad object'); + }; + return ( + (value = function () { + switch ((white(), ch)) { + case '{': + return object(); + case '[': + return array(); + case '"': + return string(); + case '-': + return number(); + default: + return ch >= '0' && '9' >= ch ? number() : word(); + } + }), + function (source: string) { + annos = []; + let errored = false; + text = source; + at = 0; + ch = ' '; + white(); + + try { + value(); + } catch (e) { + errored = true; + annos.push({ type: AnnoTypes.error, at: e.at - 1, text: e.message }); + } + if (!errored && ch) { + error('Syntax error'); + } + return { annotations: annos }; + } + ); +}; diff --git a/packages/kbn-monaco/src/xjson/index.ts b/packages/kbn-monaco/src/xjson/index.ts new file mode 100644 index 0000000000000..35fd35887bc56 --- /dev/null +++ b/packages/kbn-monaco/src/xjson/index.ts @@ -0,0 +1,24 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { registerGrammarChecker } from './language'; + +import { ID } from './constants'; + +export const XJsonLang = { registerGrammarChecker, ID }; diff --git a/packages/kbn-monaco/src/xjson/language.ts b/packages/kbn-monaco/src/xjson/language.ts new file mode 100644 index 0000000000000..fe505818d3c9a --- /dev/null +++ b/packages/kbn-monaco/src/xjson/language.ts @@ -0,0 +1,89 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// This file contains a lot of single setup logic for registering a language globally + +import { monaco } from '../monaco'; +import { WorkerProxyService } from './worker_proxy_service'; +import { registerLexerRules } from './lexer_rules'; +import { ID } from './constants'; +// @ts-ignore +import workerSrc from '!!raw-loader!../../target/public/xjson.editor.worker.js'; + +const wps = new WorkerProxyService(); + +// Register rules against shared monaco instance. +registerLexerRules(monaco); + +// In future we will need to make this map languages to workers using "id" and/or "label" values +// that get passed in. +// @ts-ignore +window.MonacoEnvironment = { + getWorker: (id: any, label: any) => { + // In kibana we will probably build this once and then load with raw-loader + const blob = new Blob([workerSrc], { type: 'application/javascript' }); + return new Worker(URL.createObjectURL(blob)); + }, +}; + +monaco.languages.onLanguage(ID, async () => { + return wps.setup(); +}); + +const OWNER = 'XJSON_GRAMMAR_CHECKER'; +export const registerGrammarChecker = (editor: monaco.editor.IEditor) => { + const allDisposables: monaco.IDisposable[] = []; + + const updateAnnos = async () => { + const { annotations } = await wps.getAnnos(); + const model = editor.getModel() as monaco.editor.ITextModel; + monaco.editor.setModelMarkers( + model, + OWNER, + annotations.map(({ at, text, type }) => { + const { column, lineNumber } = model.getPositionAt(at); + return { + startLineNumber: lineNumber, + startColumn: column, + endLineNumber: lineNumber, + endColumn: column, + message: text, + severity: type === 'error' ? monaco.MarkerSeverity.Error : monaco.MarkerSeverity.Warning, + }; + }) + ); + }; + + const onModelAdd = (model: monaco.editor.IModel) => { + allDisposables.push( + model.onDidChangeContent(async () => { + updateAnnos(); + }) + ); + + updateAnnos(); + }; + + allDisposables.push(monaco.editor.onDidCreateModel(onModelAdd)); + monaco.editor.getModels().forEach(onModelAdd); + return () => { + wps.stop(); + allDisposables.forEach((d) => d.dispose()); + }; +}; diff --git a/packages/kbn-monaco/src/xjson/lexer_rules/esql.ts b/packages/kbn-monaco/src/xjson/lexer_rules/esql.ts new file mode 100644 index 0000000000000..e75b1013d3727 --- /dev/null +++ b/packages/kbn-monaco/src/xjson/lexer_rules/esql.ts @@ -0,0 +1,270 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { monaco } from '../../monaco'; + +export const ID = 'esql'; + +const brackets = [ + { open: '[', close: ']', token: 'delimiter.square' }, + { open: '(', close: ')', token: 'delimiter.parenthesis' }, +]; + +const keywords = [ + 'describe', + 'between', + 'in', + 'like', + 'not', + 'and', + 'or', + 'desc', + 'select', + 'from', + 'where', + 'having', + 'group', + 'by', + 'order', + 'asc', + 'desc', + 'pivot', + 'for', + 'in', + 'as', + 'show', + 'columns', + 'include', + 'frozen', + 'tables', + 'escape', + 'limit', + 'rlike', + 'all', + 'distinct', + 'is', +]; +const builtinFunctions = [ + 'avg', + 'count', + 'first', + 'first_value', + 'last', + 'last_value', + 'max', + 'min', + 'sum', + 'kurtosis', + 'mad', + 'percentile', + 'percentile_rank', + 'skewness', + 'stddev_pop', + 'sum_of_squares', + 'var_pop', + 'histogram', + 'case', + 'coalesce', + 'greatest', + 'ifnull', + 'iif', + 'isnull', + 'least', + 'nullif', + 'nvl', + 'curdate', + 'current_date', + 'current_time', + 'current_timestamp', + 'curtime', + 'dateadd', + 'datediff', + 'datepart', + 'datetrunc', + 'date_add', + 'date_diff', + 'date_part', + 'date_trunc', + 'day', + 'dayname', + 'dayofmonth', + 'dayofweek', + 'dayofyear', + 'day_name', + 'day_of_month', + 'day_of_week', + 'day_of_year', + 'dom', + 'dow', + 'doy', + 'hour', + 'hour_of_day', + 'idow', + 'isodayofweek', + 'isodow', + 'isoweek', + 'isoweekofyear', + 'iso_day_of_week', + 'iso_week_of_year', + 'iw', + 'iwoy', + 'minute', + 'minute_of_day', + 'minute_of_hour', + 'month', + 'monthname', + 'month_name', + 'month_of_year', + 'now', + 'quarter', + 'second', + 'second_of_minute', + 'timestampadd', + 'timestampdiff', + 'timestamp_add', + 'timestamp_diff', + 'today', + 'week', + 'week_of_year', + 'year', + 'abs', + 'acos', + 'asin', + 'atan', + 'atan2', + 'cbrt', + 'ceil', + 'ceiling', + 'cos', + 'cosh', + 'cot', + 'degrees', + 'e', + 'exp', + 'expm1', + 'floor', + 'log', + 'log10', + 'mod', + 'pi', + 'power', + 'radians', + 'rand', + 'random', + 'round', + 'sign', + 'signum|sin', + 'sinh', + 'sqrt', + 'tan', + 'truncate', + 'ascii', + 'bit_length', + 'char', + 'character_length', + 'char_length', + 'concat', + 'insert', + 'lcase', + 'left', + 'length', + 'locate', + 'ltrim', + 'octet_length', + 'position', + 'repeat', + 'replace', + 'right', + 'rtrim', + 'space', + 'substring', + 'ucase', + 'cast', + 'convert', + 'database', + 'user', + 'st_astext', + 'st_aswkt', + 'st_distance', + 'st_geometrytype', + 'st_geomfromtext', + 'st_wkttosql', + 'st_x', + 'st_y', + 'st_z', + 'score', +]; + +export const lexerRules = { + defaultToken: 'invalid', + ignoreCase: true, + tokenPostfix: '', + keywords, + builtinFunctions, + brackets, + tokenizer: { + root: [ + [ + /[a-zA-Z_$][a-zA-Z0-9_$]*\b/, + { + cases: { + '@keywords': 'keyword', + '@builtinFunctions': 'identifier', + '@default': 'identifier', + }, + }, + ], + [/[()]/, '@brackets'], + [/--.*$/, 'comment'], + [/\/\*/, 'comment', '@comment'], + [/\/.*$/, 'comment'], + + [/".*?"/, 'string'], + + [/'.*?'/, 'constant'], + [/`.*?`/, 'string'], + // whitespace + [/[ \t\r\n]+/, { token: '@whitespace' }], + [/[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b/, 'entity.name.function'], + [/⇐|<⇒|\*|\.|\:\:|\+|\-|\/|\/\/|%|&|\^|~|<|>|<=|=>|==|!=|<>|=/, 'keyword.operator'], + [/[\(]/, 'paren.lparen'], + [/[\)]/, 'paren.rparen'], + [/\s+/, 'text'], + ], + numbers: [ + [/0[xX][0-9a-fA-F]*/, 'number'], + [/[$][+-]*\d*(\.\d*)?/, 'number'], + [/((\d+(\.\d*)?)|(\.\d+))([eE][\-+]?\d+)?/, 'number'], + ], + strings: [ + [/N'/, { token: 'string', next: '@string' }], + [/'/, { token: 'string', next: '@string' }], + ], + string: [ + [/[^']+/, 'string'], + [/''/, 'string'], + [/'/, { token: 'string', next: '@pop' }], + ], + comment: [ + [/[^\/*]+/, 'comment'], + [/\*\//, 'comment', '@pop'], + [/[\/*]/, 'comment'], + ], + }, +} as monaco.languages.IMonarchLanguage; diff --git a/packages/kbn-monaco/src/xjson/lexer_rules/index.ts b/packages/kbn-monaco/src/xjson/lexer_rules/index.ts new file mode 100644 index 0000000000000..515de09510a61 --- /dev/null +++ b/packages/kbn-monaco/src/xjson/lexer_rules/index.ts @@ -0,0 +1,33 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* eslint-disable-next-line @kbn/eslint/module_migration */ +import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'; +import * as xJson from './xjson'; +import * as esql from './esql'; +import * as painless from './painless'; + +export const registerLexerRules = (m: typeof monaco) => { + m.languages.register({ id: xJson.ID }); + m.languages.setMonarchTokensProvider(xJson.ID, xJson.lexerRules); + m.languages.register({ id: painless.ID }); + m.languages.setMonarchTokensProvider(painless.ID, painless.lexerRules); + m.languages.register({ id: esql.ID }); + m.languages.setMonarchTokensProvider(esql.ID, esql.lexerRules); +}; diff --git a/packages/kbn-monaco/src/xjson/lexer_rules/painless.ts b/packages/kbn-monaco/src/xjson/lexer_rules/painless.ts new file mode 100644 index 0000000000000..676eb3134026a --- /dev/null +++ b/packages/kbn-monaco/src/xjson/lexer_rules/painless.ts @@ -0,0 +1,194 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { monaco } from '../../monaco'; + +export const ID = 'painless'; + +/** + * Extends the default type for a Monarch language so we can use + * attribute references (like @keywords to reference the keywords list) + * in the defined tokenizer + */ +interface Language extends monaco.languages.IMonarchLanguage { + default: string; + brackets: any; + keywords: string[]; + symbols: RegExp; + escapes: RegExp; + digits: RegExp; + primitives: string[]; + octaldigits: RegExp; + binarydigits: RegExp; + constants: string[]; + operators: string[]; +} + +export const lexerRules = { + default: 'invalid', + tokenPostfix: '', + // painless does not use < >, so we define our own + brackets: [ + ['{', '}', 'delimiter.curly'], + ['[', ']', 'delimiter.square'], + ['(', ')', 'delimiter.parenthesis'], + ], + keywords: [ + 'if', + 'in', + 'else', + 'while', + 'do', + 'for', + 'continue', + 'break', + 'return', + 'new', + 'try', + 'catch', + 'throw', + 'this', + 'instanceof', + ], + primitives: ['void', 'boolean', 'byte', 'short', 'char', 'int', 'long', 'float', 'double', 'def'], + constants: ['true', 'false'], + operators: [ + '=', + '>', + '<', + '!', + '~', + '?', + '?:', + '?.', + ':', + '==', + '===', + '<=', + '>=', + '!=', + '!==', + '&&', + '||', + '++', + '--', + '+', + '-', + '*', + '/', + '&', + '|', + '^', + '%', + '<<', + '>>', + '>>>', + '+=', + '-=', + '*=', + '/=', + '&=', + '|=', + '^=', + '%=', + '<<=', + '>>=', + '>>>=', + '->', + '::', + '=~', + '==~', + ], + symbols: /[=> { + worker.initialize((ctx: any, createData: any) => { + return new XJsonWorker(ctx); + }); +}; diff --git a/packages/kbn-monaco/src/xjson/worker/xjson_worker.ts b/packages/kbn-monaco/src/xjson/worker/xjson_worker.ts new file mode 100644 index 0000000000000..501adcacb6990 --- /dev/null +++ b/packages/kbn-monaco/src/xjson/worker/xjson_worker.ts @@ -0,0 +1,35 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* eslint-disable-next-line @kbn/eslint/module_migration */ +import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'; +import { createParser } from '../grammar'; + +export class XJsonWorker { + constructor(private ctx: monaco.worker.IWorkerContext) {} + private parser: any; + + async parse() { + if (!this.parser) { + this.parser = createParser(); + } + const [model] = this.ctx.getMirrorModels(); + return this.parser(model.getValue()); + } +} diff --git a/packages/kbn-monaco/src/xjson/worker_proxy_service.ts b/packages/kbn-monaco/src/xjson/worker_proxy_service.ts new file mode 100644 index 0000000000000..17d6d56e51e59 --- /dev/null +++ b/packages/kbn-monaco/src/xjson/worker_proxy_service.ts @@ -0,0 +1,55 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { AnnoTypes } from './grammar'; +import { monaco } from '../monaco'; +import { XJsonWorker } from './worker'; +import { ID } from './constants'; + +export interface Annotation { + name?: string; + type: AnnoTypes; + text: string; + at: number; +} + +export interface AnnotationsResponse { + annotations: Annotation[]; +} + +export class WorkerProxyService { + private worker: monaco.editor.MonacoWebWorker | undefined; + + public async getAnnos(): Promise { + if (!this.worker) { + throw new Error('Worker Proxy Service has not been setup!'); + } + await this.worker.withSyncedResources(monaco.editor.getModels().map(({ uri }) => uri)); + const proxy = await this.worker.getProxy(); + return proxy.parse(); + } + + public setup() { + this.worker = monaco.editor.createWebWorker({ label: ID, moduleId: '' }); + } + + public stop() { + if (this.worker) this.worker.dispose(); + } +} diff --git a/packages/kbn-monaco/tsconfig.json b/packages/kbn-monaco/tsconfig.json new file mode 100644 index 0000000000000..95acfd32b24dd --- /dev/null +++ b/packages/kbn-monaco/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./target", + "declaration": true, + "sourceMap": true, + "types": [ + "jest", + "node" + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/packages/kbn-monaco/webpack.config.js b/packages/kbn-monaco/webpack.config.js new file mode 100644 index 0000000000000..1a7d8c031670c --- /dev/null +++ b/packages/kbn-monaco/webpack.config.js @@ -0,0 +1,51 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const path = require('path'); + +const createLangWorkerConfig = (lang) => ({ + mode: 'production', + entry: path.resolve(__dirname, 'src', lang, 'worker', `${lang}.worker.ts`), + output: { + path: path.resolve(__dirname, 'target/public'), + filename: `${lang}.editor.worker.js`, + }, + resolve: { + modules: ['node_modules'], + extensions: ['.js', '.ts', '.tsx'], + }, + stats: 'errors-only', + module: { + rules: [ + { + test: /\.(js|ts)$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader', + options: { + babelrc: false, + presets: [require.resolve('@kbn/babel-preset/webpack_preset')], + }, + }, + }, + ], + }, +}); + +module.exports = [createLangWorkerConfig('xjson')]; diff --git a/packages/kbn-monaco/yarn.lock b/packages/kbn-monaco/yarn.lock new file mode 120000 index 0000000000000..3f82ebc9cdbae --- /dev/null +++ b/packages/kbn-monaco/yarn.lock @@ -0,0 +1 @@ +../../yarn.lock \ No newline at end of file diff --git a/packages/kbn-plugin-generator/package.json b/packages/kbn-plugin-generator/package.json index b3b1eff41e4b5..b9df67b32e5d3 100644 --- a/packages/kbn-plugin-generator/package.json +++ b/packages/kbn-plugin-generator/package.json @@ -6,7 +6,7 @@ "dependencies": { "chalk": "^2.4.2", "dedent": "^0.7.0", - "execa": "^4.0.0", + "execa": "^4.0.2", "getopts": "^2.2.4", "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", diff --git a/packages/kbn-plugin-helpers/package.json b/packages/kbn-plugin-helpers/package.json index 040b779a69951..362e8302c3bec 100644 --- a/packages/kbn-plugin-helpers/package.json +++ b/packages/kbn-plugin-helpers/package.json @@ -16,7 +16,7 @@ "argv-split": "^2.0.1", "commander": "^3.0.0", "del": "^5.1.0", - "execa": "^4.0.0", + "execa": "^4.0.2", "globby": "^8.0.1", "gulp-babel": "^8.0.0", "gulp-rename": "1.4.0", diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 21fff4d85ece6..93152ef1b71dc 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -94,7 +94,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _cli__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "run", function() { return _cli__WEBPACK_IMPORTED_MODULE_0__["run"]; }); -/* harmony import */ var _production__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(705); +/* harmony import */ var _production__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(697); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _production__WEBPACK_IMPORTED_MODULE_1__["buildProductionProjects"]; }); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return _production__WEBPACK_IMPORTED_MODULE_1__["prepareExternalProjectDependencies"]; }); @@ -105,10 +105,10 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _utils_project__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(517); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Project", function() { return _utils_project__WEBPACK_IMPORTED_MODULE_3__["Project"]; }); -/* harmony import */ var _utils_workspaces__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(578); +/* harmony import */ var _utils_workspaces__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(573); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "copyWorkspacePackages", function() { return _utils_workspaces__WEBPACK_IMPORTED_MODULE_4__["copyWorkspacePackages"]; }); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(579); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(574); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getProjectPaths", function() { return _config__WEBPACK_IMPORTED_MODULE_5__["getProjectPaths"]; }); /* @@ -143,17 +143,17 @@ __webpack_require__.r(__webpack_exports__); "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "run", function() { return run; }); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var dedent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(14); -/* harmony import */ var dedent__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(dedent__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var getopts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(15); -/* harmony import */ var getopts__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(getopts__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _commands__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(17); +/* harmony import */ var dedent__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); +/* harmony import */ var dedent__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(dedent__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var getopts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); +/* harmony import */ var getopts__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(getopts__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _kbn_dev_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5); +/* harmony import */ var _kbn_dev_utils__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_kbn_dev_utils__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var _commands__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(488); /* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(689); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(34); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(500); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -181,37 +181,43 @@ __webpack_require__.r(__webpack_exports__); function help() { - const availableCommands = Object.keys(_commands__WEBPACK_IMPORTED_MODULE_4__["commands"]).map(commandName => _commands__WEBPACK_IMPORTED_MODULE_4__["commands"][commandName]).map(command => `${command.name} - ${command.description}`); - _utils_log__WEBPACK_IMPORTED_MODULE_6__["log"].write(dedent__WEBPACK_IMPORTED_MODULE_1___default.a` - usage: kbn [] + _utils_log__WEBPACK_IMPORTED_MODULE_6__["log"].info(dedent__WEBPACK_IMPORTED_MODULE_0___default.a` + usage: kbn [] - By default commands are run for Kibana itself, all packages in the 'packages/' - folder and for all plugins in './plugins' and '../kibana-extra'. + By default commands are run for Kibana itself, all packages in the 'packages/' + folder and for all plugins in './plugins' and '../kibana-extra'. - Available commands: + Available commands: - ${availableCommands.join('\n ')} + ${Object.values(_commands__WEBPACK_IMPORTED_MODULE_4__["commands"]).map(command => `${command.name} - ${command.description}`).join('\n ')} - Global options: + Global options: - -e, --exclude Exclude specified project. Can be specified multiple times to exclude multiple projects, e.g. '-e kibana -e @kbn/pm'. - -i, --include Include only specified projects. If left unspecified, it defaults to including all projects. - --oss Do not include the x-pack when running command. - --skip-kibana-plugins Filter all plugins in ./plugins and ../kibana-extra when running command. - --no-cache Disable the bootstrap cache - `); + -e, --exclude Exclude specified project. Can be specified multiple times to exclude multiple projects, e.g. '-e kibana -e @kbn/pm'. + -i, --include Include only specified projects. If left unspecified, it defaults to including all projects. + --oss Do not include the x-pack when running command. + --skip-kibana-plugins Filter all plugins in ./plugins and ../kibana-extra when running command. + --no-cache Disable the bootstrap cache + --verbose Set log level to verbose + --debug Set log level to debug + --quiet Set log level to error + --silent Disable log output + ` + '\n'); } async function run(argv) { - // We can simplify this setup (and remove this extra handling) once Yarn + _utils_log__WEBPACK_IMPORTED_MODULE_6__["log"].setLogLevel(Object(_kbn_dev_utils__WEBPACK_IMPORTED_MODULE_3__["pickLevelFromFlags"])(getopts__WEBPACK_IMPORTED_MODULE_1___default()(argv, { + boolean: ['verbose', 'debug', 'quiet', 'silent'] + }))); // We can simplify this setup (and remove this extra handling) once Yarn // starts forwarding the `--` directly to this script, see // https://github.com/yarnpkg/yarn/blob/b2d3e1a8fe45ef376b716d597cc79b38702a9320/src/cli/index.js#L174-L182 + if (argv.includes('--')) { - _utils_log__WEBPACK_IMPORTED_MODULE_6__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.red(`Using "--" is not allowed, as it doesn't work with 'yarn kbn'.`)); + _utils_log__WEBPACK_IMPORTED_MODULE_6__["log"].error(`Using "--" is not allowed, as it doesn't work with 'yarn kbn'.`); process.exit(1); } - const options = getopts__WEBPACK_IMPORTED_MODULE_2___default()(argv, { + const options = getopts__WEBPACK_IMPORTED_MODULE_1___default()(argv, { alias: { e: 'exclude', h: 'help', @@ -231,7 +237,7 @@ async function run(argv) { // built version of this tool. - const rootPath = Object(path__WEBPACK_IMPORTED_MODULE_3__["resolve"])(__dirname, '../../../'); + const rootPath = Object(path__WEBPACK_IMPORTED_MODULE_2__["resolve"])(__dirname, '../../../'); const commandName = args[0]; const extraArgs = args.slice(1); const commandOptions = { @@ -242,7 +248,7 @@ async function run(argv) { const command = _commands__WEBPACK_IMPORTED_MODULE_4__["commands"][commandName]; if (command === undefined) { - _utils_log__WEBPACK_IMPORTED_MODULE_6__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.red(`[${commandName}] is not a valid command, see 'kbn --help'`)); + _utils_log__WEBPACK_IMPORTED_MODULE_6__["log"].error(`[${commandName}] is not a valid command, see 'kbn --help'`); process.exit(1); } @@ -255,9872 +261,11181 @@ async function run(argv) { "use strict"; -const escapeStringRegexp = __webpack_require__(3); -const ansiStyles = __webpack_require__(4); -const stdoutColor = __webpack_require__(10).stdout; - -const template = __webpack_require__(13); - -const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); - -// `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; - -// `color-convert` models to exclude from the Chalk API due to conflicts and such -const skipModels = new Set(['gray']); -const styles = Object.create(null); +function dedent(strings) { -function applyOptions(obj, options) { - options = options || {}; + var raw = void 0; + if (typeof strings === "string") { + // dedent can be used as a plain function + raw = [strings]; + } else { + raw = strings.raw; + } - // Detect level if not set manually - const scLevel = stdoutColor ? stdoutColor.level : 0; - obj.level = options.level === undefined ? scLevel : options.level; - obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; -} + // first, perform interpolation + var result = ""; + for (var i = 0; i < raw.length; i++) { + result += raw[i]. + // join lines when there is a suppressed newline + replace(/\\\n[ \t]*/g, ""). -function Chalk(options) { - // We check for this.template here since calling `chalk.constructor()` - // by itself will have a `this` of a previously constructed chalk object - if (!this || !(this instanceof Chalk) || this.template) { - const chalk = {}; - applyOptions(chalk, options); + // handle escaped backticks + replace(/\\`/g, "`"); - chalk.template = function () { - const args = [].slice.call(arguments); - return chalkTag.apply(null, [chalk.template].concat(args)); - }; + if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) { + result += arguments.length <= i + 1 ? undefined : arguments[i + 1]; + } + } - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); + // now strip indentation + var lines = result.split("\n"); + var mindent = null; + lines.forEach(function (l) { + var m = l.match(/^(\s+)\S+/); + if (m) { + var indent = m[1].length; + if (!mindent) { + // this is the first indented line + mindent = indent; + } else { + mindent = Math.min(mindent, indent); + } + } + }); - chalk.template.constructor = Chalk; + if (mindent !== null) { + result = lines.map(function (l) { + return l[0] === " " ? l.slice(mindent) : l; + }).join("\n"); + } - return chalk.template; - } + // dedent eats leading and trailing whitespace too + result = result.trim(); - applyOptions(this, options); + // handle escaped newlines at the end to ensure they don't get stripped too + return result.replace(/\\n/g, "\n"); } -// Use bright blue on Windows as the normal blue color is illegible -if (isSimpleWindowsTerm) { - ansiStyles.blue.open = '\u001B[94m'; +if (true) { + module.exports = dedent; } -for (const key of Object.keys(ansiStyles)) { - ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); - - styles[key] = { - get() { - const codes = ansiStyles[key]; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); - } - }; -} -styles.visible = { - get() { - return build.call(this, this._styles || [], true, 'visible'); - } -}; +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { -ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); -for (const model of Object.keys(ansiStyles.color.ansi)) { - if (skipModels.has(model)) { - continue; - } +"use strict"; - styles[model] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.color.close, - closeRe: ansiStyles.color.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} -ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); -for (const model of Object.keys(ansiStyles.bgColor.ansi)) { - if (skipModels.has(model)) { - continue; - } +const EMPTYARR = [] +const SHORTSPLIT = /$|[!-@[-`{-~][\s\S]*/g +const isArray = Array.isArray - const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); - styles[bgModel] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.bgColor.close, - closeRe: ansiStyles.bgColor.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; +const parseValue = function(any) { + if (any === "") return "" + if (any === "false") return false + const maybe = Number(any) + return maybe * 0 === 0 ? maybe : any } -const proto = Object.defineProperties(() => {}, styles); - -function build(_styles, _empty, key) { - const builder = function () { - return applyStyle.apply(builder, arguments); - }; - - builder._styles = _styles; - builder._empty = _empty; - - const self = this; - - Object.defineProperty(builder, 'level', { - enumerable: true, - get() { - return self.level; - }, - set(level) { - self.level = level; - } - }); +const parseAlias = function(aliases) { + let out = {}, + key, + alias, + prev, + len, + any, + i, + k - Object.defineProperty(builder, 'enabled', { - enumerable: true, - get() { - return self.enabled; - }, - set(enabled) { - self.enabled = enabled; - } - }); + for (key in aliases) { + any = aliases[key] + alias = out[key] = isArray(any) ? any : [any] - // See below for fix regarding invisible grey/dim combination on Windows - builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; + for (i = 0, len = alias.length; i < len; i++) { + prev = out[alias[i]] = [key] - // `__proto__` is used because we must return a function, but there is - // no way to create a function with a different prototype - builder.__proto__ = proto; // eslint-disable-line no-proto + for (k = 0; k < len; k++) { + if (i !== k) prev.push(alias[k]) + } + } + } - return builder; + return out } -function applyStyle() { - // Support varags, but simply cast to string in case there's only one arg - const args = arguments; - const argsLen = args.length; - let str = String(arguments[0]); +const parseDefault = function(aliases, defaults) { + let out = {}, + key, + alias, + value, + len, + i - if (argsLen === 0) { - return ''; - } + for (key in defaults) { + value = defaults[key] + alias = aliases[key] - if (argsLen > 1) { - // Don't slice `arguments`, it prevents V8 optimizations - for (let a = 1; a < argsLen; a++) { - str += ' ' + args[a]; - } - } + out[key] = value - if (!this.enabled || this.level <= 0 || !str) { - return this._empty ? '' : str; - } + if (alias === undefined) { + aliases[key] = EMPTYARR + } else { + for (i = 0, len = alias.length; i < len; i++) { + out[alias[i]] = value + } + } + } - // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, - // see https://github.com/chalk/chalk/issues/58 - // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. - const originalDim = ansiStyles.dim.open; - if (isSimpleWindowsTerm && this.hasGrey) { - ansiStyles.dim.open = ''; - } + return out +} - for (const code of this._styles.slice().reverse()) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - str = code.open + str.replace(code.closeRe, code.open) + code.close; +const parseOptions = function(aliases, options, value) { + let out = {}, + key, + alias, + len, + end, + i, + k - // Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS - // https://github.com/chalk/chalk/pull/92 - str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); - } + if (options !== undefined) { + for (i = 0, len = options.length; i < len; i++) { + key = options[i] + alias = aliases[key] - // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue - ansiStyles.dim.open = originalDim; + out[key] = value - return str; + if (alias === undefined) { + aliases[key] = EMPTYARR + } else { + for (k = 0, end = alias.length; k < end; k++) { + out[alias[k]] = value + } + } + } + } + + return out } -function chalkTag(chalk, strings) { - if (!Array.isArray(strings)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return [].slice.call(arguments, 1).join(' '); - } +const write = function(out, key, value, aliases, unknown) { + let i, + prev, + alias = aliases[key], + len = alias === undefined ? -1 : alias.length - const args = [].slice.call(arguments, 2); - const parts = [strings.raw[0]]; + if (len >= 0 || unknown === undefined || unknown(key)) { + prev = out[key] - for (let i = 1; i < strings.length; i++) { - parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); - parts.push(String(strings.raw[i])); - } + if (prev === undefined) { + out[key] = value + } else { + if (isArray(prev)) { + prev.push(value) + } else { + out[key] = [prev, value] + } + } - return template(chalk, parts.join('')); + for (i = 0; i < len; i++) { + out[alias[i]] = out[key] + } + } } -Object.defineProperties(Chalk.prototype, styles); +const getopts = function(argv, opts) { + let unknown = (opts = opts || {}).unknown, + aliases = parseAlias(opts.alias), + strings = parseOptions(aliases, opts.string, ""), + values = parseDefault(aliases, opts.default), + bools = parseOptions(aliases, opts.boolean, false), + stopEarly = opts.stopEarly, + _ = [], + out = { _ }, + i = 0, + k = 0, + len = argv.length, + key, + arg, + end, + match, + value -module.exports = Chalk(); // eslint-disable-line new-cap -module.exports.supportsColor = stdoutColor; -module.exports.default = module.exports; // For TypeScript + for (; i < len; i++) { + arg = argv[i] + if (arg[0] !== "-" || arg === "-") { + if (stopEarly) while (i < len) _.push(argv[i++]) + else _.push(arg) + } else if (arg === "--") { + while (++i < len) _.push(argv[i]) + } else if (arg[1] === "-") { + end = arg.indexOf("=", 2) + if (arg[2] === "n" && arg[3] === "o" && arg[4] === "-") { + key = arg.slice(5, end >= 0 ? end : undefined) + value = false + } else if (end >= 0) { + key = arg.slice(2, end) + value = + bools[key] !== undefined || + (strings[key] === undefined + ? parseValue(arg.slice(end + 1)) + : arg.slice(end + 1)) + } else { + key = arg.slice(2) + value = + bools[key] !== undefined || + (len === i + 1 || argv[i + 1][0] === "-" + ? strings[key] === undefined + ? true + : "" + : strings[key] === undefined + ? parseValue(argv[++i]) + : argv[++i]) + } + write(out, key, value, aliases, unknown) + } else { + SHORTSPLIT.lastIndex = 2 + match = SHORTSPLIT.exec(arg) + end = match.index + value = match[0] -/***/ }), -/* 3 */ -/***/ (function(module, exports, __webpack_require__) { + for (k = 1; k < end; k++) { + write( + out, + (key = arg[k]), + k + 1 < end + ? strings[key] === undefined || + arg.substring(k + 1, (k = end)) + value + : value === "" + ? len === i + 1 || argv[i + 1][0] === "-" + ? strings[key] === undefined || "" + : bools[key] !== undefined || + (strings[key] === undefined ? parseValue(argv[++i]) : argv[++i]) + : bools[key] !== undefined || + (strings[key] === undefined ? parseValue(value) : value), + aliases, + unknown + ) + } + } + } -"use strict"; + for (key in values) if (out[key] === undefined) out[key] = values[key] + for (key in bools) if (out[key] === undefined) out[key] = false + for (key in strings) if (out[key] === undefined) out[key] = "" + return out +} -var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; +module.exports = getopts -module.exports = function (str) { - if (typeof str !== 'string') { - throw new TypeError('Expected a string'); - } - return str.replace(matchOperatorsRe, '\\$&'); -}; +/***/ }), +/* 4 */ +/***/ (function(module, exports) { +module.exports = require("path"); /***/ }), -/* 4 */ +/* 5 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(6); - -const wrapAnsi16 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${code + offset}m`; -}; -const wrapAnsi256 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};5;${code}m`; -}; +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(6); +var proc_runner_1 = __webpack_require__(7); +exports.withProcRunner = proc_runner_1.withProcRunner; +exports.ProcRunner = proc_runner_1.ProcRunner; +tslib_1.__exportStar(__webpack_require__(400), exports); +var serializers_1 = __webpack_require__(405); +exports.createAbsolutePathSerializer = serializers_1.createAbsolutePathSerializer; +var certs_1 = __webpack_require__(430); +exports.CA_CERT_PATH = certs_1.CA_CERT_PATH; +exports.ES_KEY_PATH = certs_1.ES_KEY_PATH; +exports.ES_CERT_PATH = certs_1.ES_CERT_PATH; +exports.ES_P12_PATH = certs_1.ES_P12_PATH; +exports.ES_P12_PASSWORD = certs_1.ES_P12_PASSWORD; +exports.ES_EMPTYPASSWORD_P12_PATH = certs_1.ES_EMPTYPASSWORD_P12_PATH; +exports.ES_NOPASSWORD_P12_PATH = certs_1.ES_NOPASSWORD_P12_PATH; +exports.KBN_KEY_PATH = certs_1.KBN_KEY_PATH; +exports.KBN_CERT_PATH = certs_1.KBN_CERT_PATH; +exports.KBN_P12_PATH = certs_1.KBN_P12_PATH; +exports.KBN_P12_PASSWORD = certs_1.KBN_P12_PASSWORD; +var run_1 = __webpack_require__(431); +exports.run = run_1.run; +exports.createFailError = run_1.createFailError; +exports.createFlagError = run_1.createFlagError; +exports.combineErrors = run_1.combineErrors; +exports.isFailError = run_1.isFailError; +var repo_root_1 = __webpack_require__(407); +exports.REPO_ROOT = repo_root_1.REPO_ROOT; +var kbn_client_1 = __webpack_require__(436); +exports.KbnClient = kbn_client_1.KbnClient; +tslib_1.__exportStar(__webpack_require__(479), exports); +tslib_1.__exportStar(__webpack_require__(486), exports); -const wrapAnsi16m = (fn, offset) => function () { - const rgb = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; -}; -function assembleStyles() { - const codes = new Map(); - const styles = { - modifier: { - reset: [0, 0], - // 21 isn't widely supported and 22 does the same thing - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - gray: [90, 39], +/***/ }), +/* 6 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - // Bright color - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39] - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], - - // Bright color - bgBlackBright: [100, 49], - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49] - } - }; - - // Fix humans - styles.color.grey = styles.color.gray; - - for (const groupName of Object.keys(styles)) { - const group = styles[groupName]; - - for (const styleName of Object.keys(group)) { - const style = group[styleName]; - - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m` - }; - - group[styleName] = styles[styleName]; - - codes.set(style[0], style[1]); - } - - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); - - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); - } - - const ansi2ansi = n => n; - const rgb2rgb = (r, g, b) => [r, g, b]; - - styles.color.close = '\u001B[39m'; - styles.bgColor.close = '\u001B[49m'; - - styles.color.ansi = { - ansi: wrapAnsi16(ansi2ansi, 0) - }; - styles.color.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 0) - }; - styles.color.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 0) - }; - - styles.bgColor.ansi = { - ansi: wrapAnsi16(ansi2ansi, 10) - }; - styles.bgColor.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 10) - }; - styles.bgColor.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 10) - }; - - for (let key of Object.keys(colorConvert)) { - if (typeof colorConvert[key] !== 'object') { - continue; - } - - const suite = colorConvert[key]; - - if (key === 'ansi16') { - key = 'ansi'; - } - - if ('ansi16' in suite) { - styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); - styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); - } - - if ('ansi256' in suite) { - styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); - styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); - } - - if ('rgb' in suite) { - styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); - styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); - } - } - - return styles; -} - -// Make the export immutable -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); - -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(5)(module))) - -/***/ }), -/* 5 */ -/***/ (function(module, exports) { - -module.exports = function(module) { - if (!module.webpackPolyfill) { - module.deprecate = function() {}; - module.paths = []; - // module.parent = undefined by default - if (!module.children) module.children = []; - Object.defineProperty(module, "loaded", { - enumerable: true, - get: function() { - return module.l; - } - }); - Object.defineProperty(module, "id", { - enumerable: true, - get: function() { - return module.i; - } - }); - module.webpackPolyfill = 1; - } - return module; -}; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__extends", function() { return __extends; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__assign", function() { return __assign; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__rest", function() { return __rest; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__decorate", function() { return __decorate; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__param", function() { return __param; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__metadata", function() { return __metadata; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__awaiter", function() { return __awaiter; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__generator", function() { return __generator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__exportStar", function() { return __exportStar; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__values", function() { return __values; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__read", function() { return __read; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__spread", function() { return __spread; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__await", function() { return __await; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncGenerator", function() { return __asyncGenerator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncDelegator", function() { return __asyncDelegator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncValues", function() { return __asyncValues; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__makeTemplateObject", function() { return __makeTemplateObject; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importStar", function() { return __importStar; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importDefault", function() { return __importDefault; }); +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at http://www.apache.org/licenses/LICENSE-2.0 + +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABLITY OR NON-INFRINGEMENT. + +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */ +/* global Reflect, Promise */ + +var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); +}; + +function __extends(d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} + +var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + } + return __assign.apply(this, arguments); +} + +function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +} + +function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +} + +function __param(paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } +} + +function __metadata(metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); +} + +function __awaiter(thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +} + +function __exportStar(m, exports) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} + +function __values(o) { + var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; + if (m) return m.call(o); + return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; +} + +function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; +} + +function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; +} + +function __await(v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); +} + +function __asyncGenerator(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; + function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } +} + +function __asyncDelegator(o) { + var i, p; + return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; + function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } +} + +function __asyncValues(o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } +} + +function __makeTemplateObject(cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; +}; + +function __importStar(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result.default = mod; + return result; +} + +function __importDefault(mod) { + return (mod && mod.__esModule) ? mod : { default: mod }; +} /***/ }), -/* 6 */ +/* 7 */ /***/ (function(module, exports, __webpack_require__) { -var conversions = __webpack_require__(7); -var route = __webpack_require__(9); - -var convert = {}; - -var models = Object.keys(conversions); - -function wrapRaw(fn) { - var wrappedFn = function (args) { - if (args === undefined || args === null) { - return args; - } - - if (arguments.length > 1) { - args = Array.prototype.slice.call(arguments); - } - - return fn(args); - }; - - // preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } - - return wrappedFn; -} - -function wrapRounded(fn) { - var wrappedFn = function (args) { - if (args === undefined || args === null) { - return args; - } - - if (arguments.length > 1) { - args = Array.prototype.slice.call(arguments); - } +"use strict"; - var result = fn(args); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +var with_proc_runner_1 = __webpack_require__(8); +exports.withProcRunner = with_proc_runner_1.withProcRunner; +var proc_runner_1 = __webpack_require__(9); +exports.ProcRunner = proc_runner_1.ProcRunner; - // we're assuming the result is an array here. - // see notice in conversions.js; don't use box types - // in conversion functions. - if (typeof result === 'object') { - for (var len = result.length, i = 0; i < len; i++) { - result[i] = Math.round(result[i]); - } - } - return result; - }; +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { - // preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } +"use strict"; - return wrappedFn; +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const proc_runner_1 = __webpack_require__(9); +/** + * Create a ProcRunner and pass it to an async function. When + * the async function finishes the ProcRunner is torn-down + * automatically + * + * @param {ToolingLog} log + * @param {async Function} fn + * @return {Promise} + */ +async function withProcRunner(log, fn) { + const procs = new proc_runner_1.ProcRunner(log); + try { + await fn(procs); + } + finally { + await procs.teardown(); + } } - -models.forEach(function (fromModel) { - convert[fromModel] = {}; - - Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); - Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); - - var routes = route(fromModel); - var routeModels = Object.keys(routes); - - routeModels.forEach(function (toModel) { - var fn = routes[toModel]; - - convert[fromModel][toModel] = wrapRounded(fn); - convert[fromModel][toModel].raw = wrapRaw(fn); - }); -}); - -module.exports = convert; +exports.withProcRunner = withProcRunner; /***/ }), -/* 7 */ +/* 9 */ /***/ (function(module, exports, __webpack_require__) { -/* MIT license */ -var cssKeywords = __webpack_require__(8); - -// NOTE: conversions should only return primitive values (i.e. arrays, or -// values that give correct `typeof` results). -// do not use box values types (i.e. Number(), String(), etc.) - -var reverseKeywords = {}; -for (var key in cssKeywords) { - if (cssKeywords.hasOwnProperty(key)) { - reverseKeywords[cssKeywords[key]] = key; - } -} +"use strict"; -var convert = module.exports = { - rgb: {channels: 3, labels: 'rgb'}, - hsl: {channels: 3, labels: 'hsl'}, - hsv: {channels: 3, labels: 'hsv'}, - hwb: {channels: 3, labels: 'hwb'}, - cmyk: {channels: 4, labels: 'cmyk'}, - xyz: {channels: 3, labels: 'xyz'}, - lab: {channels: 3, labels: 'lab'}, - lch: {channels: 3, labels: 'lch'}, - hex: {channels: 1, labels: ['hex']}, - keyword: {channels: 1, labels: ['keyword']}, - ansi16: {channels: 1, labels: ['ansi16']}, - ansi256: {channels: 1, labels: ['ansi256']}, - hcg: {channels: 3, labels: ['h', 'c', 'g']}, - apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, - gray: {channels: 1, labels: ['gray']} -}; - -// hide .channels and .labels properties -for (var model in convert) { - if (convert.hasOwnProperty(model)) { - if (!('channels' in convert[model])) { - throw new Error('missing channels property: ' + model); - } - - if (!('labels' in convert[model])) { - throw new Error('missing channel labels property: ' + model); - } - - if (convert[model].labels.length !== convert[model].channels) { - throw new Error('channel and label counts mismatch: ' + model); - } - - var channels = convert[model].channels; - var labels = convert[model].labels; - delete convert[model].channels; - delete convert[model].labels; - Object.defineProperty(convert[model], 'channels', {value: channels}); - Object.defineProperty(convert[model], 'labels', {value: labels}); - } +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(6); +const moment_1 = tslib_1.__importDefault(__webpack_require__(10)); +const Rx = tslib_1.__importStar(__webpack_require__(140)); +const operators_1 = __webpack_require__(241); +const exit_hook_1 = tslib_1.__importDefault(__webpack_require__(339)); +const errors_1 = __webpack_require__(340); +const proc_1 = __webpack_require__(341); +const SECOND = 1000; +const MINUTE = 60 * SECOND; +const noop = () => { }; +/** + * Helper for starting and managing processes. In many ways it resembles the + * API from `grunt_run`, processes are named and can be started, waited for, + * backgrounded once they log something matching a RegExp... + * + * @class ProcRunner + */ +class ProcRunner { + constructor(log) { + this.log = log; + this.closing = false; + this.procs = []; + this.signalUnsubscribe = exit_hook_1.default(() => { + this.teardown().catch((error) => { + log.error(`ProcRunner teardown error: ${error.stack}`); + }); + }); + } + /** + * Start a process, tracking it by `name` + * @param {String} name + * @param {Object} options + * @property {String} options.cmd executable to run + * @property {Array?} options.args arguments to provide the executable + * @property {String?} options.cwd current working directory for the process + * @property {RegExp|Boolean} options.wait Should start() wait for some time? Use + * `true` will wait until the proc exits, + * a `RegExp` will wait until that log line + * is found + * @return {Promise} + */ + async run(name, options) { + const { cmd, args = [], cwd = process.cwd(), stdin = undefined, wait = false, waitTimeout = 15 * MINUTE, env = process.env, } = options; + if (this.closing) { + throw new Error('ProcRunner is closing'); + } + if (wait && !(wait instanceof RegExp) && wait !== true) { + throw new TypeError('wait param should either be a RegExp or `true`'); + } + if (!!this.getProc(name)) { + throw new Error(`Process with name "${name}" already running`); + } + const proc = this.startProc(name, { + cmd, + args, + cwd, + env, + stdin, + }); + try { + if (wait instanceof RegExp) { + // wait for process to log matching line + await Rx.race(proc.lines$.pipe(operators_1.filter((line) => wait.test(line)), operators_1.first(), operators_1.catchError((err) => { + if (err.name !== 'EmptyError') { + throw errors_1.createCliError(`[${name}] exited without matching pattern: ${wait}`); + } + else { + throw err; + } + })), waitTimeout === false + ? Rx.NEVER + : Rx.timer(waitTimeout).pipe(operators_1.map(() => { + const sec = waitTimeout / SECOND; + throw errors_1.createCliError(`[${name}] failed to match pattern within ${sec} seconds [pattern=${wait}]`); + }))).toPromise(); + } + if (wait === true) { + // wait for process to complete + await proc.outcomePromise; + } + } + finally { + // while the procRunner closes promises will resolve/reject because + // processes and stopping, but consumers of run() shouldn't have to + // prepare for that, so just return a never-resolving promise + if (this.closing) { + await new Promise(noop); + } + } + } + /** + * Stop a named proc + */ + async stop(name, signal = 'SIGTERM') { + const proc = this.getProc(name); + if (proc) { + await proc.stop(signal); + } + else { + this.log.warning('[%s] already stopped', name); + } + } + /** + * Wait for all running processes to stop naturally + * @return {Promise} + */ + async waitForAllToStop() { + await Promise.all(this.procs.map((proc) => proc.outcomePromise)); + } + /** + * Close the ProcRunner and stop all running + * processes with `signal` + * + * @param {String} [signal=undefined] + * @return {Promise} + */ + async teardown(signal = 'exit') { + if (this.closing) { + return; + } + this.closing = true; + this.signalUnsubscribe(); + if (!signal && this.procs.length > 0) { + this.log.warning('%d processes left running, stop them with procs.stop(name):', this.procs.length, this.procs.map((proc) => proc.name)); + } + await Promise.all(this.procs.map(async (proc) => { + await proc.stop(signal === 'exit' ? 'SIGKILL' : signal); + })); + } + getProc(name) { + return this.procs.find((proc) => { + return proc.name === name; + }); + } + startProc(name, options) { + const startMs = Date.now(); + const proc = proc_1.startProc(name, options, this.log); + this.procs.push(proc); + const remove = () => { + this.procs.splice(this.procs.indexOf(proc), 1); + }; + // tie into proc outcome$, remove from _procs on compete + proc.outcome$.subscribe({ + next: (code) => { + const duration = moment_1.default.duration(Date.now() - startMs); + this.log.info('[%s] exited with %s after %s', name, code, duration.humanize()); + }, + complete: () => { + remove(); + }, + error: (error) => { + if (this.closing) { + this.log.error(error); + } + remove(); + }, + }); + return proc; + } } +exports.ProcRunner = ProcRunner; -convert.rgb.hsl = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var min = Math.min(r, g, b); - var max = Math.max(r, g, b); - var delta = max - min; - var h; - var s; - var l; - - if (max === min) { - h = 0; - } else if (r === max) { - h = (g - b) / delta; - } else if (g === max) { - h = 2 + (b - r) / delta; - } else if (b === max) { - h = 4 + (r - g) / delta; - } - - h = Math.min(h * 60, 360); - - if (h < 0) { - h += 360; - } - l = (min + max) / 2; +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { - if (max === min) { - s = 0; - } else if (l <= 0.5) { - s = delta / (max + min); - } else { - s = delta / (2 - max - min); - } +/* WEBPACK VAR INJECTION */(function(module) {var require;//! moment.js - return [h, s * 100, l * 100]; -}; +;(function (global, factory) { + true ? module.exports = factory() : + undefined +}(this, (function () { 'use strict'; -convert.rgb.hsv = function (rgb) { - var r = rgb[0]; - var g = rgb[1]; - var b = rgb[2]; - var min = Math.min(r, g, b); - var max = Math.max(r, g, b); - var delta = max - min; - var h; - var s; - var v; + var hookCallback; - if (max === 0) { - s = 0; - } else { - s = (delta / max * 1000) / 10; - } + function hooks () { + return hookCallback.apply(null, arguments); + } - if (max === min) { - h = 0; - } else if (r === max) { - h = (g - b) / delta; - } else if (g === max) { - h = 2 + (b - r) / delta; - } else if (b === max) { - h = 4 + (r - g) / delta; - } + // This is done to register the method called with moment() + // without creating circular dependencies. + function setHookCallback (callback) { + hookCallback = callback; + } - h = Math.min(h * 60, 360); + function isArray(input) { + return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; + } - if (h < 0) { - h += 360; - } + function isObject(input) { + // IE8 will treat undefined and null as object if it wasn't for + // input != null + return input != null && Object.prototype.toString.call(input) === '[object Object]'; + } - v = ((max / 255) * 1000) / 10; + function isObjectEmpty(obj) { + if (Object.getOwnPropertyNames) { + return (Object.getOwnPropertyNames(obj).length === 0); + } else { + var k; + for (k in obj) { + if (obj.hasOwnProperty(k)) { + return false; + } + } + return true; + } + } - return [h, s, v]; -}; + function isUndefined(input) { + return input === void 0; + } -convert.rgb.hwb = function (rgb) { - var r = rgb[0]; - var g = rgb[1]; - var b = rgb[2]; - var h = convert.rgb.hsl(rgb)[0]; - var w = 1 / 255 * Math.min(r, Math.min(g, b)); + function isNumber(input) { + return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; + } - b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); + function isDate(input) { + return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; + } - return [h, w * 100, b * 100]; -}; + function map(arr, fn) { + var res = [], i; + for (i = 0; i < arr.length; ++i) { + res.push(fn(arr[i], i)); + } + return res; + } -convert.rgb.cmyk = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var c; - var m; - var y; - var k; + function hasOwnProp(a, b) { + return Object.prototype.hasOwnProperty.call(a, b); + } - k = Math.min(1 - r, 1 - g, 1 - b); - c = (1 - r - k) / (1 - k) || 0; - m = (1 - g - k) / (1 - k) || 0; - y = (1 - b - k) / (1 - k) || 0; + function extend(a, b) { + for (var i in b) { + if (hasOwnProp(b, i)) { + a[i] = b[i]; + } + } - return [c * 100, m * 100, y * 100, k * 100]; -}; + if (hasOwnProp(b, 'toString')) { + a.toString = b.toString; + } -/** - * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance - * */ -function comparativeDistance(x, y) { - return ( - Math.pow(x[0] - y[0], 2) + - Math.pow(x[1] - y[1], 2) + - Math.pow(x[2] - y[2], 2) - ); -} + if (hasOwnProp(b, 'valueOf')) { + a.valueOf = b.valueOf; + } -convert.rgb.keyword = function (rgb) { - var reversed = reverseKeywords[rgb]; - if (reversed) { - return reversed; - } + return a; + } - var currentClosestDistance = Infinity; - var currentClosestKeyword; + function createUTC (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, true).utc(); + } - for (var keyword in cssKeywords) { - if (cssKeywords.hasOwnProperty(keyword)) { - var value = cssKeywords[keyword]; + function defaultParsingFlags() { + // We need to deep clone this object. + return { + empty : false, + unusedTokens : [], + unusedInput : [], + overflow : -2, + charsLeftOver : 0, + nullInput : false, + invalidMonth : null, + invalidFormat : false, + userInvalidated : false, + iso : false, + parsedDateParts : [], + meridiem : null, + rfc2822 : false, + weekdayMismatch : false + }; + } - // Compute comparative distance - var distance = comparativeDistance(rgb, value); + function getParsingFlags(m) { + if (m._pf == null) { + m._pf = defaultParsingFlags(); + } + return m._pf; + } - // Check if its less, if so set as closest - if (distance < currentClosestDistance) { - currentClosestDistance = distance; - currentClosestKeyword = keyword; - } - } - } + var some; + if (Array.prototype.some) { + some = Array.prototype.some; + } else { + some = function (fun) { + var t = Object(this); + var len = t.length >>> 0; - return currentClosestKeyword; -}; + for (var i = 0; i < len; i++) { + if (i in t && fun.call(this, t[i], i, t)) { + return true; + } + } -convert.keyword.rgb = function (keyword) { - return cssKeywords[keyword]; -}; + return false; + }; + } -convert.rgb.xyz = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; + function isValid(m) { + if (m._isValid == null) { + var flags = getParsingFlags(m); + var parsedParts = some.call(flags.parsedDateParts, function (i) { + return i != null; + }); + var isNowValid = !isNaN(m._d.getTime()) && + flags.overflow < 0 && + !flags.empty && + !flags.invalidMonth && + !flags.invalidWeekday && + !flags.weekdayMismatch && + !flags.nullInput && + !flags.invalidFormat && + !flags.userInvalidated && + (!flags.meridiem || (flags.meridiem && parsedParts)); - // assume sRGB - r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); - g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); - b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); + if (m._strict) { + isNowValid = isNowValid && + flags.charsLeftOver === 0 && + flags.unusedTokens.length === 0 && + flags.bigHour === undefined; + } - var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); - var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); - var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); + if (Object.isFrozen == null || !Object.isFrozen(m)) { + m._isValid = isNowValid; + } + else { + return isNowValid; + } + } + return m._isValid; + } - return [x * 100, y * 100, z * 100]; -}; + function createInvalid (flags) { + var m = createUTC(NaN); + if (flags != null) { + extend(getParsingFlags(m), flags); + } + else { + getParsingFlags(m).userInvalidated = true; + } -convert.rgb.lab = function (rgb) { - var xyz = convert.rgb.xyz(rgb); - var x = xyz[0]; - var y = xyz[1]; - var z = xyz[2]; - var l; - var a; - var b; + return m; + } - x /= 95.047; - y /= 100; - z /= 108.883; + // Plugins that add properties should also add the key here (null value), + // so we can properly clone ourselves. + var momentProperties = hooks.momentProperties = []; - x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); + function copyConfig(to, from) { + var i, prop, val; - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - - return [l, a, b]; -}; + if (!isUndefined(from._isAMomentObject)) { + to._isAMomentObject = from._isAMomentObject; + } + if (!isUndefined(from._i)) { + to._i = from._i; + } + if (!isUndefined(from._f)) { + to._f = from._f; + } + if (!isUndefined(from._l)) { + to._l = from._l; + } + if (!isUndefined(from._strict)) { + to._strict = from._strict; + } + if (!isUndefined(from._tzm)) { + to._tzm = from._tzm; + } + if (!isUndefined(from._isUTC)) { + to._isUTC = from._isUTC; + } + if (!isUndefined(from._offset)) { + to._offset = from._offset; + } + if (!isUndefined(from._pf)) { + to._pf = getParsingFlags(from); + } + if (!isUndefined(from._locale)) { + to._locale = from._locale; + } -convert.hsl.rgb = function (hsl) { - var h = hsl[0] / 360; - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var t1; - var t2; - var t3; - var rgb; - var val; + if (momentProperties.length > 0) { + for (i = 0; i < momentProperties.length; i++) { + prop = momentProperties[i]; + val = from[prop]; + if (!isUndefined(val)) { + to[prop] = val; + } + } + } - if (s === 0) { - val = l * 255; - return [val, val, val]; - } + return to; + } - if (l < 0.5) { - t2 = l * (1 + s); - } else { - t2 = l + s - l * s; - } + var updateInProgress = false; - t1 = 2 * l - t2; + // Moment prototype object + function Moment(config) { + copyConfig(this, config); + this._d = new Date(config._d != null ? config._d.getTime() : NaN); + if (!this.isValid()) { + this._d = new Date(NaN); + } + // Prevent infinite loop in case updateOffset creates new moment + // objects. + if (updateInProgress === false) { + updateInProgress = true; + hooks.updateOffset(this); + updateInProgress = false; + } + } - rgb = [0, 0, 0]; - for (var i = 0; i < 3; i++) { - t3 = h + 1 / 3 * -(i - 1); - if (t3 < 0) { - t3++; - } - if (t3 > 1) { - t3--; - } + function isMoment (obj) { + return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); + } - if (6 * t3 < 1) { - val = t1 + (t2 - t1) * 6 * t3; - } else if (2 * t3 < 1) { - val = t2; - } else if (3 * t3 < 2) { - val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; - } else { - val = t1; - } + function absFloor (number) { + if (number < 0) { + // -0 -> 0 + return Math.ceil(number) || 0; + } else { + return Math.floor(number); + } + } - rgb[i] = val * 255; - } + function toInt(argumentForCoercion) { + var coercedNumber = +argumentForCoercion, + value = 0; - return rgb; -}; + if (coercedNumber !== 0 && isFinite(coercedNumber)) { + value = absFloor(coercedNumber); + } -convert.hsl.hsv = function (hsl) { - var h = hsl[0]; - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var smin = s; - var lmin = Math.max(l, 0.01); - var sv; - var v; + return value; + } - l *= 2; - s *= (l <= 1) ? l : 2 - l; - smin *= lmin <= 1 ? lmin : 2 - lmin; - v = (l + s) / 2; - sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); + // compare two arrays, return the number of differences + function compareArrays(array1, array2, dontConvert) { + var len = Math.min(array1.length, array2.length), + lengthDiff = Math.abs(array1.length - array2.length), + diffs = 0, + i; + for (i = 0; i < len; i++) { + if ((dontConvert && array1[i] !== array2[i]) || + (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { + diffs++; + } + } + return diffs + lengthDiff; + } - return [h, sv * 100, v * 100]; -}; + function warn(msg) { + if (hooks.suppressDeprecationWarnings === false && + (typeof console !== 'undefined') && console.warn) { + console.warn('Deprecation warning: ' + msg); + } + } -convert.hsv.rgb = function (hsv) { - var h = hsv[0] / 60; - var s = hsv[1] / 100; - var v = hsv[2] / 100; - var hi = Math.floor(h) % 6; + function deprecate(msg, fn) { + var firstTime = true; - var f = h - Math.floor(h); - var p = 255 * v * (1 - s); - var q = 255 * v * (1 - (s * f)); - var t = 255 * v * (1 - (s * (1 - f))); - v *= 255; + return extend(function () { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(null, msg); + } + if (firstTime) { + var args = []; + var arg; + for (var i = 0; i < arguments.length; i++) { + arg = ''; + if (typeof arguments[i] === 'object') { + arg += '\n[' + i + '] '; + for (var key in arguments[0]) { + arg += key + ': ' + arguments[0][key] + ', '; + } + arg = arg.slice(0, -2); // Remove trailing comma and space + } else { + arg = arguments[i]; + } + args.push(arg); + } + warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); + firstTime = false; + } + return fn.apply(this, arguments); + }, fn); + } - switch (hi) { - case 0: - return [v, t, p]; - case 1: - return [q, v, p]; - case 2: - return [p, v, t]; - case 3: - return [p, q, v]; - case 4: - return [t, p, v]; - case 5: - return [v, p, q]; - } -}; + var deprecations = {}; -convert.hsv.hsl = function (hsv) { - var h = hsv[0]; - var s = hsv[1] / 100; - var v = hsv[2] / 100; - var vmin = Math.max(v, 0.01); - var lmin; - var sl; - var l; + function deprecateSimple(name, msg) { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(name, msg); + } + if (!deprecations[name]) { + warn(msg); + deprecations[name] = true; + } + } - l = (2 - s) * v; - lmin = (2 - s) * vmin; - sl = s * vmin; - sl /= (lmin <= 1) ? lmin : 2 - lmin; - sl = sl || 0; - l /= 2; + hooks.suppressDeprecationWarnings = false; + hooks.deprecationHandler = null; - return [h, sl * 100, l * 100]; -}; + function isFunction(input) { + return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; + } -// http://dev.w3.org/csswg/css-color/#hwb-to-rgb -convert.hwb.rgb = function (hwb) { - var h = hwb[0] / 360; - var wh = hwb[1] / 100; - var bl = hwb[2] / 100; - var ratio = wh + bl; - var i; - var v; - var f; - var n; + function set (config) { + var prop, i; + for (i in config) { + prop = config[i]; + if (isFunction(prop)) { + this[i] = prop; + } else { + this['_' + i] = prop; + } + } + this._config = config; + // Lenient ordinal parsing accepts just a number in addition to + // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. + // TODO: Remove "ordinalParse" fallback in next major release. + this._dayOfMonthOrdinalParseLenient = new RegExp( + (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + + '|' + (/\d{1,2}/).source); + } - // wh + bl cant be > 1 - if (ratio > 1) { - wh /= ratio; - bl /= ratio; - } + function mergeConfigs(parentConfig, childConfig) { + var res = extend({}, parentConfig), prop; + for (prop in childConfig) { + if (hasOwnProp(childConfig, prop)) { + if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { + res[prop] = {}; + extend(res[prop], parentConfig[prop]); + extend(res[prop], childConfig[prop]); + } else if (childConfig[prop] != null) { + res[prop] = childConfig[prop]; + } else { + delete res[prop]; + } + } + } + for (prop in parentConfig) { + if (hasOwnProp(parentConfig, prop) && + !hasOwnProp(childConfig, prop) && + isObject(parentConfig[prop])) { + // make sure changes to properties don't modify parent config + res[prop] = extend({}, res[prop]); + } + } + return res; + } - i = Math.floor(6 * h); - v = 1 - bl; - f = 6 * h - i; + function Locale(config) { + if (config != null) { + this.set(config); + } + } - if ((i & 0x01) !== 0) { - f = 1 - f; - } + var keys; - n = wh + f * (v - wh); // linear interpolation + if (Object.keys) { + keys = Object.keys; + } else { + keys = function (obj) { + var i, res = []; + for (i in obj) { + if (hasOwnProp(obj, i)) { + res.push(i); + } + } + return res; + }; + } - var r; - var g; - var b; - switch (i) { - default: - case 6: - case 0: r = v; g = n; b = wh; break; - case 1: r = n; g = v; b = wh; break; - case 2: r = wh; g = v; b = n; break; - case 3: r = wh; g = n; b = v; break; - case 4: r = n; g = wh; b = v; break; - case 5: r = v; g = wh; b = n; break; - } + var defaultCalendar = { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }; - return [r * 255, g * 255, b * 255]; -}; + function calendar (key, mom, now) { + var output = this._calendar[key] || this._calendar['sameElse']; + return isFunction(output) ? output.call(mom, now) : output; + } -convert.cmyk.rgb = function (cmyk) { - var c = cmyk[0] / 100; - var m = cmyk[1] / 100; - var y = cmyk[2] / 100; - var k = cmyk[3] / 100; - var r; - var g; - var b; + var defaultLongDateFormat = { + LTS : 'h:mm:ss A', + LT : 'h:mm A', + L : 'MM/DD/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY h:mm A', + LLLL : 'dddd, MMMM D, YYYY h:mm A' + }; - r = 1 - Math.min(1, c * (1 - k) + k); - g = 1 - Math.min(1, m * (1 - k) + k); - b = 1 - Math.min(1, y * (1 - k) + k); + function longDateFormat (key) { + var format = this._longDateFormat[key], + formatUpper = this._longDateFormat[key.toUpperCase()]; - return [r * 255, g * 255, b * 255]; -}; + if (format || !formatUpper) { + return format; + } -convert.xyz.rgb = function (xyz) { - var x = xyz[0] / 100; - var y = xyz[1] / 100; - var z = xyz[2] / 100; - var r; - var g; - var b; + this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { + return val.slice(1); + }); - r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); - g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); - b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); + return this._longDateFormat[key]; + } - // assume sRGB - r = r > 0.0031308 - ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) - : r * 12.92; + var defaultInvalidDate = 'Invalid date'; - g = g > 0.0031308 - ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) - : g * 12.92; + function invalidDate () { + return this._invalidDate; + } - b = b > 0.0031308 - ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) - : b * 12.92; + var defaultOrdinal = '%d'; + var defaultDayOfMonthOrdinalParse = /\d{1,2}/; - r = Math.min(Math.max(0, r), 1); - g = Math.min(Math.max(0, g), 1); - b = Math.min(Math.max(0, b), 1); + function ordinal (number) { + return this._ordinal.replace('%d', number); + } - return [r * 255, g * 255, b * 255]; -}; + var defaultRelativeTime = { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }; -convert.xyz.lab = function (xyz) { - var x = xyz[0]; - var y = xyz[1]; - var z = xyz[2]; - var l; - var a; - var b; + function relativeTime (number, withoutSuffix, string, isFuture) { + var output = this._relativeTime[string]; + return (isFunction(output)) ? + output(number, withoutSuffix, string, isFuture) : + output.replace(/%d/i, number); + } - x /= 95.047; - y /= 100; - z /= 108.883; + function pastFuture (diff, output) { + var format = this._relativeTime[diff > 0 ? 'future' : 'past']; + return isFunction(format) ? format(output) : format.replace(/%s/i, output); + } - x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); + var aliases = {}; - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); + function addUnitAlias (unit, shorthand) { + var lowerCase = unit.toLowerCase(); + aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; + } - return [l, a, b]; -}; + function normalizeUnits(units) { + return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; + } -convert.lab.xyz = function (lab) { - var l = lab[0]; - var a = lab[1]; - var b = lab[2]; - var x; - var y; - var z; + function normalizeObjectUnits(inputObject) { + var normalizedInput = {}, + normalizedProp, + prop; - y = (l + 16) / 116; - x = a / 500 + y; - z = y - b / 200; + for (prop in inputObject) { + if (hasOwnProp(inputObject, prop)) { + normalizedProp = normalizeUnits(prop); + if (normalizedProp) { + normalizedInput[normalizedProp] = inputObject[prop]; + } + } + } - var y2 = Math.pow(y, 3); - var x2 = Math.pow(x, 3); - var z2 = Math.pow(z, 3); - y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; - x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; - z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; + return normalizedInput; + } - x *= 95.047; - y *= 100; - z *= 108.883; + var priorities = {}; - return [x, y, z]; -}; + function addUnitPriority(unit, priority) { + priorities[unit] = priority; + } -convert.lab.lch = function (lab) { - var l = lab[0]; - var a = lab[1]; - var b = lab[2]; - var hr; - var h; - var c; - - hr = Math.atan2(b, a); - h = hr * 360 / 2 / Math.PI; + function getPrioritizedUnits(unitsObj) { + var units = []; + for (var u in unitsObj) { + units.push({unit: u, priority: priorities[u]}); + } + units.sort(function (a, b) { + return a.priority - b.priority; + }); + return units; + } - if (h < 0) { - h += 360; - } + function zeroFill(number, targetLength, forceSign) { + var absNumber = '' + Math.abs(number), + zerosToFill = targetLength - absNumber.length, + sign = number >= 0; + return (sign ? (forceSign ? '+' : '') : '-') + + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; + } - c = Math.sqrt(a * a + b * b); + var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; - return [l, c, h]; -}; + var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; -convert.lch.lab = function (lch) { - var l = lch[0]; - var c = lch[1]; - var h = lch[2]; - var a; - var b; - var hr; + var formatFunctions = {}; - hr = h / 360 * 2 * Math.PI; - a = c * Math.cos(hr); - b = c * Math.sin(hr); + var formatTokenFunctions = {}; - return [l, a, b]; -}; + // token: 'M' + // padded: ['MM', 2] + // ordinal: 'Mo' + // callback: function () { this.month() + 1 } + function addFormatToken (token, padded, ordinal, callback) { + var func = callback; + if (typeof callback === 'string') { + func = function () { + return this[callback](); + }; + } + if (token) { + formatTokenFunctions[token] = func; + } + if (padded) { + formatTokenFunctions[padded[0]] = function () { + return zeroFill(func.apply(this, arguments), padded[1], padded[2]); + }; + } + if (ordinal) { + formatTokenFunctions[ordinal] = function () { + return this.localeData().ordinal(func.apply(this, arguments), token); + }; + } + } -convert.rgb.ansi16 = function (args) { - var r = args[0]; - var g = args[1]; - var b = args[2]; - var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization + function removeFormattingTokens(input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|\]$/g, ''); + } + return input.replace(/\\/g, ''); + } - value = Math.round(value / 50); + function makeFormatFunction(format) { + var array = format.match(formattingTokens), i, length; - if (value === 0) { - return 30; - } + for (i = 0, length = array.length; i < length; i++) { + if (formatTokenFunctions[array[i]]) { + array[i] = formatTokenFunctions[array[i]]; + } else { + array[i] = removeFormattingTokens(array[i]); + } + } - var ansi = 30 - + ((Math.round(b / 255) << 2) - | (Math.round(g / 255) << 1) - | Math.round(r / 255)); + return function (mom) { + var output = '', i; + for (i = 0; i < length; i++) { + output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; + } + return output; + }; + } - if (value === 2) { - ansi += 60; - } + // format date using native date object + function formatMoment(m, format) { + if (!m.isValid()) { + return m.localeData().invalidDate(); + } - return ansi; -}; + format = expandFormat(format, m.localeData()); + formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); -convert.hsv.ansi16 = function (args) { - // optimization here; we already know the value and don't need to get - // it converted for us. - return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); -}; + return formatFunctions[format](m); + } -convert.rgb.ansi256 = function (args) { - var r = args[0]; - var g = args[1]; - var b = args[2]; + function expandFormat(format, locale) { + var i = 5; - // we use the extended greyscale palette here, with the exception of - // black and white. normal palette only has 4 greyscale shades. - if (r === g && g === b) { - if (r < 8) { - return 16; - } + function replaceLongDateFormatTokens(input) { + return locale.longDateFormat(input) || input; + } - if (r > 248) { - return 231; - } + localFormattingTokens.lastIndex = 0; + while (i >= 0 && localFormattingTokens.test(format)) { + format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); + localFormattingTokens.lastIndex = 0; + i -= 1; + } - return Math.round(((r - 8) / 247) * 24) + 232; - } + return format; + } - var ansi = 16 - + (36 * Math.round(r / 255 * 5)) - + (6 * Math.round(g / 255 * 5)) - + Math.round(b / 255 * 5); + var match1 = /\d/; // 0 - 9 + var match2 = /\d\d/; // 00 - 99 + var match3 = /\d{3}/; // 000 - 999 + var match4 = /\d{4}/; // 0000 - 9999 + var match6 = /[+-]?\d{6}/; // -999999 - 999999 + var match1to2 = /\d\d?/; // 0 - 99 + var match3to4 = /\d\d\d\d?/; // 999 - 9999 + var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 + var match1to3 = /\d{1,3}/; // 0 - 999 + var match1to4 = /\d{1,4}/; // 0 - 9999 + var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 - return ansi; -}; + var matchUnsigned = /\d+/; // 0 - inf + var matchSigned = /[+-]?\d+/; // -inf - inf -convert.ansi16.rgb = function (args) { - var color = args % 10; + var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z + var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z - // handle greyscale - if (color === 0 || color === 7) { - if (args > 50) { - color += 3.5; - } + var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 - color = color / 10.5 * 255; + // any word (or two) characters or numbers including two/three word month in arabic. + // includes scottish gaelic two word and hyphenated months + var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i; - return [color, color, color]; - } + var regexes = {}; - var mult = (~~(args > 50) + 1) * 0.5; - var r = ((color & 1) * mult) * 255; - var g = (((color >> 1) & 1) * mult) * 255; - var b = (((color >> 2) & 1) * mult) * 255; + function addRegexToken (token, regex, strictRegex) { + regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { + return (isStrict && strictRegex) ? strictRegex : regex; + }; + } - return [r, g, b]; -}; + function getParseRegexForToken (token, config) { + if (!hasOwnProp(regexes, token)) { + return new RegExp(unescapeFormat(token)); + } -convert.ansi256.rgb = function (args) { - // handle greyscale - if (args >= 232) { - var c = (args - 232) * 10 + 8; - return [c, c, c]; - } + return regexes[token](config._strict, config._locale); + } - args -= 16; + // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript + function unescapeFormat(s) { + return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { + return p1 || p2 || p3 || p4; + })); + } - var rem; - var r = Math.floor(args / 36) / 5 * 255; - var g = Math.floor((rem = args % 36) / 6) / 5 * 255; - var b = (rem % 6) / 5 * 255; + function regexEscape(s) { + return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); + } - return [r, g, b]; -}; + var tokens = {}; -convert.rgb.hex = function (args) { - var integer = ((Math.round(args[0]) & 0xFF) << 16) - + ((Math.round(args[1]) & 0xFF) << 8) - + (Math.round(args[2]) & 0xFF); + function addParseToken (token, callback) { + var i, func = callback; + if (typeof token === 'string') { + token = [token]; + } + if (isNumber(callback)) { + func = function (input, array) { + array[callback] = toInt(input); + }; + } + for (i = 0; i < token.length; i++) { + tokens[token[i]] = func; + } + } - var string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; + function addWeekParseToken (token, callback) { + addParseToken(token, function (input, array, config, token) { + config._w = config._w || {}; + callback(input, config._w, config, token); + }); + } -convert.hex.rgb = function (args) { - var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); - if (!match) { - return [0, 0, 0]; - } + function addTimeToArrayFromToken(token, input, config) { + if (input != null && hasOwnProp(tokens, token)) { + tokens[token](input, config._a, config, token); + } + } - var colorString = match[0]; + var YEAR = 0; + var MONTH = 1; + var DATE = 2; + var HOUR = 3; + var MINUTE = 4; + var SECOND = 5; + var MILLISECOND = 6; + var WEEK = 7; + var WEEKDAY = 8; - if (match[0].length === 3) { - colorString = colorString.split('').map(function (char) { - return char + char; - }).join(''); - } + // FORMATTING - var integer = parseInt(colorString, 16); - var r = (integer >> 16) & 0xFF; - var g = (integer >> 8) & 0xFF; - var b = integer & 0xFF; + addFormatToken('Y', 0, 0, function () { + var y = this.year(); + return y <= 9999 ? '' + y : '+' + y; + }); - return [r, g, b]; -}; + addFormatToken(0, ['YY', 2], 0, function () { + return this.year() % 100; + }); -convert.rgb.hcg = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var max = Math.max(Math.max(r, g), b); - var min = Math.min(Math.min(r, g), b); - var chroma = (max - min); - var grayscale; - var hue; + addFormatToken(0, ['YYYY', 4], 0, 'year'); + addFormatToken(0, ['YYYYY', 5], 0, 'year'); + addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); - if (chroma < 1) { - grayscale = min / (1 - chroma); - } else { - grayscale = 0; - } + // ALIASES - if (chroma <= 0) { - hue = 0; - } else - if (max === r) { - hue = ((g - b) / chroma) % 6; - } else - if (max === g) { - hue = 2 + (b - r) / chroma; - } else { - hue = 4 + (r - g) / chroma + 4; - } + addUnitAlias('year', 'y'); - hue /= 6; - hue %= 1; + // PRIORITIES - return [hue * 360, chroma * 100, grayscale * 100]; -}; + addUnitPriority('year', 1); -convert.hsl.hcg = function (hsl) { - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var c = 1; - var f = 0; + // PARSING - if (l < 0.5) { - c = 2.0 * s * l; - } else { - c = 2.0 * s * (1.0 - l); - } + addRegexToken('Y', matchSigned); + addRegexToken('YY', match1to2, match2); + addRegexToken('YYYY', match1to4, match4); + addRegexToken('YYYYY', match1to6, match6); + addRegexToken('YYYYYY', match1to6, match6); - if (c < 1.0) { - f = (l - 0.5 * c) / (1.0 - c); - } + addParseToken(['YYYYY', 'YYYYYY'], YEAR); + addParseToken('YYYY', function (input, array) { + array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); + }); + addParseToken('YY', function (input, array) { + array[YEAR] = hooks.parseTwoDigitYear(input); + }); + addParseToken('Y', function (input, array) { + array[YEAR] = parseInt(input, 10); + }); - return [hsl[0], c * 100, f * 100]; -}; + // HELPERS -convert.hsv.hcg = function (hsv) { - var s = hsv[1] / 100; - var v = hsv[2] / 100; + function daysInYear(year) { + return isLeapYear(year) ? 366 : 365; + } - var c = s * v; - var f = 0; + function isLeapYear(year) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; + } - if (c < 1.0) { - f = (v - c) / (1 - c); - } + // HOOKS - return [hsv[0], c * 100, f * 100]; -}; + hooks.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); + }; -convert.hcg.rgb = function (hcg) { - var h = hcg[0] / 360; - var c = hcg[1] / 100; - var g = hcg[2] / 100; + // MOMENTS - if (c === 0.0) { - return [g * 255, g * 255, g * 255]; - } + var getSetYear = makeGetSet('FullYear', true); - var pure = [0, 0, 0]; - var hi = (h % 1) * 6; - var v = hi % 1; - var w = 1 - v; - var mg = 0; + function getIsLeapYear () { + return isLeapYear(this.year()); + } - switch (Math.floor(hi)) { - case 0: - pure[0] = 1; pure[1] = v; pure[2] = 0; break; - case 1: - pure[0] = w; pure[1] = 1; pure[2] = 0; break; - case 2: - pure[0] = 0; pure[1] = 1; pure[2] = v; break; - case 3: - pure[0] = 0; pure[1] = w; pure[2] = 1; break; - case 4: - pure[0] = v; pure[1] = 0; pure[2] = 1; break; - default: - pure[0] = 1; pure[1] = 0; pure[2] = w; - } + function makeGetSet (unit, keepTime) { + return function (value) { + if (value != null) { + set$1(this, unit, value); + hooks.updateOffset(this, keepTime); + return this; + } else { + return get(this, unit); + } + }; + } - mg = (1.0 - c) * g; + function get (mom, unit) { + return mom.isValid() ? + mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; + } - return [ - (c * pure[0] + mg) * 255, - (c * pure[1] + mg) * 255, - (c * pure[2] + mg) * 255 - ]; -}; + function set$1 (mom, unit, value) { + if (mom.isValid() && !isNaN(value)) { + if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); + } + else { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } + } + } -convert.hcg.hsv = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; + // MOMENTS - var v = c + g * (1.0 - c); - var f = 0; + function stringGet (units) { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](); + } + return this; + } - if (v > 0.0) { - f = c / v; - } - return [hcg[0], f * 100, v * 100]; -}; + function stringSet (units, value) { + if (typeof units === 'object') { + units = normalizeObjectUnits(units); + var prioritized = getPrioritizedUnits(units); + for (var i = 0; i < prioritized.length; i++) { + this[prioritized[i].unit](units[prioritized[i].unit]); + } + } else { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](value); + } + } + return this; + } -convert.hcg.hsl = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; + function mod(n, x) { + return ((n % x) + x) % x; + } - var l = g * (1.0 - c) + 0.5 * c; - var s = 0; + var indexOf; - if (l > 0.0 && l < 0.5) { - s = c / (2 * l); - } else - if (l >= 0.5 && l < 1.0) { - s = c / (2 * (1 - l)); - } + if (Array.prototype.indexOf) { + indexOf = Array.prototype.indexOf; + } else { + indexOf = function (o) { + // I know + var i; + for (i = 0; i < this.length; ++i) { + if (this[i] === o) { + return i; + } + } + return -1; + }; + } - return [hcg[0], s * 100, l * 100]; -}; + function daysInMonth(year, month) { + if (isNaN(year) || isNaN(month)) { + return NaN; + } + var modMonth = mod(month, 12); + year += (month - modMonth) / 12; + return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); + } -convert.hcg.hwb = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - var v = c + g * (1.0 - c); - return [hcg[0], (v - c) * 100, (1 - v) * 100]; -}; + // FORMATTING -convert.hwb.hcg = function (hwb) { - var w = hwb[1] / 100; - var b = hwb[2] / 100; - var v = 1 - b; - var c = v - w; - var g = 0; + addFormatToken('M', ['MM', 2], 'Mo', function () { + return this.month() + 1; + }); - if (c < 1) { - g = (v - c) / (1 - c); - } + addFormatToken('MMM', 0, 0, function (format) { + return this.localeData().monthsShort(this, format); + }); - return [hwb[0], c * 100, g * 100]; -}; + addFormatToken('MMMM', 0, 0, function (format) { + return this.localeData().months(this, format); + }); -convert.apple.rgb = function (apple) { - return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; -}; + // ALIASES -convert.rgb.apple = function (rgb) { - return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; -}; + addUnitAlias('month', 'M'); -convert.gray.rgb = function (args) { - return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; -}; + // PRIORITY -convert.gray.hsl = convert.gray.hsv = function (args) { - return [0, 0, args[0]]; -}; + addUnitPriority('month', 8); -convert.gray.hwb = function (gray) { - return [0, 100, gray[0]]; -}; + // PARSING -convert.gray.cmyk = function (gray) { - return [0, 0, 0, gray[0]]; -}; + addRegexToken('M', match1to2); + addRegexToken('MM', match1to2, match2); + addRegexToken('MMM', function (isStrict, locale) { + return locale.monthsShortRegex(isStrict); + }); + addRegexToken('MMMM', function (isStrict, locale) { + return locale.monthsRegex(isStrict); + }); -convert.gray.lab = function (gray) { - return [gray[0], 0, 0]; -}; + addParseToken(['M', 'MM'], function (input, array) { + array[MONTH] = toInt(input) - 1; + }); -convert.gray.hex = function (gray) { - var val = Math.round(gray[0] / 100 * 255) & 0xFF; - var integer = (val << 16) + (val << 8) + val; + addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { + var month = config._locale.monthsParse(input, token, config._strict); + // if we didn't find a month name, mark the date as invalid. + if (month != null) { + array[MONTH] = month; + } else { + getParsingFlags(config).invalidMonth = input; + } + }); - var string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; + // LOCALES -convert.rgb.gray = function (rgb) { - var val = (rgb[0] + rgb[1] + rgb[2]) / 3; - return [val / 255 * 100]; -}; + var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; + var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); + function localeMonths (m, format) { + if (!m) { + return isArray(this._months) ? this._months : + this._months['standalone']; + } + return isArray(this._months) ? this._months[m.month()] : + this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; + } + var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); + function localeMonthsShort (m, format) { + if (!m) { + return isArray(this._monthsShort) ? this._monthsShort : + this._monthsShort['standalone']; + } + return isArray(this._monthsShort) ? this._monthsShort[m.month()] : + this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; + } -/***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { + function handleStrictParse(monthName, format, strict) { + var i, ii, mom, llc = monthName.toLocaleLowerCase(); + if (!this._monthsParse) { + // this is not used + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + for (i = 0; i < 12; ++i) { + mom = createUTC([2000, i]); + this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); + this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); + } + } -"use strict"; - - -module.exports = { - "aliceblue": [240, 248, 255], - "antiquewhite": [250, 235, 215], - "aqua": [0, 255, 255], - "aquamarine": [127, 255, 212], - "azure": [240, 255, 255], - "beige": [245, 245, 220], - "bisque": [255, 228, 196], - "black": [0, 0, 0], - "blanchedalmond": [255, 235, 205], - "blue": [0, 0, 255], - "blueviolet": [138, 43, 226], - "brown": [165, 42, 42], - "burlywood": [222, 184, 135], - "cadetblue": [95, 158, 160], - "chartreuse": [127, 255, 0], - "chocolate": [210, 105, 30], - "coral": [255, 127, 80], - "cornflowerblue": [100, 149, 237], - "cornsilk": [255, 248, 220], - "crimson": [220, 20, 60], - "cyan": [0, 255, 255], - "darkblue": [0, 0, 139], - "darkcyan": [0, 139, 139], - "darkgoldenrod": [184, 134, 11], - "darkgray": [169, 169, 169], - "darkgreen": [0, 100, 0], - "darkgrey": [169, 169, 169], - "darkkhaki": [189, 183, 107], - "darkmagenta": [139, 0, 139], - "darkolivegreen": [85, 107, 47], - "darkorange": [255, 140, 0], - "darkorchid": [153, 50, 204], - "darkred": [139, 0, 0], - "darksalmon": [233, 150, 122], - "darkseagreen": [143, 188, 143], - "darkslateblue": [72, 61, 139], - "darkslategray": [47, 79, 79], - "darkslategrey": [47, 79, 79], - "darkturquoise": [0, 206, 209], - "darkviolet": [148, 0, 211], - "deeppink": [255, 20, 147], - "deepskyblue": [0, 191, 255], - "dimgray": [105, 105, 105], - "dimgrey": [105, 105, 105], - "dodgerblue": [30, 144, 255], - "firebrick": [178, 34, 34], - "floralwhite": [255, 250, 240], - "forestgreen": [34, 139, 34], - "fuchsia": [255, 0, 255], - "gainsboro": [220, 220, 220], - "ghostwhite": [248, 248, 255], - "gold": [255, 215, 0], - "goldenrod": [218, 165, 32], - "gray": [128, 128, 128], - "green": [0, 128, 0], - "greenyellow": [173, 255, 47], - "grey": [128, 128, 128], - "honeydew": [240, 255, 240], - "hotpink": [255, 105, 180], - "indianred": [205, 92, 92], - "indigo": [75, 0, 130], - "ivory": [255, 255, 240], - "khaki": [240, 230, 140], - "lavender": [230, 230, 250], - "lavenderblush": [255, 240, 245], - "lawngreen": [124, 252, 0], - "lemonchiffon": [255, 250, 205], - "lightblue": [173, 216, 230], - "lightcoral": [240, 128, 128], - "lightcyan": [224, 255, 255], - "lightgoldenrodyellow": [250, 250, 210], - "lightgray": [211, 211, 211], - "lightgreen": [144, 238, 144], - "lightgrey": [211, 211, 211], - "lightpink": [255, 182, 193], - "lightsalmon": [255, 160, 122], - "lightseagreen": [32, 178, 170], - "lightskyblue": [135, 206, 250], - "lightslategray": [119, 136, 153], - "lightslategrey": [119, 136, 153], - "lightsteelblue": [176, 196, 222], - "lightyellow": [255, 255, 224], - "lime": [0, 255, 0], - "limegreen": [50, 205, 50], - "linen": [250, 240, 230], - "magenta": [255, 0, 255], - "maroon": [128, 0, 0], - "mediumaquamarine": [102, 205, 170], - "mediumblue": [0, 0, 205], - "mediumorchid": [186, 85, 211], - "mediumpurple": [147, 112, 219], - "mediumseagreen": [60, 179, 113], - "mediumslateblue": [123, 104, 238], - "mediumspringgreen": [0, 250, 154], - "mediumturquoise": [72, 209, 204], - "mediumvioletred": [199, 21, 133], - "midnightblue": [25, 25, 112], - "mintcream": [245, 255, 250], - "mistyrose": [255, 228, 225], - "moccasin": [255, 228, 181], - "navajowhite": [255, 222, 173], - "navy": [0, 0, 128], - "oldlace": [253, 245, 230], - "olive": [128, 128, 0], - "olivedrab": [107, 142, 35], - "orange": [255, 165, 0], - "orangered": [255, 69, 0], - "orchid": [218, 112, 214], - "palegoldenrod": [238, 232, 170], - "palegreen": [152, 251, 152], - "paleturquoise": [175, 238, 238], - "palevioletred": [219, 112, 147], - "papayawhip": [255, 239, 213], - "peachpuff": [255, 218, 185], - "peru": [205, 133, 63], - "pink": [255, 192, 203], - "plum": [221, 160, 221], - "powderblue": [176, 224, 230], - "purple": [128, 0, 128], - "rebeccapurple": [102, 51, 153], - "red": [255, 0, 0], - "rosybrown": [188, 143, 143], - "royalblue": [65, 105, 225], - "saddlebrown": [139, 69, 19], - "salmon": [250, 128, 114], - "sandybrown": [244, 164, 96], - "seagreen": [46, 139, 87], - "seashell": [255, 245, 238], - "sienna": [160, 82, 45], - "silver": [192, 192, 192], - "skyblue": [135, 206, 235], - "slateblue": [106, 90, 205], - "slategray": [112, 128, 144], - "slategrey": [112, 128, 144], - "snow": [255, 250, 250], - "springgreen": [0, 255, 127], - "steelblue": [70, 130, 180], - "tan": [210, 180, 140], - "teal": [0, 128, 128], - "thistle": [216, 191, 216], - "tomato": [255, 99, 71], - "turquoise": [64, 224, 208], - "violet": [238, 130, 238], - "wheat": [245, 222, 179], - "white": [255, 255, 255], - "whitesmoke": [245, 245, 245], - "yellow": [255, 255, 0], - "yellowgreen": [154, 205, 50] -}; + if (strict) { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } + } + function localeMonthsParse (monthName, format, strict) { + var i, mom, regex; -/***/ }), -/* 9 */ -/***/ (function(module, exports, __webpack_require__) { + if (this._monthsParseExact) { + return handleStrictParse.call(this, monthName, format, strict); + } -var conversions = __webpack_require__(7); + if (!this._monthsParse) { + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + } -/* - this function routes a model to all other models. + // TODO: add sorting + // Sorting makes sure if one month (or abbr) is a prefix of another + // see sorting in computeMonthsParse + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + if (strict && !this._longMonthsParse[i]) { + this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); + this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); + } + if (!strict && !this._monthsParse[i]) { + regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); + this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { + return i; + } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { + return i; + } else if (!strict && this._monthsParse[i].test(monthName)) { + return i; + } + } + } - all functions that are routed have a property `.conversion` attached - to the returned synthetic function. This property is an array - of strings, each with the steps in between the 'from' and 'to' - color models (inclusive). + // MOMENTS - conversions that are not possible simply are not included. -*/ + function setMonth (mom, value) { + var dayOfMonth; -function buildGraph() { - var graph = {}; - // https://jsperf.com/object-keys-vs-for-in-with-closure/3 - var models = Object.keys(conversions); + if (!mom.isValid()) { + // No op + return mom; + } - for (var len = models.length, i = 0; i < len; i++) { - graph[models[i]] = { - // http://jsperf.com/1-vs-infinity - // micro-opt, but this is simple. - distance: -1, - parent: null - }; - } + if (typeof value === 'string') { + if (/^\d+$/.test(value)) { + value = toInt(value); + } else { + value = mom.localeData().monthsParse(value); + // TODO: Another silent failure? + if (!isNumber(value)) { + return mom; + } + } + } - return graph; -} + dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); + mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); + return mom; + } -// https://en.wikipedia.org/wiki/Breadth-first_search -function deriveBFS(fromModel) { - var graph = buildGraph(); - var queue = [fromModel]; // unshift -> queue -> pop + function getSetMonth (value) { + if (value != null) { + setMonth(this, value); + hooks.updateOffset(this, true); + return this; + } else { + return get(this, 'Month'); + } + } - graph[fromModel].distance = 0; + function getDaysInMonth () { + return daysInMonth(this.year(), this.month()); + } - while (queue.length) { - var current = queue.pop(); - var adjacents = Object.keys(conversions[current]); + var defaultMonthsShortRegex = matchWord; + function monthsShortRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsShortStrictRegex; + } else { + return this._monthsShortRegex; + } + } else { + if (!hasOwnProp(this, '_monthsShortRegex')) { + this._monthsShortRegex = defaultMonthsShortRegex; + } + return this._monthsShortStrictRegex && isStrict ? + this._monthsShortStrictRegex : this._monthsShortRegex; + } + } - for (var len = adjacents.length, i = 0; i < len; i++) { - var adjacent = adjacents[i]; - var node = graph[adjacent]; + var defaultMonthsRegex = matchWord; + function monthsRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsStrictRegex; + } else { + return this._monthsRegex; + } + } else { + if (!hasOwnProp(this, '_monthsRegex')) { + this._monthsRegex = defaultMonthsRegex; + } + return this._monthsStrictRegex && isStrict ? + this._monthsStrictRegex : this._monthsRegex; + } + } - if (node.distance === -1) { - node.distance = graph[current].distance + 1; - node.parent = current; - queue.unshift(adjacent); - } - } - } + function computeMonthsParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } - return graph; -} + var shortPieces = [], longPieces = [], mixedPieces = [], + i, mom; + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + shortPieces.push(this.monthsShort(mom, '')); + longPieces.push(this.months(mom, '')); + mixedPieces.push(this.months(mom, '')); + mixedPieces.push(this.monthsShort(mom, '')); + } + // Sorting makes sure if one month (or abbr) is a prefix of another it + // will match the longer piece. + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 12; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + } + for (i = 0; i < 24; i++) { + mixedPieces[i] = regexEscape(mixedPieces[i]); + } -function link(from, to) { - return function (args) { - return to(from(args)); - }; -} + this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._monthsShortRegex = this._monthsRegex; + this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); + } -function wrapConversion(toModel, graph) { - var path = [graph[toModel].parent, toModel]; - var fn = conversions[graph[toModel].parent][toModel]; + function createDate (y, m, d, h, M, s, ms) { + // can't just apply() to create a date: + // https://stackoverflow.com/q/181348 + var date; + // the date constructor remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0) { + // preserve leap years using a full 400 year cycle, then reset + date = new Date(y + 400, m, d, h, M, s, ms); + if (isFinite(date.getFullYear())) { + date.setFullYear(y); + } + } else { + date = new Date(y, m, d, h, M, s, ms); + } - var cur = graph[toModel].parent; - while (graph[cur].parent) { - path.unshift(graph[cur].parent); - fn = link(conversions[graph[cur].parent][cur], fn); - cur = graph[cur].parent; - } - - fn.conversion = path; - return fn; -} - -module.exports = function (fromModel) { - var graph = deriveBFS(fromModel); - var conversion = {}; - - var models = Object.keys(graph); - for (var len = models.length, i = 0; i < len; i++) { - var toModel = models[i]; - var node = graph[toModel]; + return date; + } - if (node.parent === null) { - // no possible conversion, or this node is the source model. - continue; - } + function createUTCDate (y) { + var date; + // the Date.UTC function remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0) { + var args = Array.prototype.slice.call(arguments); + // preserve leap years using a full 400 year cycle, then reset + args[0] = y + 400; + date = new Date(Date.UTC.apply(null, args)); + if (isFinite(date.getUTCFullYear())) { + date.setUTCFullYear(y); + } + } else { + date = new Date(Date.UTC.apply(null, arguments)); + } - conversion[toModel] = wrapConversion(toModel, graph); - } + return date; + } - return conversion; -}; + // start-of-first-week - start-of-year + function firstWeekOffset(year, dow, doy) { + var // first-week day -- which january is always in the first week (4 for iso, 1 for other) + fwd = 7 + dow - doy, + // first-week day local weekday -- which local weekday is fwd + fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; + return -fwdlw + fwd - 1; + } + // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday + function dayOfYearFromWeeks(year, week, weekday, dow, doy) { + var localWeekday = (7 + weekday - dow) % 7, + weekOffset = firstWeekOffset(year, dow, doy), + dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, + resYear, resDayOfYear; -/***/ }), -/* 10 */ -/***/ (function(module, exports, __webpack_require__) { + if (dayOfYear <= 0) { + resYear = year - 1; + resDayOfYear = daysInYear(resYear) + dayOfYear; + } else if (dayOfYear > daysInYear(year)) { + resYear = year + 1; + resDayOfYear = dayOfYear - daysInYear(year); + } else { + resYear = year; + resDayOfYear = dayOfYear; + } -"use strict"; + return { + year: resYear, + dayOfYear: resDayOfYear + }; + } -const os = __webpack_require__(11); -const hasFlag = __webpack_require__(12); + function weekOfYear(mom, dow, doy) { + var weekOffset = firstWeekOffset(mom.year(), dow, doy), + week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, + resWeek, resYear; -const env = process.env; + if (week < 1) { + resYear = mom.year() - 1; + resWeek = week + weeksInYear(resYear, dow, doy); + } else if (week > weeksInYear(mom.year(), dow, doy)) { + resWeek = week - weeksInYear(mom.year(), dow, doy); + resYear = mom.year() + 1; + } else { + resYear = mom.year(); + resWeek = week; + } -let forceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false')) { - forceColor = false; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - forceColor = true; -} -if ('FORCE_COLOR' in env) { - forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; -} + return { + week: resWeek, + year: resYear + }; + } -function translateLevel(level) { - if (level === 0) { - return false; - } + function weeksInYear(year, dow, doy) { + var weekOffset = firstWeekOffset(year, dow, doy), + weekOffsetNext = firstWeekOffset(year + 1, dow, doy); + return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; + } - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} + // FORMATTING -function supportsColor(stream) { - if (forceColor === false) { - return 0; - } + addFormatToken('w', ['ww', 2], 'wo', 'week'); + addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } + // ALIASES - if (hasFlag('color=256')) { - return 2; - } + addUnitAlias('week', 'w'); + addUnitAlias('isoWeek', 'W'); - if (stream && !stream.isTTY && forceColor !== true) { - // VS code debugger doesn't have isTTY set - if (env.VSCODE_PID) { - return 1; - } - return 0; - } + // PRIORITIES - const min = forceColor ? 1 : 0; + addUnitPriority('week', 5); + addUnitPriority('isoWeek', 5); - if (process.platform === 'win32') { - // Node.js 7.5.0 is the first version of Node.js to include a patch to - // libuv that enables 256 color output on Windows. Anything earlier and it - // won't work. However, here we target Node.js 8 at minimum as it is an LTS - // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows - // release that supports 256 colors. Windows 10 build 14931 is the first release - // that supports 16m/TrueColor. - const osRelease = os.release().split('.'); - if ( - Number(process.versions.node.split('.')[0]) >= 8 && - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } + // PARSING - return 1; - } + addRegexToken('w', match1to2); + addRegexToken('ww', match1to2, match2); + addRegexToken('W', match1to2); + addRegexToken('WW', match1to2, match2); - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; - } + addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { + week[token.substr(0, 1)] = toInt(input); + }); - return min; - } + // HELPERS - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } + // LOCALES - if (env.COLORTERM === 'truecolor') { - return 3; - } + function localeWeek (mom) { + return weekOfYear(mom, this._week.dow, this._week.doy).week; + } - if ('TERM_PROGRAM' in env) { - const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + var defaultLocaleWeek = { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 6th is the first week of the year. + }; - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } + function localeFirstDayOfWeek () { + return this._week.dow; + } - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } + function localeFirstDayOfYear () { + return this._week.doy; + } - if (/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } + // MOMENTS - if ('COLORTERM' in env) { - return 1; - } + function getSetWeek (input) { + var week = this.localeData().week(this); + return input == null ? week : this.add((input - week) * 7, 'd'); + } - if (env.TERM === 'dumb') { - return min; - } + function getSetISOWeek (input) { + var week = weekOfYear(this, 1, 4).week; + return input == null ? week : this.add((input - week) * 7, 'd'); + } - return min; -} + // FORMATTING -function getSupportLevel(stream) { - const level = supportsColor(stream); - return translateLevel(level); -} + addFormatToken('d', 0, 'do', 'day'); -module.exports = { - supportsColor: getSupportLevel, - stdout: getSupportLevel(process.stdout), - stderr: getSupportLevel(process.stderr) -}; + addFormatToken('dd', 0, 0, function (format) { + return this.localeData().weekdaysMin(this, format); + }); + addFormatToken('ddd', 0, 0, function (format) { + return this.localeData().weekdaysShort(this, format); + }); -/***/ }), -/* 11 */ -/***/ (function(module, exports) { + addFormatToken('dddd', 0, 0, function (format) { + return this.localeData().weekdays(this, format); + }); -module.exports = require("os"); + addFormatToken('e', 0, 0, 'weekday'); + addFormatToken('E', 0, 0, 'isoWeekday'); -/***/ }), -/* 12 */ -/***/ (function(module, exports, __webpack_require__) { + // ALIASES -"use strict"; + addUnitAlias('day', 'd'); + addUnitAlias('weekday', 'e'); + addUnitAlias('isoWeekday', 'E'); -module.exports = (flag, argv) => { - argv = argv || process.argv; - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const pos = argv.indexOf(prefix + flag); - const terminatorPos = argv.indexOf('--'); - return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); -}; + // PRIORITY + addUnitPriority('day', 11); + addUnitPriority('weekday', 11); + addUnitPriority('isoWeekday', 11); + // PARSING -/***/ }), -/* 13 */ -/***/ (function(module, exports, __webpack_require__) { + addRegexToken('d', match1to2); + addRegexToken('e', match1to2); + addRegexToken('E', match1to2); + addRegexToken('dd', function (isStrict, locale) { + return locale.weekdaysMinRegex(isStrict); + }); + addRegexToken('ddd', function (isStrict, locale) { + return locale.weekdaysShortRegex(isStrict); + }); + addRegexToken('dddd', function (isStrict, locale) { + return locale.weekdaysRegex(isStrict); + }); -"use strict"; + addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { + var weekday = config._locale.weekdaysParse(input, token, config._strict); + // if we didn't get a weekday name, mark the date as invalid + if (weekday != null) { + week.d = weekday; + } else { + getParsingFlags(config).invalidWeekday = input; + } + }); -const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; -const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; -const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; + addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { + week[token] = toInt(input); + }); -const ESCAPES = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); + // HELPERS -function unescape(c) { - if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); - } + function parseWeekday(input, locale) { + if (typeof input !== 'string') { + return input; + } - return ESCAPES.get(c) || c; -} + if (!isNaN(input)) { + return parseInt(input, 10); + } -function parseArguments(name, args) { - const results = []; - const chunks = args.trim().split(/\s*,\s*/g); - let matches; + input = locale.weekdaysParse(input); + if (typeof input === 'number') { + return input; + } - for (const chunk of chunks) { - if (!isNaN(chunk)) { - results.push(Number(chunk)); - } else if ((matches = chunk.match(STRING_REGEX))) { - results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); - } else { - throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); - } - } + return null; + } - return results; -} + function parseIsoWeekday(input, locale) { + if (typeof input === 'string') { + return locale.weekdaysParse(input) % 7 || 7; + } + return isNaN(input) ? null : input; + } -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; + // LOCALES + function shiftWeekdays (ws, n) { + return ws.slice(n, 7).concat(ws.slice(0, n)); + } - const results = []; - let matches; + var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); + function localeWeekdays (m, format) { + var weekdays = isArray(this._weekdays) ? this._weekdays : + this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone']; + return (m === true) ? shiftWeekdays(weekdays, this._week.dow) + : (m) ? weekdays[m.day()] : weekdays; + } - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; + var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); + function localeWeekdaysShort (m) { + return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow) + : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; + } - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } - } + var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); + function localeWeekdaysMin (m) { + return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow) + : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; + } - return results; -} + function handleStrictParse$1(weekdayName, format, strict) { + var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._shortWeekdaysParse = []; + this._minWeekdaysParse = []; -function buildStyle(chalk, styles) { - const enabled = {}; + for (i = 0; i < 7; ++i) { + mom = createUTC([2000, 1]).day(i); + this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); + this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); + this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); + } + } - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } - } + if (strict) { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } + } - let current = chalk; - for (const styleName of Object.keys(enabled)) { - if (Array.isArray(enabled[styleName])) { - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } + function localeWeekdaysParse (weekdayName, format, strict) { + var i, mom, regex; - if (enabled[styleName].length > 0) { - current = current[styleName].apply(current, enabled[styleName]); - } else { - current = current[styleName]; - } - } - } + if (this._weekdaysParseExact) { + return handleStrictParse$1.call(this, weekdayName, format, strict); + } - return current; -} + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._minWeekdaysParse = []; + this._shortWeekdaysParse = []; + this._fullWeekdaysParse = []; + } -module.exports = (chalk, tmp) => { - const styles = []; - const chunks = []; - let chunk = []; + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already - // eslint-disable-next-line max-params - tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { - if (escapeChar) { - chunk.push(unescape(escapeChar)); - } else if (style) { - const str = chunk.join(''); - chunk = []; - chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); - styles.push({inverse, styles: parseStyle(style)}); - } else if (close) { - if (styles.length === 0) { - throw new Error('Found extraneous } in Chalk template literal'); - } + mom = createUTC([2000, 1]).day(i); + if (strict && !this._fullWeekdaysParse[i]) { + this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i'); + this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i'); + this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i'); + } + if (!this._weekdaysParse[i]) { + regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); + this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { + return i; + } + } + } - chunks.push(buildStyle(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(chr); - } - }); + // MOMENTS - chunks.push(chunk.join('')); + function getSetDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); + if (input != null) { + input = parseWeekday(input, this.localeData()); + return this.add(input - day, 'd'); + } else { + return day; + } + } - if (styles.length > 0) { - const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMsg); - } + function getSetLocaleDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; + return input == null ? weekday : this.add(input - weekday, 'd'); + } - return chunks.join(''); -}; + function getSetISODayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + // behaves the same as moment#day except + // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) + // as a setter, sunday should belong to the previous week. -/***/ }), -/* 14 */ -/***/ (function(module, exports, __webpack_require__) { + if (input != null) { + var weekday = parseIsoWeekday(input, this.localeData()); + return this.day(this.day() % 7 ? weekday : weekday - 7); + } else { + return this.day() || 7; + } + } -"use strict"; + var defaultWeekdaysRegex = matchWord; + function weekdaysRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysStrictRegex; + } else { + return this._weekdaysRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysRegex')) { + this._weekdaysRegex = defaultWeekdaysRegex; + } + return this._weekdaysStrictRegex && isStrict ? + this._weekdaysStrictRegex : this._weekdaysRegex; + } + } + var defaultWeekdaysShortRegex = matchWord; + function weekdaysShortRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysShortStrictRegex; + } else { + return this._weekdaysShortRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysShortRegex')) { + this._weekdaysShortRegex = defaultWeekdaysShortRegex; + } + return this._weekdaysShortStrictRegex && isStrict ? + this._weekdaysShortStrictRegex : this._weekdaysShortRegex; + } + } -function dedent(strings) { + var defaultWeekdaysMinRegex = matchWord; + function weekdaysMinRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysMinStrictRegex; + } else { + return this._weekdaysMinRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysMinRegex')) { + this._weekdaysMinRegex = defaultWeekdaysMinRegex; + } + return this._weekdaysMinStrictRegex && isStrict ? + this._weekdaysMinStrictRegex : this._weekdaysMinRegex; + } + } - var raw = void 0; - if (typeof strings === "string") { - // dedent can be used as a plain function - raw = [strings]; - } else { - raw = strings.raw; - } - // first, perform interpolation - var result = ""; - for (var i = 0; i < raw.length; i++) { - result += raw[i]. - // join lines when there is a suppressed newline - replace(/\\\n[ \t]*/g, ""). + function computeWeekdaysParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } - // handle escaped backticks - replace(/\\`/g, "`"); + var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], + i, mom, minp, shortp, longp; + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, 1]).day(i); + minp = this.weekdaysMin(mom, ''); + shortp = this.weekdaysShort(mom, ''); + longp = this.weekdays(mom, ''); + minPieces.push(minp); + shortPieces.push(shortp); + longPieces.push(longp); + mixedPieces.push(minp); + mixedPieces.push(shortp); + mixedPieces.push(longp); + } + // Sorting makes sure if one weekday (or abbr) is a prefix of another it + // will match the longer piece. + minPieces.sort(cmpLenRev); + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 7; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + mixedPieces[i] = regexEscape(mixedPieces[i]); + } - if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) { - result += arguments.length <= i + 1 ? undefined : arguments[i + 1]; - } - } + this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._weekdaysShortRegex = this._weekdaysRegex; + this._weekdaysMinRegex = this._weekdaysRegex; - // now strip indentation - var lines = result.split("\n"); - var mindent = null; - lines.forEach(function (l) { - var m = l.match(/^(\s+)\S+/); - if (m) { - var indent = m[1].length; - if (!mindent) { - // this is the first indented line - mindent = indent; - } else { - mindent = Math.min(mindent, indent); - } + this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); + this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); } - }); - if (mindent !== null) { - result = lines.map(function (l) { - return l[0] === " " ? l.slice(mindent) : l; - }).join("\n"); - } + // FORMATTING - // dedent eats leading and trailing whitespace too - result = result.trim(); + function hFormat() { + return this.hours() % 12 || 12; + } - // handle escaped newlines at the end to ensure they don't get stripped too - return result.replace(/\\n/g, "\n"); -} + function kFormat() { + return this.hours() || 24; + } -if (true) { - module.exports = dedent; -} + addFormatToken('H', ['HH', 2], 0, 'hour'); + addFormatToken('h', ['hh', 2], 0, hFormat); + addFormatToken('k', ['kk', 2], 0, kFormat); + addFormatToken('hmm', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); + }); -/***/ }), -/* 15 */ -/***/ (function(module, exports, __webpack_require__) { + addFormatToken('hmmss', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); + }); -"use strict"; + addFormatToken('Hmm', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2); + }); + addFormatToken('Hmmss', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); + }); -const EMPTYARR = [] -const SHORTSPLIT = /$|[!-@[-`{-~][\s\S]*/g -const isArray = Array.isArray + function meridiem (token, lowercase) { + addFormatToken(token, 0, 0, function () { + return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); + }); + } -const parseValue = function(any) { - if (any === "") return "" - if (any === "false") return false - const maybe = Number(any) - return maybe * 0 === 0 ? maybe : any -} + meridiem('a', true); + meridiem('A', false); -const parseAlias = function(aliases) { - let out = {}, - key, - alias, - prev, - len, - any, - i, - k + // ALIASES - for (key in aliases) { - any = aliases[key] - alias = out[key] = isArray(any) ? any : [any] + addUnitAlias('hour', 'h'); - for (i = 0, len = alias.length; i < len; i++) { - prev = out[alias[i]] = [key] + // PRIORITY + addUnitPriority('hour', 13); - for (k = 0; k < len; k++) { - if (i !== k) prev.push(alias[k]) - } + // PARSING + + function matchMeridiem (isStrict, locale) { + return locale._meridiemParse; } - } - return out -} + addRegexToken('a', matchMeridiem); + addRegexToken('A', matchMeridiem); + addRegexToken('H', match1to2); + addRegexToken('h', match1to2); + addRegexToken('k', match1to2); + addRegexToken('HH', match1to2, match2); + addRegexToken('hh', match1to2, match2); + addRegexToken('kk', match1to2, match2); -const parseDefault = function(aliases, defaults) { - let out = {}, - key, - alias, - value, - len, - i + addRegexToken('hmm', match3to4); + addRegexToken('hmmss', match5to6); + addRegexToken('Hmm', match3to4); + addRegexToken('Hmmss', match5to6); - for (key in defaults) { - value = defaults[key] - alias = aliases[key] + addParseToken(['H', 'HH'], HOUR); + addParseToken(['k', 'kk'], function (input, array, config) { + var kInput = toInt(input); + array[HOUR] = kInput === 24 ? 0 : kInput; + }); + addParseToken(['a', 'A'], function (input, array, config) { + config._isPm = config._locale.isPM(input); + config._meridiem = input; + }); + addParseToken(['h', 'hh'], function (input, array, config) { + array[HOUR] = toInt(input); + getParsingFlags(config).bigHour = true; + }); + addParseToken('hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('Hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + }); + addParseToken('Hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + }); - out[key] = value + // LOCALES - if (alias === undefined) { - aliases[key] = EMPTYARR - } else { - for (i = 0, len = alias.length; i < len; i++) { - out[alias[i]] = value - } + function localeIsPM (input) { + // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays + // Using charAt should be more compatible. + return ((input + '').toLowerCase().charAt(0) === 'p'); } - } - return out -} + var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; + function localeMeridiem (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'pm' : 'PM'; + } else { + return isLower ? 'am' : 'AM'; + } + } -const parseOptions = function(aliases, options, value) { - let out = {}, - key, - alias, - len, - end, - i, - k - if (options !== undefined) { - for (i = 0, len = options.length; i < len; i++) { - key = options[i] - alias = aliases[key] + // MOMENTS - out[key] = value + // Setting the hour should keep the time, because the user explicitly + // specified which hour they want. So trying to maintain the same hour (in + // a new timezone) makes sense. Adding/subtracting hours does not follow + // this rule. + var getSetHour = makeGetSet('Hours', true); - if (alias === undefined) { - aliases[key] = EMPTYARR - } else { - for (k = 0, end = alias.length; k < end; k++) { - out[alias[k]] = value - } - } - } - } + var baseConfig = { + calendar: defaultCalendar, + longDateFormat: defaultLongDateFormat, + invalidDate: defaultInvalidDate, + ordinal: defaultOrdinal, + dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, + relativeTime: defaultRelativeTime, - return out -} + months: defaultLocaleMonths, + monthsShort: defaultLocaleMonthsShort, -const write = function(out, key, value, aliases, unknown) { - let i, - prev, - alias = aliases[key], - len = alias === undefined ? -1 : alias.length + week: defaultLocaleWeek, - if (len >= 0 || unknown === undefined || unknown(key)) { - prev = out[key] + weekdays: defaultLocaleWeekdays, + weekdaysMin: defaultLocaleWeekdaysMin, + weekdaysShort: defaultLocaleWeekdaysShort, - if (prev === undefined) { - out[key] = value - } else { - if (isArray(prev)) { - prev.push(value) - } else { - out[key] = [prev, value] - } - } + meridiemParse: defaultLocaleMeridiemParse + }; - for (i = 0; i < len; i++) { - out[alias[i]] = out[key] + // internal storage for locale config files + var locales = {}; + var localeFamilies = {}; + var globalLocale; + + function normalizeLocale(key) { + return key ? key.toLowerCase().replace('_', '-') : key; } - } -} -const getopts = function(argv, opts) { - let unknown = (opts = opts || {}).unknown, - aliases = parseAlias(opts.alias), - strings = parseOptions(aliases, opts.string, ""), - values = parseDefault(aliases, opts.default), - bools = parseOptions(aliases, opts.boolean, false), - stopEarly = opts.stopEarly, - _ = [], - out = { _ }, - i = 0, - k = 0, - len = argv.length, - key, - arg, - end, - match, - value + // pick the locale from the array + // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each + // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root + function chooseLocale(names) { + var i = 0, j, next, locale, split; - for (; i < len; i++) { - arg = argv[i] + while (i < names.length) { + split = normalizeLocale(names[i]).split('-'); + j = split.length; + next = normalizeLocale(names[i + 1]); + next = next ? next.split('-') : null; + while (j > 0) { + locale = loadLocale(split.slice(0, j).join('-')); + if (locale) { + return locale; + } + if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { + //the next array item is better than a shallower substring of this one + break; + } + j--; + } + i++; + } + return globalLocale; + } - if (arg[0] !== "-" || arg === "-") { - if (stopEarly) while (i < len) _.push(argv[i++]) - else _.push(arg) - } else if (arg === "--") { - while (++i < len) _.push(argv[i]) - } else if (arg[1] === "-") { - end = arg.indexOf("=", 2) - if (arg[2] === "n" && arg[3] === "o" && arg[4] === "-") { - key = arg.slice(5, end >= 0 ? end : undefined) - value = false - } else if (end >= 0) { - key = arg.slice(2, end) - value = - bools[key] !== undefined || - (strings[key] === undefined - ? parseValue(arg.slice(end + 1)) - : arg.slice(end + 1)) - } else { - key = arg.slice(2) - value = - bools[key] !== undefined || - (len === i + 1 || argv[i + 1][0] === "-" - ? strings[key] === undefined - ? true - : "" - : strings[key] === undefined - ? parseValue(argv[++i]) - : argv[++i]) - } - write(out, key, value, aliases, unknown) - } else { - SHORTSPLIT.lastIndex = 2 - match = SHORTSPLIT.exec(arg) - end = match.index - value = match[0] - - for (k = 1; k < end; k++) { - write( - out, - (key = arg[k]), - k + 1 < end - ? strings[key] === undefined || - arg.substring(k + 1, (k = end)) + value - : value === "" - ? len === i + 1 || argv[i + 1][0] === "-" - ? strings[key] === undefined || "" - : bools[key] !== undefined || - (strings[key] === undefined ? parseValue(argv[++i]) : argv[++i]) - : bools[key] !== undefined || - (strings[key] === undefined ? parseValue(value) : value), - aliases, - unknown - ) - } + function loadLocale(name) { + var oldLocale = null; + // TODO: Find a better way to register and load all the locales in Node + if (!locales[name] && (typeof module !== 'undefined') && + module && module.exports) { + try { + oldLocale = globalLocale._abbr; + var aliasedRequire = require; + __webpack_require__(12)("./" + name); + getSetGlobalLocale(oldLocale); + } catch (e) {} + } + return locales[name]; } - } - - for (key in values) if (out[key] === undefined) out[key] = values[key] - for (key in bools) if (out[key] === undefined) out[key] = false - for (key in strings) if (out[key] === undefined) out[key] = "" - return out -} + // This function will load locale and then set the global locale. If + // no arguments are passed in, it will simply return the current global + // locale key. + function getSetGlobalLocale (key, values) { + var data; + if (key) { + if (isUndefined(values)) { + data = getLocale(key); + } + else { + data = defineLocale(key, values); + } -module.exports = getopts + if (data) { + // moment.duration._locale = moment._locale = data; + globalLocale = data; + } + else { + if ((typeof console !== 'undefined') && console.warn) { + //warn user if arguments are passed but the locale could not be set + console.warn('Locale ' + key + ' not found. Did you forget to load it?'); + } + } + } + return globalLocale._abbr; + } -/***/ }), -/* 16 */ -/***/ (function(module, exports) { + function defineLocale (name, config) { + if (config !== null) { + var locale, parentConfig = baseConfig; + config.abbr = name; + if (locales[name] != null) { + deprecateSimple('defineLocaleOverride', + 'use moment.updateLocale(localeName, config) to change ' + + 'an existing locale. moment.defineLocale(localeName, ' + + 'config) should only be used for creating a new locale ' + + 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); + parentConfig = locales[name]._config; + } else if (config.parentLocale != null) { + if (locales[config.parentLocale] != null) { + parentConfig = locales[config.parentLocale]._config; + } else { + locale = loadLocale(config.parentLocale); + if (locale != null) { + parentConfig = locale._config; + } else { + if (!localeFamilies[config.parentLocale]) { + localeFamilies[config.parentLocale] = []; + } + localeFamilies[config.parentLocale].push({ + name: name, + config: config + }); + return null; + } + } + } + locales[name] = new Locale(mergeConfigs(parentConfig, config)); -module.exports = require("path"); + if (localeFamilies[name]) { + localeFamilies[name].forEach(function (x) { + defineLocale(x.name, x.config); + }); + } -/***/ }), -/* 17 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + // backwards compat for now: also set the locale + // make sure we set the locale AFTER all child locales have been + // created, so we won't end up with the child locale set. + getSetGlobalLocale(name); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "commands", function() { return commands; }); -/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(18); -/* harmony import */ var _clean__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(586); -/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(686); -/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(687); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + return locales[name]; + } else { + // useful for testing + delete locales[name]; + return null; + } + } + function updateLocale(name, config) { + if (config != null) { + var locale, tmpLocale, parentConfig = baseConfig; + // MERGE + tmpLocale = loadLocale(name); + if (tmpLocale != null) { + parentConfig = tmpLocale._config; + } + config = mergeConfigs(parentConfig, config); + locale = new Locale(config); + locale.parentLocale = locales[name]; + locales[name] = locale; + // backwards compat for now: also set the locale + getSetGlobalLocale(name); + } else { + // pass null for config to unupdate, useful for tests + if (locales[name] != null) { + if (locales[name].parentLocale != null) { + locales[name] = locales[name].parentLocale; + } else if (locales[name] != null) { + delete locales[name]; + } + } + } + return locales[name]; + } -const commands = { - bootstrap: _bootstrap__WEBPACK_IMPORTED_MODULE_0__["BootstrapCommand"], - clean: _clean__WEBPACK_IMPORTED_MODULE_1__["CleanCommand"], - run: _run__WEBPACK_IMPORTED_MODULE_2__["RunCommand"], - watch: _watch__WEBPACK_IMPORTED_MODULE_3__["WatchCommand"] -}; + // returns locale data + function getLocale (key) { + var locale; -/***/ }), -/* 18 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + if (key && key._locale && key._locale._abbr) { + key = key._locale._abbr; + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BootstrapCommand", function() { return BootstrapCommand; }); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _utils_link_project_executables__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(19); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(34); -/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(501); -/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(502); -/* harmony import */ var _utils_project_checksums__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(580); -/* harmony import */ var _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(585); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + if (!key) { + return globalLocale; + } + if (!isArray(key)) { + //short-circuit everything else + locale = loadLocale(key); + if (locale) { + return locale; + } + key = [key]; + } + return chooseLocale(key); + } + function listLocales() { + return keys(locales); + } + function checkOverflow (m) { + var overflow; + var a = m._a; + if (a && getParsingFlags(m).overflow === -2) { + overflow = + a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : + a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : + a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : + a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : + a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : + a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : + -1; + if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { + overflow = DATE; + } + if (getParsingFlags(m)._overflowWeeks && overflow === -1) { + overflow = WEEK; + } + if (getParsingFlags(m)._overflowWeekday && overflow === -1) { + overflow = WEEKDAY; + } -const BootstrapCommand = { - description: 'Install dependencies and crosslink projects', - name: 'bootstrap', + getParsingFlags(m).overflow = overflow; + } - async run(projects, projectGraph, { - options, - kbn - }) { - const batchedProjectsByWorkspace = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_4__["topologicallyBatchProjects"])(projects, projectGraph, { - batchByWorkspace: true - }); - const batchedProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_4__["topologicallyBatchProjects"])(projects, projectGraph); - const extraArgs = [...(options['frozen-lockfile'] === true ? ['--frozen-lockfile'] : []), ...(options['prefer-offline'] === true ? ['--prefer-offline'] : [])]; - _utils_log__WEBPACK_IMPORTED_MODULE_2__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold('\nRunning installs in topological order:')); + return m; + } - for (const batch of batchedProjectsByWorkspace) { - for (const project of batch) { - if (project.isWorkspaceProject) { - _utils_log__WEBPACK_IMPORTED_MODULE_2__["log"].write(`Skipping workspace project: ${project.name}`); - continue; + // Pick the first defined of two or three arguments. + function defaults(a, b, c) { + if (a != null) { + return a; } - - if (project.hasDependencies()) { - await project.installDependencies({ - extraArgs - }); + if (b != null) { + return b; } - } + return c; } - _utils_log__WEBPACK_IMPORTED_MODULE_2__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold('\nInstalls completed, linking package executables:\n')); - await Object(_utils_link_project_executables__WEBPACK_IMPORTED_MODULE_1__["linkProjectExecutables"])(projects, projectGraph); - /** - * At the end of the bootstrapping process we call all `kbn:bootstrap` scripts - * in the list of projects. We do this because some projects need to be - * transpiled before they can be used. Ideally we shouldn't do this unless we - * have to, as it will slow down the bootstrapping process. - */ + function currentDateArray(config) { + // hooks is actually the exported moment object + var nowValue = new Date(hooks.now()); + if (config._useUTC) { + return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; + } + return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; + } - _utils_log__WEBPACK_IMPORTED_MODULE_2__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold('\nLinking executables completed, running `kbn:bootstrap` scripts\n')); - const checksums = options.cache ? await Object(_utils_project_checksums__WEBPACK_IMPORTED_MODULE_5__["getAllChecksums"])(kbn, _utils_log__WEBPACK_IMPORTED_MODULE_2__["log"]) : false; - await Object(_utils_parallelize__WEBPACK_IMPORTED_MODULE_3__["parallelizeBatches"])(batchedProjects, async project => { - if (project.hasScript('kbn:bootstrap')) { - const cacheFile = new _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_6__["BootstrapCacheFile"](kbn, project, checksums); + // convert an array to a date. + // the array should mirror the parameters below + // note: all values past the year are optional and will default to the lowest possible value. + // [year, month, day , hour, minute, second, millisecond] + function configFromArray (config) { + var i, date, input = [], currentDate, expectedWeekday, yearToUse; - if (cacheFile.isValid()) { - _utils_log__WEBPACK_IMPORTED_MODULE_2__["log"].success(`[${project.name}] cache up to date`); - } else { - cacheFile.delete(); - await project.runScriptStreaming('kbn:bootstrap'); - cacheFile.write(); + if (config._d) { + return; } - } - }); - _utils_log__WEBPACK_IMPORTED_MODULE_2__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green.bold('\nBootstrapping completed!\n')); - } -}; - -/***/ }), -/* 19 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + currentDate = currentDateArray(config); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "linkProjectExecutables", function() { return linkProjectExecutables; }); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(16); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(20); -/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(34); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + //compute day of the year from weeks and weekdays + if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { + dayOfYearFromWeekInfo(config); + } + //if the day of the year is set, figure out what it is + if (config._dayOfYear != null) { + yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); + if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { + getParsingFlags(config)._overflowDayOfYear = true; + } + date = createUTCDate(yearToUse, 0, config._dayOfYear); + config._a[MONTH] = date.getUTCMonth(); + config._a[DATE] = date.getUTCDate(); + } + // Default to current date. + // * if no year, month, day of month are given, default to today + // * if day of month is given, default month and year + // * if month is given, default only year + // * if year is given, don't default anything + for (i = 0; i < 3 && config._a[i] == null; ++i) { + config._a[i] = input[i] = currentDate[i]; + } -/** - * Yarn does not link the executables from dependencies that are installed - * using `link:` https://github.com/yarnpkg/yarn/pull/5046 - * - * We simulate this functionality by walking through each project's project - * dependencies, and manually linking their executables if defined. The logic - * for linking was mostly adapted from lerna: https://github.com/lerna/lerna/blob/1d7eb9eeff65d5a7de64dea73613b1bf6bfa8d57/src/PackageUtilities.js#L348 - */ -async function linkProjectExecutables(projectsByName, projectGraph) { - for (const [projectName, projectDeps] of projectGraph) { - const project = projectsByName.get(projectName); - const binsDir = Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(project.nodeModulesLocation, '.bin'); + // Zero out whatever was not defaulted, including time + for (; i < 7; i++) { + config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; + } - for (const projectDep of projectDeps) { - const executables = projectDep.getExecutables(); + // Check for 24:00:00.000 + if (config._a[HOUR] === 24 && + config._a[MINUTE] === 0 && + config._a[SECOND] === 0 && + config._a[MILLISECOND] === 0) { + config._nextDay = true; + config._a[HOUR] = 0; + } - for (const name of Object.keys(executables)) { - const srcPath = executables[name]; // existing logic from lerna -- ensure that the bin we are going to - // point to exists or ignore it + config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); + expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); - if (!(await Object(_fs__WEBPACK_IMPORTED_MODULE_2__["isFile"])(srcPath))) { - continue; + // Apply timezone offset from input. The actual utcOffset can be changed + // with parseZone. + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); } - const dest = Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(binsDir, name); // Get relative project path with normalized path separators. + if (config._nextDay) { + config._a[HOUR] = 24; + } - const projectRelativePath = Object(path__WEBPACK_IMPORTED_MODULE_0__["relative"])(project.path, srcPath).split(path__WEBPACK_IMPORTED_MODULE_0__["sep"]).join('/'); - _log__WEBPACK_IMPORTED_MODULE_3__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_1___default.a`{dim [${project.name}]} ${name} -> {dim ${projectRelativePath}}`); - await Object(_fs__WEBPACK_IMPORTED_MODULE_2__["mkdirp"])(Object(path__WEBPACK_IMPORTED_MODULE_0__["dirname"])(dest)); - await Object(_fs__WEBPACK_IMPORTED_MODULE_2__["createSymlink"])(srcPath, dest, 'exec'); - await Object(_fs__WEBPACK_IMPORTED_MODULE_2__["chmod"])(dest, '755'); - } + // check for mismatching day of week + if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { + getParsingFlags(config).weekdayMismatch = true; + } } - } -} - -/***/ }), -/* 20 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readFile", function() { return readFile; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "chmod", function() { return chmod; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mkdirp", function() { return mkdirp; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unlink", function() { return unlink; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "copyDirectory", function() { return copyDirectory; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isSymlink", function() { return isSymlink; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isDirectory", function() { return isDirectory; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isFile", function() { return isFile; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createSymlink", function() { return createSymlink; }); -/* harmony import */ var cmd_shim__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(21); -/* harmony import */ var cmd_shim__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(cmd_shim__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(23); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var ncp__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(33); -/* harmony import */ var ncp__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(ncp__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(29); -/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_4__); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - - + function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; -const lstat = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.lstat); -const readFile = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.readFile); -const symlink = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.symlink); -const chmod = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.chmod); -const cmdShim = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(cmd_shim__WEBPACK_IMPORTED_MODULE_0___default.a); -const mkdir = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.mkdir); -const mkdirp = async path => await mkdir(path, { - recursive: true -}); -const unlink = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.unlink); -const copyDirectory = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(ncp__WEBPACK_IMPORTED_MODULE_2__["ncp"]); + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; -async function statTest(path, block) { - try { - return block((await lstat(path))); - } catch (e) { - if (e.code === 'ENOENT') { - return false; - } + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); + week = defaults(w.W, 1); + weekday = defaults(w.E, 1); + if (weekday < 1 || weekday > 7) { + weekdayOverflow = true; + } + } else { + dow = config._locale._week.dow; + doy = config._locale._week.doy; - throw e; - } -} -/** - * Test if a path points to a symlink. - * @param path - */ + var curWeek = weekOfYear(createLocal(), dow, doy); + weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); -async function isSymlink(path) { - return await statTest(path, stats => stats.isSymbolicLink()); -} -/** - * Test if a path points to a directory. - * @param path - */ + // Default to current week. + week = defaults(w.w, curWeek.week); -async function isDirectory(path) { - return await statTest(path, stats => stats.isDirectory()); -} -/** - * Test if a path points to a regular file. - * @param path - */ - -async function isFile(path) { - return await statTest(path, stats => stats.isFile()); -} -/** - * Create a symlink at dest that points to src. Adapted from - * https://github.com/lerna/lerna/blob/2f1b87d9e2295f587e4ac74269f714271d8ed428/src/FileSystemUtilities.js#L103. - * - * @param src - * @param dest - * @param type 'dir', 'file', 'junction', or 'exec'. 'exec' on - * windows will use the `cmd-shim` module since symlinks can't be used - * for executable files on windows. - */ - -async function createSymlink(src, dest, type) { - if (process.platform === 'win32') { - if (type === 'exec') { - await cmdShim(src, dest); - } else { - await forceCreate(src, dest, type); + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < 0 || weekday > 6) { + weekdayOverflow = true; + } + } else if (w.e != null) { + // local weekday -- counting starts from beginning of week + weekday = w.e + dow; + if (w.e < 0 || w.e > 6) { + weekdayOverflow = true; + } + } else { + // default to beginning of week + weekday = dow; + } + } + if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { + getParsingFlags(config)._overflowWeeks = true; + } else if (weekdayOverflow != null) { + getParsingFlags(config)._overflowWeekday = true; + } else { + temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } } - } else { - const posixType = type === 'exec' ? 'file' : type; - const relativeSource = Object(path__WEBPACK_IMPORTED_MODULE_3__["relative"])(Object(path__WEBPACK_IMPORTED_MODULE_3__["dirname"])(dest), src); - await forceCreate(relativeSource, dest, posixType); - } -} -async function forceCreate(src, dest, type) { - try { - // If something exists at `dest` we need to remove it first. - await unlink(dest); - } catch (error) { - if (error.code !== 'ENOENT') { - throw error; - } - } + // iso 8601 regex + // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) + var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; + var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; - await symlink(src, dest, type); -} + var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; -/***/ }), -/* 21 */ -/***/ (function(module, exports, __webpack_require__) { + var isoDates = [ + ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], + ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], + ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], + ['GGGG-[W]WW', /\d{4}-W\d\d/, false], + ['YYYY-DDD', /\d{4}-\d{3}/], + ['YYYY-MM', /\d{4}-\d\d/, false], + ['YYYYYYMMDD', /[+-]\d{10}/], + ['YYYYMMDD', /\d{8}/], + // YYYYMM is NOT allowed by the standard + ['GGGG[W]WWE', /\d{4}W\d{3}/], + ['GGGG[W]WW', /\d{4}W\d{2}/, false], + ['YYYYDDD', /\d{7}/] + ]; -// On windows, create a .cmd file. -// Read the #! in the file to see what it uses. The vast majority -// of the time, this will be either: -// "#!/usr/bin/env " -// or: -// "#! " -// -// Write a binroot/pkg.bin + ".cmd" file that has this line in it: -// @ %~dp0 %* + // iso time formats and regexes + var isoTimes = [ + ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], + ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], + ['HH:mm:ss', /\d\d:\d\d:\d\d/], + ['HH:mm', /\d\d:\d\d/], + ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], + ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], + ['HHmmss', /\d\d\d\d\d\d/], + ['HHmm', /\d\d\d\d/], + ['HH', /\d\d/] + ]; -module.exports = cmdShim -cmdShim.ifExists = cmdShimIfExists + var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; -var fs = __webpack_require__(22) + // date from iso format + function configFromISO(config) { + var i, l, + string = config._i, + match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), + allowTime, dateFormat, timeFormat, tzFormat; -var mkdir = __webpack_require__(31) - , path = __webpack_require__(16) - , toBatchSyntax = __webpack_require__(32) - , shebangExpr = /^#\!\s*(?:\/usr\/bin\/env)?\s*([^ \t]+=[^ \t]+\s+)*\s*([^ \t]+)(.*)$/ + if (match) { + getParsingFlags(config).iso = true; -function cmdShimIfExists (from, to, cb) { - fs.stat(from, function (er) { - if (er) return cb() - cmdShim(from, to, cb) - }) -} + for (i = 0, l = isoDates.length; i < l; i++) { + if (isoDates[i][1].exec(match[1])) { + dateFormat = isoDates[i][0]; + allowTime = isoDates[i][2] !== false; + break; + } + } + if (dateFormat == null) { + config._isValid = false; + return; + } + if (match[3]) { + for (i = 0, l = isoTimes.length; i < l; i++) { + if (isoTimes[i][1].exec(match[3])) { + // match[2] should be 'T' or space + timeFormat = (match[2] || ' ') + isoTimes[i][0]; + break; + } + } + if (timeFormat == null) { + config._isValid = false; + return; + } + } + if (!allowTime && timeFormat != null) { + config._isValid = false; + return; + } + if (match[4]) { + if (tzRegex.exec(match[4])) { + tzFormat = 'Z'; + } else { + config._isValid = false; + return; + } + } + config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); + configFromStringAndFormat(config); + } else { + config._isValid = false; + } + } -// Try to unlink, but ignore errors. -// Any problems will surface later. -function rm (path, cb) { - fs.unlink(path, function(er) { - cb() - }) -} + // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 + var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; -function cmdShim (from, to, cb) { - fs.stat(from, function (er, stat) { - if (er) - return cb(er) + function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { + var result = [ + untruncateYear(yearStr), + defaultLocaleMonthsShort.indexOf(monthStr), + parseInt(dayStr, 10), + parseInt(hourStr, 10), + parseInt(minuteStr, 10) + ]; - cmdShim_(from, to, cb) - }) -} + if (secondStr) { + result.push(parseInt(secondStr, 10)); + } -function cmdShim_ (from, to, cb) { - var then = times(2, next, cb) - rm(to, then) - rm(to + ".cmd", then) + return result; + } - function next(er) { - writeShim(from, to, cb) - } -} + function untruncateYear(yearStr) { + var year = parseInt(yearStr, 10); + if (year <= 49) { + return 2000 + year; + } else if (year <= 999) { + return 1900 + year; + } + return year; + } -function writeShim (from, to, cb) { - // make a cmd file and a sh script - // First, check if the bin is a #! of some sort. - // If not, then assume it's something that'll be compiled, or some other - // sort of script, and just call it directly. - mkdir(path.dirname(to), function (er) { - if (er) - return cb(er) - fs.readFile(from, "utf8", function (er, data) { - if (er) return writeShim_(from, to, null, null, cb) - var firstLine = data.trim().split(/\r*\n/)[0] - , shebang = firstLine.match(shebangExpr) - if (!shebang) return writeShim_(from, to, null, null, null, cb) - var vars = shebang[1] || "" - , prog = shebang[2] - , args = shebang[3] || "" - return writeShim_(from, to, prog, args, vars, cb) - }) - }) -} + function preprocessRFC2822(s) { + // Remove comments and folding whitespace and replace multiple-spaces with a single space + return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + } + + function checkWeekday(weekdayStr, parsedInput, config) { + if (weekdayStr) { + // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. + var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), + weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); + if (weekdayProvided !== weekdayActual) { + getParsingFlags(config).weekdayMismatch = true; + config._isValid = false; + return false; + } + } + return true; + } + var obsOffsets = { + UT: 0, + GMT: 0, + EDT: -4 * 60, + EST: -5 * 60, + CDT: -5 * 60, + CST: -6 * 60, + MDT: -6 * 60, + MST: -7 * 60, + PDT: -7 * 60, + PST: -8 * 60 + }; -function writeShim_ (from, to, prog, args, variables, cb) { - var shTarget = path.relative(path.dirname(to), from) - , target = shTarget.split("/").join("\\") - , longProg - , shProg = prog && prog.split("\\").join("/") - , shLongProg - , pwshProg = shProg && "\"" + shProg + "$exe\"" - , pwshLongProg - shTarget = shTarget.split("\\").join("/") - args = args || "" - variables = variables || "" - if (!prog) { - prog = "\"%~dp0\\" + target + "\"" - shProg = "\"$basedir/" + shTarget + "\"" - pwshProg = shProg - args = "" - target = "" - shTarget = "" - } else { - longProg = "\"%~dp0\\" + prog + ".exe\"" - shLongProg = "\"$basedir/" + prog + "\"" - pwshLongProg = "\"$basedir/" + prog + "$exe\"" - target = "\"%~dp0\\" + target + "\"" - shTarget = "\"$basedir/" + shTarget + "\"" - } + function calculateOffset(obsOffset, militaryOffset, numOffset) { + if (obsOffset) { + return obsOffsets[obsOffset]; + } else if (militaryOffset) { + // the only allowed military tz is Z + return 0; + } else { + var hm = parseInt(numOffset, 10); + var m = hm % 100, h = (hm - m) / 100; + return h * 60 + m; + } + } - // @SETLOCAL - // - // @IF EXIST "%~dp0\node.exe" ( - // @SET "_prog=%~dp0\node.exe" - // ) ELSE ( - // @SET "_prog=node" - // @SET PATHEXT=%PATHEXT:;.JS;=;% - // ) - // - // "%_prog%" "%~dp0\.\node_modules\npm\bin\npm-cli.js" %* - // @ENDLOCAL - var cmd - if (longProg) { - shLongProg = shLongProg.trim(); - args = args.trim(); - var variableDeclarationsAsBatch = toBatchSyntax.convertToSetCommands(variables) - cmd = "@SETLOCAL\r\n" - + variableDeclarationsAsBatch - + "\r\n" - + "@IF EXIST " + longProg + " (\r\n" - + " @SET \"_prog=" + longProg.replace(/(^")|("$)/g, '') + "\"\r\n" - + ") ELSE (\r\n" - + " @SET \"_prog=" + prog.replace(/(^")|("$)/g, '') + "\"\r\n" - + " @SET PATHEXT=%PATHEXT:;.JS;=;%\r\n" - + ")\r\n" - + "\r\n" - + "\"%_prog%\" " + args + " " + target + " %*\r\n" - + '@ENDLOCAL\r\n' - } else { - cmd = "@" + prog + " " + args + " " + target + " %*\r\n" - } + // date and time from ref 2822 format + function configFromRFC2822(config) { + var match = rfc2822.exec(preprocessRFC2822(config._i)); + if (match) { + var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); + if (!checkWeekday(match[1], parsedArray, config)) { + return; + } - // #!/bin/sh - // basedir=`dirname "$0"` - // - // case `uname` in - // *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;; - // esac - // - // if [ -x "$basedir/node.exe" ]; then - // "$basedir/node.exe" "$basedir/node_modules/npm/bin/npm-cli.js" "$@" - // ret=$? - // else - // node "$basedir/node_modules/npm/bin/npm-cli.js" "$@" - // ret=$? - // fi - // exit $ret + config._a = parsedArray; + config._tzm = calculateOffset(match[8], match[9], match[10]); - var sh = "#!/bin/sh\n" + config._d = createUTCDate.apply(null, config._a); + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); - sh = sh - + "basedir=$(dirname \"$(echo \"$0\" | sed -e 's,\\\\,/,g')\")\n" - + "\n" - + "case `uname` in\n" - + " *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w \"$basedir\"`;;\n" - + "esac\n" - + "\n" + getParsingFlags(config).rfc2822 = true; + } else { + config._isValid = false; + } + } - if (shLongProg) { - sh = sh - + "if [ -x "+shLongProg+" ]; then\n" - + " " + variables + shLongProg + " " + args + " " + shTarget + " \"$@\"\n" - + " ret=$?\n" - + "else \n" - + " " + variables + shProg + " " + args + " " + shTarget + " \"$@\"\n" - + " ret=$?\n" - + "fi\n" - + "exit $ret\n" - } else { - sh = sh - + shProg + " " + args + " " + shTarget + " \"$@\"\n" - + "exit $?\n" - } + // date from iso format or fallback + function configFromString(config) { + var matched = aspNetJsonRegex.exec(config._i); - // #!/usr/bin/env pwsh - // $basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent - // - // $ret=0 - // $exe = "" - // if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { - // # Fix case when both the Windows and Linux builds of Node - // # are installed in the same directory - // $exe = ".exe" - // } - // if (Test-Path "$basedir/node") { - // & "$basedir/node$exe" "$basedir/node_modules/npm/bin/npm-cli.js" $args - // $ret=$LASTEXITCODE - // } else { - // & "node$exe" "$basedir/node_modules/npm/bin/npm-cli.js" $args - // $ret=$LASTEXITCODE - // } - // exit $ret - var pwsh = "#!/usr/bin/env pwsh\n" - + "$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent\n" - + "\n" - + "$exe=\"\"\n" - + "if ($PSVersionTable.PSVersion -lt \"6.0\" -or $IsWindows) {\n" - + " # Fix case when both the Windows and Linux builds of Node\n" - + " # are installed in the same directory\n" - + " $exe=\".exe\"\n" - + "}\n" - if (shLongProg) { - pwsh = pwsh - + "$ret=0\n" - + "if (Test-Path " + pwshLongProg + ") {\n" - + " & " + pwshLongProg + " " + args + " " + shTarget + " $args\n" - + " $ret=$LASTEXITCODE\n" - + "} else {\n" - + " & " + pwshProg + " " + args + " " + shTarget + " $args\n" - + " $ret=$LASTEXITCODE\n" - + "}\n" - + "exit $ret\n" - } else { - pwsh = pwsh - + "& " + pwshProg + " " + args + " " + shTarget + " $args\n" - + "exit $LASTEXITCODE\n" - } + if (matched !== null) { + config._d = new Date(+matched[1]); + return; + } - var then = times(3, next, cb) - fs.writeFile(to + ".ps1", pwsh, "utf8", then) - fs.writeFile(to + ".cmd", cmd, "utf8", then) - fs.writeFile(to, sh, "utf8", then) - function next () { - chmodShim(to, cb) - } -} + configFromISO(config); + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } -function chmodShim (to, cb) { - var then = times(2, cb, cb) - fs.chmod(to, "0755", then) - fs.chmod(to + ".cmd", "0755", then) - fs.chmod(to + ".ps1", "0755", then) -} + configFromRFC2822(config); + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } -function times(n, ok, cb) { - var errState = null - return function(er) { - if (!errState) { - if (er) - cb(errState = er) - else if (--n === 0) - ok() + // Final attempt, use Input Fallback + hooks.createFromInputFallback(config); } - } -} + hooks.createFromInputFallback = deprecate( + 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + + 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + + 'discouraged and will be removed in an upcoming major release. Please refer to ' + + 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', + function (config) { + config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); + } + ); -/***/ }), -/* 22 */ -/***/ (function(module, exports, __webpack_require__) { + // constant that refers to the ISO standard + hooks.ISO_8601 = function () {}; -var fs = __webpack_require__(23) -var polyfills = __webpack_require__(24) -var legacy = __webpack_require__(26) -var clone = __webpack_require__(28) + // constant that refers to the RFC 2822 form + hooks.RFC_2822 = function () {}; -var util = __webpack_require__(29) + // date from string and format string + function configFromStringAndFormat(config) { + // TODO: Move this to another part of the creation flow to prevent circular deps + if (config._f === hooks.ISO_8601) { + configFromISO(config); + return; + } + if (config._f === hooks.RFC_2822) { + configFromRFC2822(config); + return; + } + config._a = []; + getParsingFlags(config).empty = true; -/* istanbul ignore next - node 0.x polyfill */ -var gracefulQueue -var previousSymbol - -/* istanbul ignore else - node 0.x polyfill */ -if (typeof Symbol === 'function' && typeof Symbol.for === 'function') { - gracefulQueue = Symbol.for('graceful-fs.queue') - // This is used in testing by future versions - previousSymbol = Symbol.for('graceful-fs.previous') -} else { - gracefulQueue = '___graceful-fs.queue' - previousSymbol = '___graceful-fs.previous' -} + // This array is used to make a Date, either with `new Date` or `Date.UTC` + var string = '' + config._i, + i, parsedInput, tokens, token, skipped, + stringLength = string.length, + totalParsedInputLength = 0; -function noop () {} + tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; -var debug = noop -if (util.debuglog) - debug = util.debuglog('gfs4') -else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) - debug = function() { - var m = util.format.apply(util, arguments) - m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') - console.error(m) - } + for (i = 0; i < tokens.length; i++) { + token = tokens[i]; + parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; + // console.log('token', token, 'parsedInput', parsedInput, + // 'regex', getParseRegexForToken(token, config)); + if (parsedInput) { + skipped = string.substr(0, string.indexOf(parsedInput)); + if (skipped.length > 0) { + getParsingFlags(config).unusedInput.push(skipped); + } + string = string.slice(string.indexOf(parsedInput) + parsedInput.length); + totalParsedInputLength += parsedInput.length; + } + // don't parse if it's not a known token + if (formatTokenFunctions[token]) { + if (parsedInput) { + getParsingFlags(config).empty = false; + } + else { + getParsingFlags(config).unusedTokens.push(token); + } + addTimeToArrayFromToken(token, parsedInput, config); + } + else if (config._strict && !parsedInput) { + getParsingFlags(config).unusedTokens.push(token); + } + } -// Once time initialization -if (!global[gracefulQueue]) { - // This queue can be shared by multiple loaded instances - var queue = [] - Object.defineProperty(global, gracefulQueue, { - get: function() { - return queue - } - }) + // add remaining unparsed input length to the string + getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; + if (string.length > 0) { + getParsingFlags(config).unusedInput.push(string); + } - // Patch fs.close/closeSync to shared queue version, because we need - // to retry() whenever a close happens *anywhere* in the program. - // This is essential when multiple graceful-fs instances are - // in play at the same time. - fs.close = (function (fs$close) { - function close (fd, cb) { - return fs$close.call(fs, fd, function (err) { - // This function uses the graceful-fs shared queue - if (!err) { - retry() + // clear _12h flag if hour is <= 12 + if (config._a[HOUR] <= 12 && + getParsingFlags(config).bigHour === true && + config._a[HOUR] > 0) { + getParsingFlags(config).bigHour = undefined; } - if (typeof cb === 'function') - cb.apply(this, arguments) - }) + getParsingFlags(config).parsedDateParts = config._a.slice(0); + getParsingFlags(config).meridiem = config._meridiem; + // handle meridiem + config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); + + configFromArray(config); + checkOverflow(config); } - Object.defineProperty(close, previousSymbol, { - value: fs$close - }) - return close - })(fs.close) - fs.closeSync = (function (fs$closeSync) { - function closeSync (fd) { - // This function uses the graceful-fs shared queue - fs$closeSync.apply(fs, arguments) - retry() + function meridiemFixWrap (locale, hour, meridiem) { + var isPm; + + if (meridiem == null) { + // nothing to do + return hour; + } + if (locale.meridiemHour != null) { + return locale.meridiemHour(hour, meridiem); + } else if (locale.isPM != null) { + // Fallback + isPm = locale.isPM(meridiem); + if (isPm && hour < 12) { + hour += 12; + } + if (!isPm && hour === 12) { + hour = 0; + } + return hour; + } else { + // this is not supposed to happen + return hour; + } } - Object.defineProperty(closeSync, previousSymbol, { - value: fs$closeSync - }) - return closeSync - })(fs.closeSync) + // date from string and array of format strings + function configFromStringAndArray(config) { + var tempConfig, + bestMoment, - if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { - process.on('exit', function() { - debug(global[gracefulQueue]) - __webpack_require__(30).equal(global[gracefulQueue].length, 0) - }) - } -} + scoreToBeat, + i, + currentScore; -module.exports = patch(clone(fs)) -if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) { - module.exports = patch(fs) - fs.__patched = true; -} + if (config._f.length === 0) { + getParsingFlags(config).invalidFormat = true; + config._d = new Date(NaN); + return; + } -function patch (fs) { - // Everything that references the open() function needs to be in here - polyfills(fs) - fs.gracefulify = patch + for (i = 0; i < config._f.length; i++) { + currentScore = 0; + tempConfig = copyConfig({}, config); + if (config._useUTC != null) { + tempConfig._useUTC = config._useUTC; + } + tempConfig._f = config._f[i]; + configFromStringAndFormat(tempConfig); - fs.createReadStream = createReadStream - fs.createWriteStream = createWriteStream - var fs$readFile = fs.readFile - fs.readFile = readFile - function readFile (path, options, cb) { - if (typeof options === 'function') - cb = options, options = null + if (!isValid(tempConfig)) { + continue; + } - return go$readFile(path, options, cb) + // if there is any input that was not parsed add a penalty for that format + currentScore += getParsingFlags(tempConfig).charsLeftOver; - function go$readFile (path, options, cb) { - return fs$readFile(path, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$readFile, [path, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() + //or tokens + currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; + + getParsingFlags(tempConfig).score = currentScore; + + if (scoreToBeat == null || currentScore < scoreToBeat) { + scoreToBeat = currentScore; + bestMoment = tempConfig; + } } - }) + + extend(config, bestMoment || tempConfig); } - } - var fs$writeFile = fs.writeFile - fs.writeFile = writeFile - function writeFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null + function configFromObject(config) { + if (config._d) { + return; + } - return go$writeFile(path, data, options, cb) + var i = normalizeObjectUnits(config._i); + config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { + return obj && parseInt(obj, 10); + }); - function go$writeFile (path, data, options, cb) { - return fs$writeFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$writeFile, [path, data, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() + configFromArray(config); + } + + function createFromConfig (config) { + var res = new Moment(checkOverflow(prepareConfig(config))); + if (res._nextDay) { + // Adding is smart enough around DST + res.add(1, 'd'); + res._nextDay = undefined; } - }) + + return res; } - } - var fs$appendFile = fs.appendFile - if (fs$appendFile) - fs.appendFile = appendFile - function appendFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null + function prepareConfig (config) { + var input = config._i, + format = config._f; - return go$appendFile(path, data, options, cb) + config._locale = config._locale || getLocale(config._l); - function go$appendFile (path, data, options, cb) { - return fs$appendFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$appendFile, [path, data, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() + if (input === null || (format === undefined && input === '')) { + return createInvalid({nullInput: true}); } - }) - } - } - - var fs$readdir = fs.readdir - fs.readdir = readdir - function readdir (path, options, cb) { - var args = [path] - if (typeof options !== 'function') { - args.push(options) - } else { - cb = options - } - args.push(go$readdir$cb) - return go$readdir(args) + if (typeof input === 'string') { + config._i = input = config._locale.preparse(input); + } - function go$readdir$cb (err, files) { - if (files && files.sort) - files.sort() + if (isMoment(input)) { + return new Moment(checkOverflow(input)); + } else if (isDate(input)) { + config._d = input; + } else if (isArray(format)) { + configFromStringAndArray(config); + } else if (format) { + configFromStringAndFormat(config); + } else { + configFromInput(config); + } - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$readdir, [args]]) + if (!isValid(config)) { + config._d = null; + } - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } + return config; } - } - function go$readdir (args) { - return fs$readdir.apply(fs, args) - } + function configFromInput(config) { + var input = config._i; + if (isUndefined(input)) { + config._d = new Date(hooks.now()); + } else if (isDate(input)) { + config._d = new Date(input.valueOf()); + } else if (typeof input === 'string') { + configFromString(config); + } else if (isArray(input)) { + config._a = map(input.slice(0), function (obj) { + return parseInt(obj, 10); + }); + configFromArray(config); + } else if (isObject(input)) { + configFromObject(config); + } else if (isNumber(input)) { + // from milliseconds + config._d = new Date(input); + } else { + hooks.createFromInputFallback(config); + } + } - if (process.version.substr(0, 4) === 'v0.8') { - var legStreams = legacy(fs) - ReadStream = legStreams.ReadStream - WriteStream = legStreams.WriteStream - } + function createLocalOrUTC (input, format, locale, strict, isUTC) { + var c = {}; - var fs$ReadStream = fs.ReadStream - if (fs$ReadStream) { - ReadStream.prototype = Object.create(fs$ReadStream.prototype) - ReadStream.prototype.open = ReadStream$open - } + if (locale === true || locale === false) { + strict = locale; + locale = undefined; + } - var fs$WriteStream = fs.WriteStream - if (fs$WriteStream) { - WriteStream.prototype = Object.create(fs$WriteStream.prototype) - WriteStream.prototype.open = WriteStream$open - } + if ((isObject(input) && isObjectEmpty(input)) || + (isArray(input) && input.length === 0)) { + input = undefined; + } + // object construction must be done this way. + // https://github.com/moment/moment/issues/1423 + c._isAMomentObject = true; + c._useUTC = c._isUTC = isUTC; + c._l = locale; + c._i = input; + c._f = format; + c._strict = strict; - Object.defineProperty(fs, 'ReadStream', { - get: function () { - return ReadStream - }, - set: function (val) { - ReadStream = val - }, - enumerable: true, - configurable: true - }) - Object.defineProperty(fs, 'WriteStream', { - get: function () { - return WriteStream - }, - set: function (val) { - WriteStream = val - }, - enumerable: true, - configurable: true - }) + return createFromConfig(c); + } - // legacy names - var FileReadStream = ReadStream - Object.defineProperty(fs, 'FileReadStream', { - get: function () { - return FileReadStream - }, - set: function (val) { - FileReadStream = val - }, - enumerable: true, - configurable: true - }) - var FileWriteStream = WriteStream - Object.defineProperty(fs, 'FileWriteStream', { - get: function () { - return FileWriteStream - }, - set: function (val) { - FileWriteStream = val - }, - enumerable: true, - configurable: true - }) + function createLocal (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, false); + } - function ReadStream (path, options) { - if (this instanceof ReadStream) - return fs$ReadStream.apply(this, arguments), this - else - return ReadStream.apply(Object.create(ReadStream.prototype), arguments) - } + var prototypeMin = deprecate( + 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', + function () { + var other = createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other < this ? this : other; + } else { + return createInvalid(); + } + } + ); - function ReadStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - if (that.autoClose) - that.destroy() + var prototypeMax = deprecate( + 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', + function () { + var other = createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other > this ? this : other; + } else { + return createInvalid(); + } + } + ); - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - that.read() - } - }) - } + // Pick a moment m from moments so that m[fn](other) is true for all + // other. This relies on the function fn to be transitive. + // + // moments should either be an array of moment objects or an array, whose + // first element is an array of moment objects. + function pickBy(fn, moments) { + var res, i; + if (moments.length === 1 && isArray(moments[0])) { + moments = moments[0]; + } + if (!moments.length) { + return createLocal(); + } + res = moments[0]; + for (i = 1; i < moments.length; ++i) { + if (!moments[i].isValid() || moments[i][fn](res)) { + res = moments[i]; + } + } + return res; + } - function WriteStream (path, options) { - if (this instanceof WriteStream) - return fs$WriteStream.apply(this, arguments), this - else - return WriteStream.apply(Object.create(WriteStream.prototype), arguments) - } + // TODO: Use [].sort instead? + function min () { + var args = [].slice.call(arguments, 0); - function WriteStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - that.destroy() - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - } - }) - } + return pickBy('isBefore', args); + } - function createReadStream (path, options) { - return new fs.ReadStream(path, options) - } + function max () { + var args = [].slice.call(arguments, 0); - function createWriteStream (path, options) { - return new fs.WriteStream(path, options) - } + return pickBy('isAfter', args); + } - var fs$open = fs.open - fs.open = open - function open (path, flags, mode, cb) { - if (typeof mode === 'function') - cb = mode, mode = null + var now = function () { + return Date.now ? Date.now() : +(new Date()); + }; - return go$open(path, flags, mode, cb) + var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; - function go$open (path, flags, mode, cb) { - return fs$open(path, flags, mode, function (err, fd) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$open, [path, flags, mode, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() + function isDurationValid(m) { + for (var key in m) { + if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { + return false; + } } - }) - } - } - return fs -} + var unitHasDecimal = false; + for (var i = 0; i < ordering.length; ++i) { + if (m[ordering[i]]) { + if (unitHasDecimal) { + return false; // only allow non-integers for smallest unit + } + if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { + unitHasDecimal = true; + } + } + } -function enqueue (elem) { - debug('ENQUEUE', elem[0].name, elem[1]) - global[gracefulQueue].push(elem) -} + return true; + } -function retry () { - var elem = global[gracefulQueue].shift() - if (elem) { - debug('RETRY', elem[0].name, elem[1]) - elem[0].apply(null, elem[1]) - } -} + function isValid$1() { + return this._isValid; + } + function createInvalid$1() { + return createDuration(NaN); + } -/***/ }), -/* 23 */ -/***/ (function(module, exports) { + function Duration (duration) { + var normalizedInput = normalizeObjectUnits(duration), + years = normalizedInput.year || 0, + quarters = normalizedInput.quarter || 0, + months = normalizedInput.month || 0, + weeks = normalizedInput.week || normalizedInput.isoWeek || 0, + days = normalizedInput.day || 0, + hours = normalizedInput.hour || 0, + minutes = normalizedInput.minute || 0, + seconds = normalizedInput.second || 0, + milliseconds = normalizedInput.millisecond || 0; -module.exports = require("fs"); + this._isValid = isDurationValid(normalizedInput); -/***/ }), -/* 24 */ -/***/ (function(module, exports, __webpack_require__) { + // representation for dateAddRemove + this._milliseconds = +milliseconds + + seconds * 1e3 + // 1000 + minutes * 6e4 + // 1000 * 60 + hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 + // Because of dateAddRemove treats 24 hours as different from a + // day when working around DST, we need to store them separately + this._days = +days + + weeks * 7; + // It is impossible to translate months into days without knowing + // which months you are are talking about, so we have to store + // it separately. + this._months = +months + + quarters * 3 + + years * 12; -var constants = __webpack_require__(25) + this._data = {}; -var origCwd = process.cwd -var cwd = null + this._locale = getLocale(); -var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform + this._bubble(); + } -process.cwd = function() { - if (!cwd) - cwd = origCwd.call(process) - return cwd -} -try { - process.cwd() -} catch (er) {} + function isDuration (obj) { + return obj instanceof Duration; + } -var chdir = process.chdir -process.chdir = function(d) { - cwd = null - chdir.call(process, d) -} + function absRound (number) { + if (number < 0) { + return Math.round(-1 * number) * -1; + } else { + return Math.round(number); + } + } -module.exports = patch + // FORMATTING -function patch (fs) { - // (re-)implement some things that are known busted or missing. + function offset (token, separator) { + addFormatToken(token, 0, 0, function () { + var offset = this.utcOffset(); + var sign = '+'; + if (offset < 0) { + offset = -offset; + sign = '-'; + } + return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); + }); + } - // lchmod, broken prior to 0.6.2 - // back-port the fix here. - if (constants.hasOwnProperty('O_SYMLINK') && - process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { - patchLchmod(fs) - } + offset('Z', ':'); + offset('ZZ', ''); - // lutimes implementation, or no-op - if (!fs.lutimes) { - patchLutimes(fs) - } + // PARSING - // https://github.com/isaacs/node-graceful-fs/issues/4 - // Chown should not fail on einval or eperm if non-root. - // It should not fail on enosys ever, as this just indicates - // that a fs doesn't support the intended operation. + addRegexToken('Z', matchShortOffset); + addRegexToken('ZZ', matchShortOffset); + addParseToken(['Z', 'ZZ'], function (input, array, config) { + config._useUTC = true; + config._tzm = offsetFromString(matchShortOffset, input); + }); - fs.chown = chownFix(fs.chown) - fs.fchown = chownFix(fs.fchown) - fs.lchown = chownFix(fs.lchown) + // HELPERS - fs.chmod = chmodFix(fs.chmod) - fs.fchmod = chmodFix(fs.fchmod) - fs.lchmod = chmodFix(fs.lchmod) + // timezone chunker + // '+10:00' > ['10', '00'] + // '-1530' > ['-15', '30'] + var chunkOffset = /([\+\-]|\d\d)/gi; - fs.chownSync = chownFixSync(fs.chownSync) - fs.fchownSync = chownFixSync(fs.fchownSync) - fs.lchownSync = chownFixSync(fs.lchownSync) + function offsetFromString(matcher, string) { + var matches = (string || '').match(matcher); - fs.chmodSync = chmodFixSync(fs.chmodSync) - fs.fchmodSync = chmodFixSync(fs.fchmodSync) - fs.lchmodSync = chmodFixSync(fs.lchmodSync) + if (matches === null) { + return null; + } - fs.stat = statFix(fs.stat) - fs.fstat = statFix(fs.fstat) - fs.lstat = statFix(fs.lstat) + var chunk = matches[matches.length - 1] || []; + var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; + var minutes = +(parts[1] * 60) + toInt(parts[2]); - fs.statSync = statFixSync(fs.statSync) - fs.fstatSync = statFixSync(fs.fstatSync) - fs.lstatSync = statFixSync(fs.lstatSync) + return minutes === 0 ? + 0 : + parts[0] === '+' ? minutes : -minutes; + } - // if lchmod/lchown do not exist, then make them no-ops - if (!fs.lchmod) { - fs.lchmod = function (path, mode, cb) { - if (cb) process.nextTick(cb) + // Return a moment from input, that is local/utc/zone equivalent to model. + function cloneWithOffset(input, model) { + var res, diff; + if (model._isUTC) { + res = model.clone(); + diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); + // Use low-level api, because this fn is low-level api. + res._d.setTime(res._d.valueOf() + diff); + hooks.updateOffset(res, false); + return res; + } else { + return createLocal(input).local(); + } } - fs.lchmodSync = function () {} - } - if (!fs.lchown) { - fs.lchown = function (path, uid, gid, cb) { - if (cb) process.nextTick(cb) + + function getDateOffset (m) { + // On Firefox.24 Date#getTimezoneOffset returns a floating point. + // https://github.com/moment/moment/pull/1871 + return -Math.round(m._d.getTimezoneOffset() / 15) * 15; } - fs.lchownSync = function () {} - } - // on Windows, A/V software can lock the directory, causing this - // to fail with an EACCES or EPERM if the directory contains newly - // created files. Try again on failure, for up to 60 seconds. + // HOOKS - // Set the timeout this long because some Windows Anti-Virus, such as Parity - // bit9, may lock files for up to a minute, causing npm package install - // failures. Also, take care to yield the scheduler. Windows scheduling gives - // CPU to a busy looping process, which can cause the program causing the lock - // contention to be starved of CPU by node, so the contention doesn't resolve. - if (platform === "win32") { - fs.rename = (function (fs$rename) { return function (from, to, cb) { - var start = Date.now() - var backoff = 0; - fs$rename(from, to, function CB (er) { - if (er - && (er.code === "EACCES" || er.code === "EPERM") - && Date.now() - start < 60000) { - setTimeout(function() { - fs.stat(to, function (stater, st) { - if (stater && stater.code === "ENOENT") - fs$rename(from, to, CB); - else - cb(er) - }) - }, backoff) - if (backoff < 100) - backoff += 10; - return; - } - if (cb) cb(er) - }) - }})(fs.rename) - } + // This function will be called whenever a moment is mutated. + // It is intended to keep the offset in sync with the timezone. + hooks.updateOffset = function () {}; - // if read() returns EAGAIN, then just try it again. - fs.read = (function (fs$read) { - function read (fd, buffer, offset, length, position, callback_) { - var callback - if (callback_ && typeof callback_ === 'function') { - var eagCounter = 0 - callback = function (er, _, __) { - if (er && er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - return fs$read.call(fs, fd, buffer, offset, length, position, callback) - } - callback_.apply(this, arguments) + // MOMENTS + + // keepLocalTime = true means only change the timezone, without + // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> + // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset + // +0200, so we adjust the time as needed, to be valid. + // + // Keeping the time actually adds/subtracts (one hour) + // from the actual represented time. That is why we call updateOffset + // a second time. In case it wants us to change the offset again + // _changeInProgress == true case, then we have to adjust, because + // there is no such time in the given timezone. + function getSetOffset (input, keepLocalTime, keepMinutes) { + var offset = this._offset || 0, + localAdjust; + if (!this.isValid()) { + return input != null ? this : NaN; + } + if (input != null) { + if (typeof input === 'string') { + input = offsetFromString(matchShortOffset, input); + if (input === null) { + return this; + } + } else if (Math.abs(input) < 16 && !keepMinutes) { + input = input * 60; + } + if (!this._isUTC && keepLocalTime) { + localAdjust = getDateOffset(this); + } + this._offset = input; + this._isUTC = true; + if (localAdjust != null) { + this.add(localAdjust, 'm'); + } + if (offset !== input) { + if (!keepLocalTime || this._changeInProgress) { + addSubtract(this, createDuration(input - offset, 'm'), 1, false); + } else if (!this._changeInProgress) { + this._changeInProgress = true; + hooks.updateOffset(this, true); + this._changeInProgress = null; + } + } + return this; + } else { + return this._isUTC ? offset : getDateOffset(this); } - } - return fs$read.call(fs, fd, buffer, offset, length, position, callback) } - // This ensures `util.promisify` works as it does for native `fs.read`. - read.__proto__ = fs$read - return read - })(fs.read) + function getSetZone (input, keepLocalTime) { + if (input != null) { + if (typeof input !== 'string') { + input = -input; + } - fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { - var eagCounter = 0 - while (true) { - try { - return fs$readSync.call(fs, fd, buffer, offset, length, position) - } catch (er) { - if (er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - continue + this.utcOffset(input, keepLocalTime); + + return this; + } else { + return -this.utcOffset(); } - throw er - } } - }})(fs.readSync) - function patchLchmod (fs) { - fs.lchmod = function (path, mode, callback) { - fs.open( path - , constants.O_WRONLY | constants.O_SYMLINK - , mode - , function (err, fd) { - if (err) { - if (callback) callback(err) - return - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function (err) { - fs.close(fd, function(err2) { - if (callback) callback(err || err2) - }) - }) - }) + function setOffsetToUTC (keepLocalTime) { + return this.utcOffset(0, keepLocalTime); } - fs.lchmodSync = function (path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) + function setOffsetToLocal (keepLocalTime) { + if (this._isUTC) { + this.utcOffset(0, keepLocalTime); + this._isUTC = false; - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var threw = true - var ret - try { - ret = fs.fchmodSync(fd, mode) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) + if (keepLocalTime) { + this.subtract(getDateOffset(this), 'm'); + } } - } - return ret + return this; } - } - function patchLutimes (fs) { - if (constants.hasOwnProperty("O_SYMLINK")) { - fs.lutimes = function (path, at, mt, cb) { - fs.open(path, constants.O_SYMLINK, function (er, fd) { - if (er) { - if (cb) cb(er) - return - } - fs.futimes(fd, at, mt, function (er) { - fs.close(fd, function (er2) { - if (cb) cb(er || er2) - }) - }) - }) - } + function setOffsetToParsedOffset () { + if (this._tzm != null) { + this.utcOffset(this._tzm, false, true); + } else if (typeof this._i === 'string') { + var tZone = offsetFromString(matchOffset, this._i); + if (tZone != null) { + this.utcOffset(tZone); + } + else { + this.utcOffset(0, true); + } + } + return this; + } - fs.lutimesSync = function (path, at, mt) { - var fd = fs.openSync(path, constants.O_SYMLINK) - var ret - var threw = true - try { - ret = fs.futimesSync(fd, at, mt) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) - } + function hasAlignedHourOffset (input) { + if (!this.isValid()) { + return false; } - return ret - } + input = input ? createLocal(input).utcOffset() : 0; - } else { - fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } - fs.lutimesSync = function () {} + return (this.utcOffset() - input) % 60 === 0; } - } - function chmodFix (orig) { - if (!orig) return orig - return function (target, mode, cb) { - return orig.call(fs, target, mode, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) + function isDaylightSavingTime () { + return ( + this.utcOffset() > this.clone().month(0).utcOffset() || + this.utcOffset() > this.clone().month(5).utcOffset() + ); } - } - function chmodFixSync (orig) { - if (!orig) return orig - return function (target, mode) { - try { - return orig.call(fs, target, mode) - } catch (er) { - if (!chownErOk(er)) throw er - } + function isDaylightSavingTimeShifted () { + if (!isUndefined(this._isDSTShifted)) { + return this._isDSTShifted; + } + + var c = {}; + + copyConfig(c, this); + c = prepareConfig(c); + + if (c._a) { + var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); + this._isDSTShifted = this.isValid() && + compareArrays(c._a, other.toArray()) > 0; + } else { + this._isDSTShifted = false; + } + + return this._isDSTShifted; } - } + function isLocal () { + return this.isValid() ? !this._isUTC : false; + } - function chownFix (orig) { - if (!orig) return orig - return function (target, uid, gid, cb) { - return orig.call(fs, target, uid, gid, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) + function isUtcOffset () { + return this.isValid() ? this._isUTC : false; } - } - function chownFixSync (orig) { - if (!orig) return orig - return function (target, uid, gid) { - try { - return orig.call(fs, target, uid, gid) - } catch (er) { - if (!chownErOk(er)) throw er - } + function isUtc () { + return this.isValid() ? this._isUTC && this._offset === 0 : false; } - } - function statFix (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target, options, cb) { - if (typeof options === 'function') { - cb = options - options = null - } - function callback (er, stats) { - if (stats) { - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - } - if (cb) cb.apply(this, arguments) - } - return options ? orig.call(fs, target, options, callback) - : orig.call(fs, target, callback) - } - } - - function statFixSync (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target, options) { - var stats = options ? orig.call(fs, target, options) - : orig.call(fs, target) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - return stats; - } - } + // ASP.NET json date format regex + var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; - // ENOSYS means that the fs doesn't support the op. Just ignore - // that, because it doesn't matter. - // - // if there's no getuid, or if getuid() is something other - // than 0, and the error is EINVAL or EPERM, then just ignore - // it. - // - // This specific case is a silent failure in cp, install, tar, - // and most other unix tools that manage permissions. - // - // When running as root, or if other types of errors are - // encountered, then it's strict. - function chownErOk (er) { - if (!er) - return true + // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html + // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere + // and further modified to allow for strings containing both week and day + var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; - if (er.code === "ENOSYS") - return true + function createDuration (input, key) { + var duration = input, + // matching against regexp is expensive, do it on demand + match = null, + sign, + ret, + diffRes; - var nonroot = !process.getuid || process.getuid() !== 0 - if (nonroot) { - if (er.code === "EINVAL" || er.code === "EPERM") - return true - } + if (isDuration(input)) { + duration = { + ms : input._milliseconds, + d : input._days, + M : input._months + }; + } else if (isNumber(input)) { + duration = {}; + if (key) { + duration[key] = input; + } else { + duration.milliseconds = input; + } + } else if (!!(match = aspNetRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : 1; + duration = { + y : 0, + d : toInt(match[DATE]) * sign, + h : toInt(match[HOUR]) * sign, + m : toInt(match[MINUTE]) * sign, + s : toInt(match[SECOND]) * sign, + ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match + }; + } else if (!!(match = isoRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : 1; + duration = { + y : parseIso(match[2], sign), + M : parseIso(match[3], sign), + w : parseIso(match[4], sign), + d : parseIso(match[5], sign), + h : parseIso(match[6], sign), + m : parseIso(match[7], sign), + s : parseIso(match[8], sign) + }; + } else if (duration == null) {// checks for null or undefined + duration = {}; + } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { + diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); - return false - } -} + duration = {}; + duration.ms = diffRes.milliseconds; + duration.M = diffRes.months; + } + ret = new Duration(duration); -/***/ }), -/* 25 */ -/***/ (function(module, exports) { + if (isDuration(input) && hasOwnProp(input, '_locale')) { + ret._locale = input._locale; + } -module.exports = require("constants"); + return ret; + } -/***/ }), -/* 26 */ -/***/ (function(module, exports, __webpack_require__) { + createDuration.fn = Duration.prototype; + createDuration.invalid = createInvalid$1; -var Stream = __webpack_require__(27).Stream + function parseIso (inp, sign) { + // We'd normally use ~~inp for this, but unfortunately it also + // converts floats to ints. + // inp may be undefined, so careful calling replace on it. + var res = inp && parseFloat(inp.replace(',', '.')); + // apply sign while we're at it + return (isNaN(res) ? 0 : res) * sign; + } -module.exports = legacy + function positiveMomentsDifference(base, other) { + var res = {}; -function legacy (fs) { - return { - ReadStream: ReadStream, - WriteStream: WriteStream - } + res.months = other.month() - base.month() + + (other.year() - base.year()) * 12; + if (base.clone().add(res.months, 'M').isAfter(other)) { + --res.months; + } - function ReadStream (path, options) { - if (!(this instanceof ReadStream)) return new ReadStream(path, options); + res.milliseconds = +other - +(base.clone().add(res.months, 'M')); - Stream.call(this); + return res; + } - var self = this; + function momentsDifference(base, other) { + var res; + if (!(base.isValid() && other.isValid())) { + return {milliseconds: 0, months: 0}; + } - this.path = path; - this.fd = null; - this.readable = true; - this.paused = false; + other = cloneWithOffset(other, base); + if (base.isBefore(other)) { + res = positiveMomentsDifference(base, other); + } else { + res = positiveMomentsDifference(other, base); + res.milliseconds = -res.milliseconds; + res.months = -res.months; + } - this.flags = 'r'; - this.mode = 438; /*=0666*/ - this.bufferSize = 64 * 1024; + return res; + } - options = options || {}; + // TODO: remove 'name' arg after deprecation is removed + function createAdder(direction, name) { + return function (val, period) { + var dur, tmp; + //invert the arguments, but complain about it + if (period !== null && !isNaN(+period)) { + deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + + 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); + tmp = val; val = period; period = tmp; + } - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; + val = typeof val === 'string' ? +val : val; + dur = createDuration(val, period); + addSubtract(this, dur, direction); + return this; + }; } - if (this.encoding) this.setEncoding(this.encoding); - - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if ('number' !== typeof this.end) { - throw TypeError('end must be a Number'); - } + function addSubtract (mom, duration, isAdding, updateOffset) { + var milliseconds = duration._milliseconds, + days = absRound(duration._days), + months = absRound(duration._months); - if (this.start > this.end) { - throw new Error('start must be <= end'); - } + if (!mom.isValid()) { + // No op + return; + } - this.pos = this.start; - } + updateOffset = updateOffset == null ? true : updateOffset; - if (this.fd !== null) { - process.nextTick(function() { - self._read(); - }); - return; + if (months) { + setMonth(mom, get(mom, 'Month') + months * isAdding); + } + if (days) { + set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); + } + if (milliseconds) { + mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); + } + if (updateOffset) { + hooks.updateOffset(mom, days || months); + } } - fs.open(this.path, this.flags, this.mode, function (err, fd) { - if (err) { - self.emit('error', err); - self.readable = false; - return; - } + var add = createAdder(1, 'add'); + var subtract = createAdder(-1, 'subtract'); - self.fd = fd; - self.emit('open', fd); - self._read(); - }) - } + function getCalendarFormat(myMoment, now) { + var diff = myMoment.diff(now, 'days', true); + return diff < -6 ? 'sameElse' : + diff < -1 ? 'lastWeek' : + diff < 0 ? 'lastDay' : + diff < 1 ? 'sameDay' : + diff < 2 ? 'nextDay' : + diff < 7 ? 'nextWeek' : 'sameElse'; + } - function WriteStream (path, options) { - if (!(this instanceof WriteStream)) return new WriteStream(path, options); + function calendar$1 (time, formats) { + // We want to compare the start of today, vs this. + // Getting start-of-today depends on whether we're local/utc/offset or not. + var now = time || createLocal(), + sod = cloneWithOffset(now, this).startOf('day'), + format = hooks.calendarFormat(this, sod) || 'sameElse'; - Stream.call(this); + var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); - this.path = path; - this.fd = null; - this.writable = true; + return this.format(output || this.localeData().calendar(format, this, createLocal(now))); + } - this.flags = 'w'; - this.encoding = 'binary'; - this.mode = 438; /*=0666*/ - this.bytesWritten = 0; + function clone () { + return new Moment(this); + } - options = options || {}; + function isAfter (input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(units) || 'millisecond'; + if (units === 'millisecond') { + return this.valueOf() > localInput.valueOf(); + } else { + return localInput.valueOf() < this.clone().startOf(units).valueOf(); + } + } - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; + function isBefore (input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(units) || 'millisecond'; + if (units === 'millisecond') { + return this.valueOf() < localInput.valueOf(); + } else { + return this.clone().endOf(units).valueOf() < localInput.valueOf(); + } } - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } + function isBetween (from, to, units, inclusivity) { + var localFrom = isMoment(from) ? from : createLocal(from), + localTo = isMoment(to) ? to : createLocal(to); + if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) { + return false; + } + inclusivity = inclusivity || '()'; + return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && + (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units)); + } - this.pos = this.start; + function isSame (input, units) { + var localInput = isMoment(input) ? input : createLocal(input), + inputMs; + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(units) || 'millisecond'; + if (units === 'millisecond') { + return this.valueOf() === localInput.valueOf(); + } else { + inputMs = localInput.valueOf(); + return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); + } } - this.busy = false; - this._queue = []; + function isSameOrAfter (input, units) { + return this.isSame(input, units) || this.isAfter(input, units); + } - if (this.fd === null) { - this._open = fs.open; - this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); - this.flush(); + function isSameOrBefore (input, units) { + return this.isSame(input, units) || this.isBefore(input, units); } - } -} + function diff (input, units, asFloat) { + var that, + zoneDelta, + output; -/***/ }), -/* 27 */ -/***/ (function(module, exports) { + if (!this.isValid()) { + return NaN; + } -module.exports = require("stream"); + that = cloneWithOffset(input, this); -/***/ }), -/* 28 */ -/***/ (function(module, exports, __webpack_require__) { + if (!that.isValid()) { + return NaN; + } -"use strict"; + zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; + units = normalizeUnits(units); -module.exports = clone + switch (units) { + case 'year': output = monthDiff(this, that) / 12; break; + case 'month': output = monthDiff(this, that); break; + case 'quarter': output = monthDiff(this, that) / 3; break; + case 'second': output = (this - that) / 1e3; break; // 1000 + case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 + case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 + case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst + case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst + default: output = this - that; + } -function clone (obj) { - if (obj === null || typeof obj !== 'object') - return obj + return asFloat ? output : absFloor(output); + } - if (obj instanceof Object) - var copy = { __proto__: obj.__proto__ } - else - var copy = Object.create(null) + function monthDiff (a, b) { + // difference in months + var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), + // b is in (anchor - 1 month, anchor + 1 month) + anchor = a.clone().add(wholeMonthDiff, 'months'), + anchor2, adjust; - Object.getOwnPropertyNames(obj).forEach(function (key) { - Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) - }) + if (b - anchor < 0) { + anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor - anchor2); + } else { + anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor2 - anchor); + } - return copy -} + //check for negative zero, return zero if negative zero + return -(wholeMonthDiff + adjust) || 0; + } + hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; + hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; -/***/ }), -/* 29 */ -/***/ (function(module, exports) { + function toString () { + return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); + } -module.exports = require("util"); + function toISOString(keepOffset) { + if (!this.isValid()) { + return null; + } + var utc = keepOffset !== true; + var m = utc ? this.clone().utc() : this; + if (m.year() < 0 || m.year() > 9999) { + return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); + } + if (isFunction(Date.prototype.toISOString)) { + // native implementation is ~50x faster, use it when we can + if (utc) { + return this.toDate().toISOString(); + } else { + return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z')); + } + } + return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); + } -/***/ }), -/* 30 */ -/***/ (function(module, exports) { + /** + * Return a human readable representation of a moment that can + * also be evaluated to get a new moment which is the same + * + * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects + */ + function inspect () { + if (!this.isValid()) { + return 'moment.invalid(/* ' + this._i + ' */)'; + } + var func = 'moment'; + var zone = ''; + if (!this.isLocal()) { + func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; + zone = 'Z'; + } + var prefix = '[' + func + '("]'; + var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; + var datetime = '-MM-DD[T]HH:mm:ss.SSS'; + var suffix = zone + '[")]'; -module.exports = require("assert"); + return this.format(prefix + year + datetime + suffix); + } -/***/ }), -/* 31 */ -/***/ (function(module, exports, __webpack_require__) { + function format (inputString) { + if (!inputString) { + inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; + } + var output = formatMoment(this, inputString); + return this.localeData().postformat(output); + } -var path = __webpack_require__(16); -var fs = __webpack_require__(23); -var _0777 = parseInt('0777', 8); + function from (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + createLocal(time).isValid())) { + return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } + } -module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; + function fromNow (withoutSuffix) { + return this.from(createLocal(), withoutSuffix); + } -function mkdirP (p, opts, f, made) { - if (typeof opts === 'function') { - f = opts; - opts = {}; + function to (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + createLocal(time).isValid())) { + return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } } - else if (!opts || typeof opts !== 'object') { - opts = { mode: opts }; + + function toNow (withoutSuffix) { + return this.to(createLocal(), withoutSuffix); } - - var mode = opts.mode; - var xfs = opts.fs || fs; - - if (mode === undefined) { - mode = _0777 & (~process.umask()); - } - if (!made) made = null; - - var cb = f || function () {}; - p = path.resolve(p); - - xfs.mkdir(p, mode, function (er) { - if (!er) { - made = made || p; - return cb(null, made); + + // If passed a locale key, it will set the locale for this + // instance. Otherwise, it will return the locale configuration + // variables for this instance. + function locale (key) { + var newLocaleData; + + if (key === undefined) { + return this._locale._abbr; + } else { + newLocaleData = getLocale(key); + if (newLocaleData != null) { + this._locale = newLocaleData; + } + return this; } - switch (er.code) { - case 'ENOENT': - if (path.dirname(p) === p) return cb(er); - mkdirP(path.dirname(p), opts, function (er, made) { - if (er) cb(er, made); - else mkdirP(p, opts, cb, made); - }); - break; + } - // In the case of any other error, just see if there's a dir - // there already. If so, then hooray! If not, then something - // is borked. - default: - xfs.stat(p, function (er2, stat) { - // if the stat fails, then that's super weird. - // let the original error be the failure reason. - if (er2 || !stat.isDirectory()) cb(er, made) - else cb(null, made); - }); - break; + var lang = deprecate( + 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', + function (key) { + if (key === undefined) { + return this.localeData(); + } else { + return this.locale(key); + } } - }); -} + ); -mkdirP.sync = function sync (p, opts, made) { - if (!opts || typeof opts !== 'object') { - opts = { mode: opts }; + function localeData () { + return this._locale; } - - var mode = opts.mode; - var xfs = opts.fs || fs; - - if (mode === undefined) { - mode = _0777 & (~process.umask()); + + var MS_PER_SECOND = 1000; + var MS_PER_MINUTE = 60 * MS_PER_SECOND; + var MS_PER_HOUR = 60 * MS_PER_MINUTE; + var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; + + // actual modulo - handles negative numbers (for dates before 1970): + function mod$1(dividend, divisor) { + return (dividend % divisor + divisor) % divisor; } - if (!made) made = null; - p = path.resolve(p); + function localStartOfDate(y, m, d) { + // the date constructor remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0) { + // preserve leap years using a full 400 year cycle, then reset + return new Date(y + 400, m, d) - MS_PER_400_YEARS; + } else { + return new Date(y, m, d).valueOf(); + } + } - try { - xfs.mkdirSync(p, mode); - made = made || p; + function utcStartOfDate(y, m, d) { + // Date.UTC remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0) { + // preserve leap years using a full 400 year cycle, then reset + return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS; + } else { + return Date.UTC(y, m, d); + } } - catch (err0) { - switch (err0.code) { - case 'ENOENT' : - made = sync(path.dirname(p), opts, made); - sync(p, opts, made); - break; - // In the case of any other error, just see if there's a dir - // there already. If so, then hooray! If not, then something - // is borked. - default: - var stat; - try { - stat = xfs.statSync(p); - } - catch (err1) { - throw err0; - } - if (!stat.isDirectory()) throw err0; + function startOf (units) { + var time; + units = normalizeUnits(units); + if (units === undefined || units === 'millisecond' || !this.isValid()) { + return this; + } + + var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; + + switch (units) { + case 'year': + time = startOfDate(this.year(), 0, 1); + break; + case 'quarter': + time = startOfDate(this.year(), this.month() - this.month() % 3, 1); + break; + case 'month': + time = startOfDate(this.year(), this.month(), 1); + break; + case 'week': + time = startOfDate(this.year(), this.month(), this.date() - this.weekday()); + break; + case 'isoWeek': + time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1)); + break; + case 'day': + case 'date': + time = startOfDate(this.year(), this.month(), this.date()); + break; + case 'hour': + time = this._d.valueOf(); + time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR); + break; + case 'minute': + time = this._d.valueOf(); + time -= mod$1(time, MS_PER_MINUTE); + break; + case 'second': + time = this._d.valueOf(); + time -= mod$1(time, MS_PER_SECOND); break; } + + this._d.setTime(time); + hooks.updateOffset(this, true); + return this; } - return made; -}; + function endOf (units) { + var time; + units = normalizeUnits(units); + if (units === undefined || units === 'millisecond' || !this.isValid()) { + return this; + } + var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; -/***/ }), -/* 32 */ -/***/ (function(module, exports) { + switch (units) { + case 'year': + time = startOfDate(this.year() + 1, 0, 1) - 1; + break; + case 'quarter': + time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1; + break; + case 'month': + time = startOfDate(this.year(), this.month() + 1, 1) - 1; + break; + case 'week': + time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1; + break; + case 'isoWeek': + time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1; + break; + case 'day': + case 'date': + time = startOfDate(this.year(), this.month(), this.date() + 1) - 1; + break; + case 'hour': + time = this._d.valueOf(); + time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1; + break; + case 'minute': + time = this._d.valueOf(); + time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1; + break; + case 'second': + time = this._d.valueOf(); + time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1; + break; + } -exports.replaceDollarWithPercentPair = replaceDollarWithPercentPair -exports.convertToSetCommand = convertToSetCommand -exports.convertToSetCommands = convertToSetCommands - -function convertToSetCommand(key, value) { - var line = "" - key = key || "" - key = key.trim() - value = value || "" - value = value.trim() - if(key && value && value.length > 0) { - line = "@SET " + key + "=" + replaceDollarWithPercentPair(value) + "\r\n" - } - return line -} - -function extractVariableValuePairs(declarations) { - var pairs = {} - declarations.map(function(declaration) { - var split = declaration.split("=") - pairs[split[0]]=split[1] - }) - return pairs -} - -function convertToSetCommands(variableString) { - var variableValuePairs = extractVariableValuePairs(variableString.split(" ")) - var variableDeclarationsAsBatch = "" - Object.keys(variableValuePairs).forEach(function (key) { - variableDeclarationsAsBatch += convertToSetCommand(key, variableValuePairs[key]) - }) - return variableDeclarationsAsBatch -} - -function replaceDollarWithPercentPair(value) { - var dollarExpressions = /\$\{?([^\$@#\?\- \t{}:]+)\}?/g - var result = "" - var startIndex = 0 - value = value || "" - do { - var match = dollarExpressions.exec(value) - if(match) { - var betweenMatches = value.substring(startIndex, match.index) || "" - result += betweenMatches + "%" + match[1] + "%" - startIndex = dollarExpressions.lastIndex - } - } while (dollarExpressions.lastIndex > 0) - result += value.substr(startIndex) - return result -} - - + this._d.setTime(time); + hooks.updateOffset(this, true); + return this; + } + function valueOf () { + return this._d.valueOf() - ((this._offset || 0) * 60000); + } -/***/ }), -/* 33 */ -/***/ (function(module, exports, __webpack_require__) { + function unix () { + return Math.floor(this.valueOf() / 1000); + } -var fs = __webpack_require__(23), - path = __webpack_require__(16); + function toDate () { + return new Date(this.valueOf()); + } -module.exports = ncp; -ncp.ncp = ncp; + function toArray () { + var m = this; + return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; + } -function ncp (source, dest, options, callback) { - var cback = callback; + function toObject () { + var m = this; + return { + years: m.year(), + months: m.month(), + date: m.date(), + hours: m.hours(), + minutes: m.minutes(), + seconds: m.seconds(), + milliseconds: m.milliseconds() + }; + } - if (!callback) { - cback = options; - options = {}; - } + function toJSON () { + // new Date(NaN).toJSON() === null + return this.isValid() ? this.toISOString() : null; + } - var basePath = process.cwd(), - currentPath = path.resolve(basePath, source), - targetPath = path.resolve(basePath, dest), - filter = options.filter, - rename = options.rename, - transform = options.transform, - clobber = options.clobber !== false, - modified = options.modified, - dereference = options.dereference, - errs = null, - started = 0, - finished = 0, - running = 0, - limit = options.limit || ncp.limit || 16; + function isValid$2 () { + return isValid(this); + } - limit = (limit < 1) ? 1 : (limit > 512) ? 512 : limit; + function parsingFlags () { + return extend({}, getParsingFlags(this)); + } - startCopy(currentPath); - - function startCopy(source) { - started++; - if (filter) { - if (filter instanceof RegExp) { - if (!filter.test(source)) { - return cb(true); - } - } - else if (typeof filter === 'function') { - if (!filter(source)) { - return cb(true); - } - } + function invalidAt () { + return getParsingFlags(this).overflow; } - return getStats(source); - } - function getStats(source) { - var stat = dereference ? fs.stat : fs.lstat; - if (running >= limit) { - return setImmediate(function () { - getStats(source); - }); + function creationData() { + return { + input: this._i, + format: this._f, + locale: this._locale, + isUTC: this._isUTC, + strict: this._strict + }; } - running++; - stat(source, function (err, stats) { - var item = {}; - if (err) { - return onError(err); - } - // We need to get the mode from the stats object and preserve it. - item.name = source; - item.mode = stats.mode; - item.mtime = stats.mtime; //modified time - item.atime = stats.atime; //access time + // FORMATTING - if (stats.isDirectory()) { - return onDir(item); - } - else if (stats.isFile()) { - return onFile(item); - } - else if (stats.isSymbolicLink()) { - // Symlinks don't really need to know about the mode. - return onLink(source); - } + addFormatToken(0, ['gg', 2], 0, function () { + return this.weekYear() % 100; }); - } - function onFile(file) { - var target = file.name.replace(currentPath, targetPath); - if(rename) { - target = rename(target); - } - isWritable(target, function (writable) { - if (writable) { - return copyFile(file, target); - } - if(clobber) { - rmFile(target, function () { - copyFile(file, target); - }); - } - if (modified) { - var stat = dereference ? fs.stat : fs.lstat; - stat(target, function(err, stats) { - //if souce modified time greater to target modified time copy file - if (file.mtime.getTime()>stats.mtime.getTime()) - copyFile(file, target); - else return cb(); - }); - } - else { - return cb(); - } + addFormatToken(0, ['GG', 2], 0, function () { + return this.isoWeekYear() % 100; }); - } - function copyFile(file, target) { - var readStream = fs.createReadStream(file.name), - writeStream = fs.createWriteStream(target, { mode: file.mode }); - - readStream.on('error', onError); - writeStream.on('error', onError); - - if(transform) { - transform(readStream, writeStream, file); - } else { - writeStream.on('open', function() { - readStream.pipe(writeStream); - }); + function addWeekYearFormatToken (token, getter) { + addFormatToken(0, [token, token.length], 0, getter); } - writeStream.once('finish', function() { - if (modified) { - //target file modified date sync. - fs.utimesSync(target, file.atime, file.mtime); - cb(); - } - else cb(); - }); - } - function rmFile(file, done) { - fs.unlink(file, function (err) { - if (err) { - return onError(err); - } - return done(); - }); - } + addWeekYearFormatToken('gggg', 'weekYear'); + addWeekYearFormatToken('ggggg', 'weekYear'); + addWeekYearFormatToken('GGGG', 'isoWeekYear'); + addWeekYearFormatToken('GGGGG', 'isoWeekYear'); - function onDir(dir) { - var target = dir.name.replace(currentPath, targetPath); - isWritable(target, function (writable) { - if (writable) { - return mkDir(dir, target); - } - copyDir(dir.name); - }); - } + // ALIASES - function mkDir(dir, target) { - fs.mkdir(target, dir.mode, function (err) { - if (err) { - return onError(err); - } - copyDir(dir.name); - }); - } + addUnitAlias('weekYear', 'gg'); + addUnitAlias('isoWeekYear', 'GG'); - function copyDir(dir) { - fs.readdir(dir, function (err, items) { - if (err) { - return onError(err); - } - items.forEach(function (item) { - startCopy(path.join(dir, item)); - }); - return cb(); + // PRIORITY + + addUnitPriority('weekYear', 1); + addUnitPriority('isoWeekYear', 1); + + + // PARSING + + addRegexToken('G', matchSigned); + addRegexToken('g', matchSigned); + addRegexToken('GG', match1to2, match2); + addRegexToken('gg', match1to2, match2); + addRegexToken('GGGG', match1to4, match4); + addRegexToken('gggg', match1to4, match4); + addRegexToken('GGGGG', match1to6, match6); + addRegexToken('ggggg', match1to6, match6); + + addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { + week[token.substr(0, 2)] = toInt(input); }); - } - function onLink(link) { - var target = link.replace(currentPath, targetPath); - fs.readlink(link, function (err, resolvedPath) { - if (err) { - return onError(err); - } - checkLink(resolvedPath, target); + addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { + week[token] = hooks.parseTwoDigitYear(input); }); - } - function checkLink(resolvedPath, target) { - if (dereference) { - resolvedPath = path.resolve(basePath, resolvedPath); - } - isWritable(target, function (writable) { - if (writable) { - return makeLink(resolvedPath, target); - } - fs.readlink(target, function (err, targetDest) { - if (err) { - return onError(err); - } - if (dereference) { - targetDest = path.resolve(basePath, targetDest); - } - if (targetDest === resolvedPath) { - return cb(); - } - return rmFile(target, function () { - makeLink(resolvedPath, target); - }); - }); - }); - } - - function makeLink(linkPath, target) { - fs.symlink(linkPath, target, function (err) { - if (err) { - return onError(err); - } - return cb(); - }); - } - - function isWritable(path, done) { - fs.lstat(path, function (err) { - if (err) { - if (err.code === 'ENOENT') return done(true); - return done(false); - } - return done(false); - }); - } + // MOMENTS - function onError(err) { - if (options.stopOnError) { - return cback(err); + function getSetWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, + this.week(), + this.weekday(), + this.localeData()._week.dow, + this.localeData()._week.doy); } - else if (!errs && options.errs) { - errs = fs.createWriteStream(options.errs); + + function getSetISOWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, this.isoWeek(), this.isoWeekday(), 1, 4); } - else if (!errs) { - errs = []; + + function getISOWeeksInYear () { + return weeksInYear(this.year(), 1, 4); } - if (typeof errs.write === 'undefined') { - errs.push(err); + + function getWeeksInYear () { + var weekInfo = this.localeData()._week; + return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); } - else { - errs.write(err.stack + '\n\n'); + + function getSetWeekYearHelper(input, week, weekday, dow, doy) { + var weeksTarget; + if (input == null) { + return weekOfYear(this, dow, doy).year; + } else { + weeksTarget = weeksInYear(input, dow, doy); + if (week > weeksTarget) { + week = weeksTarget; + } + return setWeekAll.call(this, input, week, weekday, dow, doy); + } } - return cb(); - } - function cb(skipped) { - if (!skipped) running--; - finished++; - if ((started === finished) && (running === 0)) { - if (cback !== undefined ) { - return errs ? cback(errs) : cback(null); - } + function setWeekAll(weekYear, week, weekday, dow, doy) { + var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), + date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); + + this.year(date.getUTCFullYear()); + this.month(date.getUTCMonth()); + this.date(date.getUTCDate()); + return this; } - } -} + // FORMATTING + addFormatToken('Q', 0, 'Qo', 'quarter'); + // ALIASES -/***/ }), -/* 34 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + addUnitAlias('quarter', 'Q'); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "log", function() { return log; }); -/* harmony import */ var _kbn_dev_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(35); -/* harmony import */ var _kbn_dev_utils__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_kbn_dev_utils__WEBPACK_IMPORTED_MODULE_0__); -function _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; } + // PRIORITY -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + addUnitPriority('quarter', 7); + // PARSING -class Log extends _kbn_dev_utils__WEBPACK_IMPORTED_MODULE_0__["ToolingLog"] { - constructor() { - super({ - level: 'info', - writeTo: process.stdout + addRegexToken('Q', match1); + addParseToken('Q', function (input, array) { + array[MONTH] = (toInt(input) - 1) * 3; }); - _defineProperty(this, "testWriter", void 0); - } - /** - * Log something to the console. Ideally we would use a real logger in - * kbn-pm, but that's a pretty big change for now. - * @param ...args - */ - + // MOMENTS - write(...args) { - // eslint-disable-next-line no-console - console.log(...args); - } + function getSetQuarter (input) { + return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); + } -} + // FORMATTING -const log = new Log(); + addFormatToken('D', ['DD', 2], 'Do', 'date'); -/***/ }), -/* 35 */ -/***/ (function(module, exports, __webpack_require__) { + // ALIASES -"use strict"; + addUnitAlias('date', 'D'); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const tslib_1 = __webpack_require__(36); -var proc_runner_1 = __webpack_require__(37); -exports.withProcRunner = proc_runner_1.withProcRunner; -exports.ProcRunner = proc_runner_1.ProcRunner; -tslib_1.__exportStar(__webpack_require__(414), exports); -var serializers_1 = __webpack_require__(419); -exports.createAbsolutePathSerializer = serializers_1.createAbsolutePathSerializer; -var certs_1 = __webpack_require__(443); -exports.CA_CERT_PATH = certs_1.CA_CERT_PATH; -exports.ES_KEY_PATH = certs_1.ES_KEY_PATH; -exports.ES_CERT_PATH = certs_1.ES_CERT_PATH; -exports.ES_P12_PATH = certs_1.ES_P12_PATH; -exports.ES_P12_PASSWORD = certs_1.ES_P12_PASSWORD; -exports.ES_EMPTYPASSWORD_P12_PATH = certs_1.ES_EMPTYPASSWORD_P12_PATH; -exports.ES_NOPASSWORD_P12_PATH = certs_1.ES_NOPASSWORD_P12_PATH; -exports.KBN_KEY_PATH = certs_1.KBN_KEY_PATH; -exports.KBN_CERT_PATH = certs_1.KBN_CERT_PATH; -exports.KBN_P12_PATH = certs_1.KBN_P12_PATH; -exports.KBN_P12_PASSWORD = certs_1.KBN_P12_PASSWORD; -var run_1 = __webpack_require__(444); -exports.run = run_1.run; -exports.createFailError = run_1.createFailError; -exports.createFlagError = run_1.createFlagError; -exports.combineErrors = run_1.combineErrors; -exports.isFailError = run_1.isFailError; -var repo_root_1 = __webpack_require__(421); -exports.REPO_ROOT = repo_root_1.REPO_ROOT; -var kbn_client_1 = __webpack_require__(449); -exports.KbnClient = kbn_client_1.KbnClient; -tslib_1.__exportStar(__webpack_require__(492), exports); -tslib_1.__exportStar(__webpack_require__(499), exports); + // PRIORITY + addUnitPriority('date', 9); + // PARSING -/***/ }), -/* 36 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + addRegexToken('D', match1to2); + addRegexToken('DD', match1to2, match2); + addRegexToken('Do', function (isStrict, locale) { + // TODO: Remove "ordinalParse" fallback in next major release. + return isStrict ? + (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : + locale._dayOfMonthOrdinalParseLenient; + }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__extends", function() { return __extends; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__assign", function() { return __assign; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__rest", function() { return __rest; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__decorate", function() { return __decorate; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__param", function() { return __param; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__metadata", function() { return __metadata; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__awaiter", function() { return __awaiter; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__generator", function() { return __generator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__exportStar", function() { return __exportStar; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__values", function() { return __values; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__read", function() { return __read; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__spread", function() { return __spread; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__await", function() { return __await; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncGenerator", function() { return __asyncGenerator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncDelegator", function() { return __asyncDelegator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncValues", function() { return __asyncValues; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__makeTemplateObject", function() { return __makeTemplateObject; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importStar", function() { return __importStar; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importDefault", function() { return __importDefault; }); -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at http://www.apache.org/licenses/LICENSE-2.0 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */ -/* global Reflect, Promise */ - -var extendStatics = function(d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); -}; - -function __extends(d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -} - -var __assign = function() { - __assign = Object.assign || function __assign(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; - } - return t; - } - return __assign.apply(this, arguments); -} - -function __rest(s, e) { - var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) - t[p] = s[p]; - if (s != null && typeof Object.getOwnPropertySymbols === "function") - for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) - t[p[i]] = s[p[i]]; - return t; -} - -function __decorate(decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -} - -function __param(paramIndex, decorator) { - return function (target, key) { decorator(target, key, paramIndex); } -} - -function __metadata(metadataKey, metadataValue) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); -} - -function __awaiter(thisArg, _arguments, P, generator) { - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -} - -function __generator(thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -} - -function __exportStar(m, exports) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} - -function __values(o) { - var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; - if (m) return m.call(o); - return { - next: function () { - if (o && i >= o.length) o = void 0; - return { value: o && o[i++], done: !o }; - } - }; -} - -function __read(o, n) { - var m = typeof Symbol === "function" && o[Symbol.iterator]; - if (!m) return o; - var i = m.call(o), r, ar = [], e; - try { - while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); - } - catch (error) { e = { error: error }; } - finally { - try { - if (r && !r.done && (m = i["return"])) m.call(i); - } - finally { if (e) throw e.error; } - } - return ar; -} - -function __spread() { - for (var ar = [], i = 0; i < arguments.length; i++) - ar = ar.concat(__read(arguments[i])); - return ar; -} - -function __await(v) { - return this instanceof __await ? (this.v = v, this) : new __await(v); -} - -function __asyncGenerator(thisArg, _arguments, generator) { - if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); - var g = generator.apply(thisArg, _arguments || []), i, q = []; - return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; - function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } - function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } - function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } - function fulfill(value) { resume("next", value); } - function reject(value) { resume("throw", value); } - function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } -} - -function __asyncDelegator(o) { - var i, p; - return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; - function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } -} - -function __asyncValues(o) { - if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); - var m = o[Symbol.asyncIterator], i; - return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); - function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } - function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } -} - -function __makeTemplateObject(cooked, raw) { - if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } - return cooked; -}; - -function __importStar(mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result.default = mod; - return result; -} - -function __importDefault(mod) { - return (mod && mod.__esModule) ? mod : { default: mod }; -} + addParseToken(['D', 'DD'], DATE); + addParseToken('Do', function (input, array) { + array[DATE] = toInt(input.match(match1to2)[0]); + }); + // MOMENTS -/***/ }), -/* 37 */ -/***/ (function(module, exports, __webpack_require__) { + var getSetDayOfMonth = makeGetSet('Date', true); -"use strict"; + // FORMATTING -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -var with_proc_runner_1 = __webpack_require__(38); -exports.withProcRunner = with_proc_runner_1.withProcRunner; -var proc_runner_1 = __webpack_require__(39); -exports.ProcRunner = proc_runner_1.ProcRunner; + addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); + // ALIASES -/***/ }), -/* 38 */ -/***/ (function(module, exports, __webpack_require__) { + addUnitAlias('dayOfYear', 'DDD'); -"use strict"; + // PRIORITY + addUnitPriority('dayOfYear', 4); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const proc_runner_1 = __webpack_require__(39); -/** - * Create a ProcRunner and pass it to an async function. When - * the async function finishes the ProcRunner is torn-down - * automatically - * - * @param {ToolingLog} log - * @param {async Function} fn - * @return {Promise} - */ -async function withProcRunner(log, fn) { - const procs = new proc_runner_1.ProcRunner(log); - try { - await fn(procs); - } - finally { - await procs.teardown(); - } -} -exports.withProcRunner = withProcRunner; + // PARSING + addRegexToken('DDD', match1to3); + addRegexToken('DDDD', match3); + addParseToken(['DDD', 'DDDD'], function (input, array, config) { + config._dayOfYear = toInt(input); + }); -/***/ }), -/* 39 */ -/***/ (function(module, exports, __webpack_require__) { + // HELPERS -"use strict"; + // MOMENTS -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const tslib_1 = __webpack_require__(36); -const moment_1 = tslib_1.__importDefault(__webpack_require__(40)); -const Rx = tslib_1.__importStar(__webpack_require__(169)); -const operators_1 = __webpack_require__(270); -const exit_hook_1 = tslib_1.__importDefault(__webpack_require__(368)); -const errors_1 = __webpack_require__(369); -const proc_1 = __webpack_require__(370); -const SECOND = 1000; -const MINUTE = 60 * SECOND; -const noop = () => { }; -/** - * Helper for starting and managing processes. In many ways it resembles the - * API from `grunt_run`, processes are named and can be started, waited for, - * backgrounded once they log something matching a RegExp... - * - * @class ProcRunner - */ -class ProcRunner { - constructor(log) { - this.log = log; - this.closing = false; - this.procs = []; - this.signalUnsubscribe = exit_hook_1.default(() => { - this.teardown().catch((error) => { - log.error(`ProcRunner teardown error: ${error.stack}`); - }); - }); - } - /** - * Start a process, tracking it by `name` - * @param {String} name - * @param {Object} options - * @property {String} options.cmd executable to run - * @property {Array?} options.args arguments to provide the executable - * @property {String?} options.cwd current working directory for the process - * @property {RegExp|Boolean} options.wait Should start() wait for some time? Use - * `true` will wait until the proc exits, - * a `RegExp` will wait until that log line - * is found - * @return {Promise} - */ - async run(name, options) { - const { cmd, args = [], cwd = process.cwd(), stdin = undefined, wait = false, waitTimeout = 15 * MINUTE, env = process.env, } = options; - if (this.closing) { - throw new Error('ProcRunner is closing'); - } - if (wait && !(wait instanceof RegExp) && wait !== true) { - throw new TypeError('wait param should either be a RegExp or `true`'); - } - if (!!this.getProc(name)) { - throw new Error(`Process with name "${name}" already running`); - } - const proc = this.startProc(name, { - cmd, - args, - cwd, - env, - stdin, - }); - try { - if (wait instanceof RegExp) { - // wait for process to log matching line - await Rx.race(proc.lines$.pipe(operators_1.filter((line) => wait.test(line)), operators_1.first(), operators_1.catchError((err) => { - if (err.name !== 'EmptyError') { - throw errors_1.createCliError(`[${name}] exited without matching pattern: ${wait}`); - } - else { - throw err; - } - })), waitTimeout === false - ? Rx.NEVER - : Rx.timer(waitTimeout).pipe(operators_1.map(() => { - const sec = waitTimeout / SECOND; - throw errors_1.createCliError(`[${name}] failed to match pattern within ${sec} seconds [pattern=${wait}]`); - }))).toPromise(); - } - if (wait === true) { - // wait for process to complete - await proc.outcomePromise; - } - } - finally { - // while the procRunner closes promises will resolve/reject because - // processes and stopping, but consumers of run() shouldn't have to - // prepare for that, so just return a never-resolving promise - if (this.closing) { - await new Promise(noop); - } - } - } - /** - * Stop a named proc - */ - async stop(name, signal = 'SIGTERM') { - const proc = this.getProc(name); - if (proc) { - await proc.stop(signal); - } - else { - this.log.warning('[%s] already stopped', name); - } - } - /** - * Wait for all running processes to stop naturally - * @return {Promise} - */ - async waitForAllToStop() { - await Promise.all(this.procs.map((proc) => proc.outcomePromise)); - } - /** - * Close the ProcRunner and stop all running - * processes with `signal` - * - * @param {String} [signal=undefined] - * @return {Promise} - */ - async teardown(signal = 'exit') { - if (this.closing) { - return; - } - this.closing = true; - this.signalUnsubscribe(); - if (!signal && this.procs.length > 0) { - this.log.warning('%d processes left running, stop them with procs.stop(name):', this.procs.length, this.procs.map((proc) => proc.name)); - } - await Promise.all(this.procs.map(async (proc) => { - await proc.stop(signal === 'exit' ? 'SIGKILL' : signal); - })); - } - getProc(name) { - return this.procs.find((proc) => { - return proc.name === name; - }); - } - startProc(name, options) { - const startMs = Date.now(); - const proc = proc_1.startProc(name, options, this.log); - this.procs.push(proc); - const remove = () => { - this.procs.splice(this.procs.indexOf(proc), 1); - }; - // tie into proc outcome$, remove from _procs on compete - proc.outcome$.subscribe({ - next: (code) => { - const duration = moment_1.default.duration(Date.now() - startMs); - this.log.info('[%s] exited with %s after %s', name, code, duration.humanize()); - }, - complete: () => { - remove(); - }, - error: (error) => { - if (this.closing) { - this.log.error(error); - } - remove(); - }, - }); - return proc; + function getSetDayOfYear (input) { + var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; + return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); } -} -exports.ProcRunner = ProcRunner; - - -/***/ }), -/* 40 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(module) {var require;//! moment.js -;(function (global, factory) { - true ? module.exports = factory() : - undefined -}(this, (function () { 'use strict'; + // FORMATTING - var hookCallback; + addFormatToken('m', ['mm', 2], 0, 'minute'); - function hooks () { - return hookCallback.apply(null, arguments); - } + // ALIASES - // This is done to register the method called with moment() - // without creating circular dependencies. - function setHookCallback (callback) { - hookCallback = callback; - } + addUnitAlias('minute', 'm'); - function isArray(input) { - return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; - } + // PRIORITY - function isObject(input) { - // IE8 will treat undefined and null as object if it wasn't for - // input != null - return input != null && Object.prototype.toString.call(input) === '[object Object]'; - } + addUnitPriority('minute', 14); - function isObjectEmpty(obj) { - if (Object.getOwnPropertyNames) { - return (Object.getOwnPropertyNames(obj).length === 0); - } else { - var k; - for (k in obj) { - if (obj.hasOwnProperty(k)) { - return false; - } - } - return true; - } - } + // PARSING - function isUndefined(input) { - return input === void 0; - } + addRegexToken('m', match1to2); + addRegexToken('mm', match1to2, match2); + addParseToken(['m', 'mm'], MINUTE); - function isNumber(input) { - return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; - } + // MOMENTS - function isDate(input) { - return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; - } + var getSetMinute = makeGetSet('Minutes', false); - function map(arr, fn) { - var res = [], i; - for (i = 0; i < arr.length; ++i) { - res.push(fn(arr[i], i)); - } - return res; - } + // FORMATTING - function hasOwnProp(a, b) { - return Object.prototype.hasOwnProperty.call(a, b); - } + addFormatToken('s', ['ss', 2], 0, 'second'); - function extend(a, b) { - for (var i in b) { - if (hasOwnProp(b, i)) { - a[i] = b[i]; - } - } + // ALIASES - if (hasOwnProp(b, 'toString')) { - a.toString = b.toString; - } + addUnitAlias('second', 's'); - if (hasOwnProp(b, 'valueOf')) { - a.valueOf = b.valueOf; - } + // PRIORITY - return a; - } + addUnitPriority('second', 15); - function createUTC (input, format, locale, strict) { - return createLocalOrUTC(input, format, locale, strict, true).utc(); - } + // PARSING - function defaultParsingFlags() { - // We need to deep clone this object. - return { - empty : false, - unusedTokens : [], - unusedInput : [], - overflow : -2, - charsLeftOver : 0, - nullInput : false, - invalidMonth : null, - invalidFormat : false, - userInvalidated : false, - iso : false, - parsedDateParts : [], - meridiem : null, - rfc2822 : false, - weekdayMismatch : false - }; - } + addRegexToken('s', match1to2); + addRegexToken('ss', match1to2, match2); + addParseToken(['s', 'ss'], SECOND); - function getParsingFlags(m) { - if (m._pf == null) { - m._pf = defaultParsingFlags(); - } - return m._pf; - } + // MOMENTS - var some; - if (Array.prototype.some) { - some = Array.prototype.some; - } else { - some = function (fun) { - var t = Object(this); - var len = t.length >>> 0; + var getSetSecond = makeGetSet('Seconds', false); - for (var i = 0; i < len; i++) { - if (i in t && fun.call(this, t[i], i, t)) { - return true; - } - } + // FORMATTING - return false; - }; - } + addFormatToken('S', 0, 0, function () { + return ~~(this.millisecond() / 100); + }); - function isValid(m) { - if (m._isValid == null) { - var flags = getParsingFlags(m); - var parsedParts = some.call(flags.parsedDateParts, function (i) { - return i != null; - }); - var isNowValid = !isNaN(m._d.getTime()) && - flags.overflow < 0 && - !flags.empty && - !flags.invalidMonth && - !flags.invalidWeekday && - !flags.weekdayMismatch && - !flags.nullInput && - !flags.invalidFormat && - !flags.userInvalidated && - (!flags.meridiem || (flags.meridiem && parsedParts)); + addFormatToken(0, ['SS', 2], 0, function () { + return ~~(this.millisecond() / 10); + }); - if (m._strict) { - isNowValid = isNowValid && - flags.charsLeftOver === 0 && - flags.unusedTokens.length === 0 && - flags.bigHour === undefined; - } + addFormatToken(0, ['SSS', 3], 0, 'millisecond'); + addFormatToken(0, ['SSSS', 4], 0, function () { + return this.millisecond() * 10; + }); + addFormatToken(0, ['SSSSS', 5], 0, function () { + return this.millisecond() * 100; + }); + addFormatToken(0, ['SSSSSS', 6], 0, function () { + return this.millisecond() * 1000; + }); + addFormatToken(0, ['SSSSSSS', 7], 0, function () { + return this.millisecond() * 10000; + }); + addFormatToken(0, ['SSSSSSSS', 8], 0, function () { + return this.millisecond() * 100000; + }); + addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { + return this.millisecond() * 1000000; + }); - if (Object.isFrozen == null || !Object.isFrozen(m)) { - m._isValid = isNowValid; - } - else { - return isNowValid; - } - } - return m._isValid; - } - function createInvalid (flags) { - var m = createUTC(NaN); - if (flags != null) { - extend(getParsingFlags(m), flags); - } - else { - getParsingFlags(m).userInvalidated = true; - } + // ALIASES - return m; - } + addUnitAlias('millisecond', 'ms'); - // Plugins that add properties should also add the key here (null value), - // so we can properly clone ourselves. - var momentProperties = hooks.momentProperties = []; + // PRIORITY - function copyConfig(to, from) { - var i, prop, val; + addUnitPriority('millisecond', 16); - if (!isUndefined(from._isAMomentObject)) { - to._isAMomentObject = from._isAMomentObject; - } - if (!isUndefined(from._i)) { - to._i = from._i; - } - if (!isUndefined(from._f)) { - to._f = from._f; - } - if (!isUndefined(from._l)) { - to._l = from._l; - } - if (!isUndefined(from._strict)) { - to._strict = from._strict; - } - if (!isUndefined(from._tzm)) { - to._tzm = from._tzm; - } - if (!isUndefined(from._isUTC)) { - to._isUTC = from._isUTC; - } - if (!isUndefined(from._offset)) { - to._offset = from._offset; - } - if (!isUndefined(from._pf)) { - to._pf = getParsingFlags(from); - } - if (!isUndefined(from._locale)) { - to._locale = from._locale; - } + // PARSING - if (momentProperties.length > 0) { - for (i = 0; i < momentProperties.length; i++) { - prop = momentProperties[i]; - val = from[prop]; - if (!isUndefined(val)) { - to[prop] = val; - } - } - } + addRegexToken('S', match1to3, match1); + addRegexToken('SS', match1to3, match2); + addRegexToken('SSS', match1to3, match3); - return to; + var token; + for (token = 'SSSS'; token.length <= 9; token += 'S') { + addRegexToken(token, matchUnsigned); } - var updateInProgress = false; - - // Moment prototype object - function Moment(config) { - copyConfig(this, config); - this._d = new Date(config._d != null ? config._d.getTime() : NaN); - if (!this.isValid()) { - this._d = new Date(NaN); - } - // Prevent infinite loop in case updateOffset creates new moment - // objects. - if (updateInProgress === false) { - updateInProgress = true; - hooks.updateOffset(this); - updateInProgress = false; - } + function parseMs(input, array) { + array[MILLISECOND] = toInt(('0.' + input) * 1000); } - function isMoment (obj) { - return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); + for (token = 'S'; token.length <= 9; token += 'S') { + addParseToken(token, parseMs); } + // MOMENTS - function absFloor (number) { - if (number < 0) { - // -0 -> 0 - return Math.ceil(number) || 0; - } else { - return Math.floor(number); - } - } + var getSetMillisecond = makeGetSet('Milliseconds', false); - function toInt(argumentForCoercion) { - var coercedNumber = +argumentForCoercion, - value = 0; + // FORMATTING - if (coercedNumber !== 0 && isFinite(coercedNumber)) { - value = absFloor(coercedNumber); - } + addFormatToken('z', 0, 0, 'zoneAbbr'); + addFormatToken('zz', 0, 0, 'zoneName'); - return value; - } + // MOMENTS - // compare two arrays, return the number of differences - function compareArrays(array1, array2, dontConvert) { - var len = Math.min(array1.length, array2.length), - lengthDiff = Math.abs(array1.length - array2.length), - diffs = 0, - i; - for (i = 0; i < len; i++) { - if ((dontConvert && array1[i] !== array2[i]) || - (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { - diffs++; - } - } - return diffs + lengthDiff; + function getZoneAbbr () { + return this._isUTC ? 'UTC' : ''; } - function warn(msg) { - if (hooks.suppressDeprecationWarnings === false && - (typeof console !== 'undefined') && console.warn) { - console.warn('Deprecation warning: ' + msg); - } + function getZoneName () { + return this._isUTC ? 'Coordinated Universal Time' : ''; } - function deprecate(msg, fn) { - var firstTime = true; + var proto = Moment.prototype; - return extend(function () { - if (hooks.deprecationHandler != null) { - hooks.deprecationHandler(null, msg); - } - if (firstTime) { - var args = []; - var arg; - for (var i = 0; i < arguments.length; i++) { - arg = ''; - if (typeof arguments[i] === 'object') { - arg += '\n[' + i + '] '; - for (var key in arguments[0]) { - arg += key + ': ' + arguments[0][key] + ', '; - } - arg = arg.slice(0, -2); // Remove trailing comma and space - } else { - arg = arguments[i]; - } - args.push(arg); - } - warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); - firstTime = false; - } - return fn.apply(this, arguments); - }, fn); + proto.add = add; + proto.calendar = calendar$1; + proto.clone = clone; + proto.diff = diff; + proto.endOf = endOf; + proto.format = format; + proto.from = from; + proto.fromNow = fromNow; + proto.to = to; + proto.toNow = toNow; + proto.get = stringGet; + proto.invalidAt = invalidAt; + proto.isAfter = isAfter; + proto.isBefore = isBefore; + proto.isBetween = isBetween; + proto.isSame = isSame; + proto.isSameOrAfter = isSameOrAfter; + proto.isSameOrBefore = isSameOrBefore; + proto.isValid = isValid$2; + proto.lang = lang; + proto.locale = locale; + proto.localeData = localeData; + proto.max = prototypeMax; + proto.min = prototypeMin; + proto.parsingFlags = parsingFlags; + proto.set = stringSet; + proto.startOf = startOf; + proto.subtract = subtract; + proto.toArray = toArray; + proto.toObject = toObject; + proto.toDate = toDate; + proto.toISOString = toISOString; + proto.inspect = inspect; + proto.toJSON = toJSON; + proto.toString = toString; + proto.unix = unix; + proto.valueOf = valueOf; + proto.creationData = creationData; + proto.year = getSetYear; + proto.isLeapYear = getIsLeapYear; + proto.weekYear = getSetWeekYear; + proto.isoWeekYear = getSetISOWeekYear; + proto.quarter = proto.quarters = getSetQuarter; + proto.month = getSetMonth; + proto.daysInMonth = getDaysInMonth; + proto.week = proto.weeks = getSetWeek; + proto.isoWeek = proto.isoWeeks = getSetISOWeek; + proto.weeksInYear = getWeeksInYear; + proto.isoWeeksInYear = getISOWeeksInYear; + proto.date = getSetDayOfMonth; + proto.day = proto.days = getSetDayOfWeek; + proto.weekday = getSetLocaleDayOfWeek; + proto.isoWeekday = getSetISODayOfWeek; + proto.dayOfYear = getSetDayOfYear; + proto.hour = proto.hours = getSetHour; + proto.minute = proto.minutes = getSetMinute; + proto.second = proto.seconds = getSetSecond; + proto.millisecond = proto.milliseconds = getSetMillisecond; + proto.utcOffset = getSetOffset; + proto.utc = setOffsetToUTC; + proto.local = setOffsetToLocal; + proto.parseZone = setOffsetToParsedOffset; + proto.hasAlignedHourOffset = hasAlignedHourOffset; + proto.isDST = isDaylightSavingTime; + proto.isLocal = isLocal; + proto.isUtcOffset = isUtcOffset; + proto.isUtc = isUtc; + proto.isUTC = isUtc; + proto.zoneAbbr = getZoneAbbr; + proto.zoneName = getZoneName; + proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); + proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); + proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); + proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); + proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); + + function createUnix (input) { + return createLocal(input * 1000); } - var deprecations = {}; + function createInZone () { + return createLocal.apply(null, arguments).parseZone(); + } - function deprecateSimple(name, msg) { - if (hooks.deprecationHandler != null) { - hooks.deprecationHandler(name, msg); - } - if (!deprecations[name]) { - warn(msg); - deprecations[name] = true; - } + function preParsePostFormat (string) { + return string; } - hooks.suppressDeprecationWarnings = false; - hooks.deprecationHandler = null; + var proto$1 = Locale.prototype; - function isFunction(input) { - return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; - } + proto$1.calendar = calendar; + proto$1.longDateFormat = longDateFormat; + proto$1.invalidDate = invalidDate; + proto$1.ordinal = ordinal; + proto$1.preparse = preParsePostFormat; + proto$1.postformat = preParsePostFormat; + proto$1.relativeTime = relativeTime; + proto$1.pastFuture = pastFuture; + proto$1.set = set; - function set (config) { - var prop, i; - for (i in config) { - prop = config[i]; - if (isFunction(prop)) { - this[i] = prop; - } else { - this['_' + i] = prop; - } - } - this._config = config; - // Lenient ordinal parsing accepts just a number in addition to - // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. - // TODO: Remove "ordinalParse" fallback in next major release. - this._dayOfMonthOrdinalParseLenient = new RegExp( - (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + - '|' + (/\d{1,2}/).source); + proto$1.months = localeMonths; + proto$1.monthsShort = localeMonthsShort; + proto$1.monthsParse = localeMonthsParse; + proto$1.monthsRegex = monthsRegex; + proto$1.monthsShortRegex = monthsShortRegex; + proto$1.week = localeWeek; + proto$1.firstDayOfYear = localeFirstDayOfYear; + proto$1.firstDayOfWeek = localeFirstDayOfWeek; + + proto$1.weekdays = localeWeekdays; + proto$1.weekdaysMin = localeWeekdaysMin; + proto$1.weekdaysShort = localeWeekdaysShort; + proto$1.weekdaysParse = localeWeekdaysParse; + + proto$1.weekdaysRegex = weekdaysRegex; + proto$1.weekdaysShortRegex = weekdaysShortRegex; + proto$1.weekdaysMinRegex = weekdaysMinRegex; + + proto$1.isPM = localeIsPM; + proto$1.meridiem = localeMeridiem; + + function get$1 (format, index, field, setter) { + var locale = getLocale(); + var utc = createUTC().set(setter, index); + return locale[field](utc, format); } - function mergeConfigs(parentConfig, childConfig) { - var res = extend({}, parentConfig), prop; - for (prop in childConfig) { - if (hasOwnProp(childConfig, prop)) { - if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { - res[prop] = {}; - extend(res[prop], parentConfig[prop]); - extend(res[prop], childConfig[prop]); - } else if (childConfig[prop] != null) { - res[prop] = childConfig[prop]; - } else { - delete res[prop]; - } - } + function listMonthsImpl (format, index, field) { + if (isNumber(format)) { + index = format; + format = undefined; } - for (prop in parentConfig) { - if (hasOwnProp(parentConfig, prop) && - !hasOwnProp(childConfig, prop) && - isObject(parentConfig[prop])) { - // make sure changes to properties don't modify parent config - res[prop] = extend({}, res[prop]); - } + + format = format || ''; + + if (index != null) { + return get$1(format, index, field, 'month'); } - return res; - } - function Locale(config) { - if (config != null) { - this.set(config); + var i; + var out = []; + for (i = 0; i < 12; i++) { + out[i] = get$1(format, i, field, 'month'); } + return out; } - var keys; - - if (Object.keys) { - keys = Object.keys; - } else { - keys = function (obj) { - var i, res = []; - for (i in obj) { - if (hasOwnProp(obj, i)) { - res.push(i); - } + // () + // (5) + // (fmt, 5) + // (fmt) + // (true) + // (true, 5) + // (true, fmt, 5) + // (true, fmt) + function listWeekdaysImpl (localeSorted, format, index, field) { + if (typeof localeSorted === 'boolean') { + if (isNumber(format)) { + index = format; + format = undefined; } - return res; - }; - } - var defaultCalendar = { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }; + format = format || ''; + } else { + format = localeSorted; + index = format; + localeSorted = false; - function calendar (key, mom, now) { - var output = this._calendar[key] || this._calendar['sameElse']; - return isFunction(output) ? output.call(mom, now) : output; - } + if (isNumber(format)) { + index = format; + format = undefined; + } - var defaultLongDateFormat = { - LTS : 'h:mm:ss A', - LT : 'h:mm A', - L : 'MM/DD/YYYY', - LL : 'MMMM D, YYYY', - LLL : 'MMMM D, YYYY h:mm A', - LLLL : 'dddd, MMMM D, YYYY h:mm A' - }; + format = format || ''; + } - function longDateFormat (key) { - var format = this._longDateFormat[key], - formatUpper = this._longDateFormat[key.toUpperCase()]; + var locale = getLocale(), + shift = localeSorted ? locale._week.dow : 0; - if (format || !formatUpper) { - return format; + if (index != null) { + return get$1(format, (index + shift) % 7, field, 'day'); } - this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { - return val.slice(1); - }); - - return this._longDateFormat[key]; + var i; + var out = []; + for (i = 0; i < 7; i++) { + out[i] = get$1(format, (i + shift) % 7, field, 'day'); + } + return out; } - var defaultInvalidDate = 'Invalid date'; - - function invalidDate () { - return this._invalidDate; + function listMonths (format, index) { + return listMonthsImpl(format, index, 'months'); } - var defaultOrdinal = '%d'; - var defaultDayOfMonthOrdinalParse = /\d{1,2}/; - - function ordinal (number) { - return this._ordinal.replace('%d', number); + function listMonthsShort (format, index) { + return listMonthsImpl(format, index, 'monthsShort'); } - var defaultRelativeTime = { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - ss : '%d seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }; - - function relativeTime (number, withoutSuffix, string, isFuture) { - var output = this._relativeTime[string]; - return (isFunction(output)) ? - output(number, withoutSuffix, string, isFuture) : - output.replace(/%d/i, number); + function listWeekdays (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); } - function pastFuture (diff, output) { - var format = this._relativeTime[diff > 0 ? 'future' : 'past']; - return isFunction(format) ? format(output) : format.replace(/%s/i, output); + function listWeekdaysShort (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); } - var aliases = {}; - - function addUnitAlias (unit, shorthand) { - var lowerCase = unit.toLowerCase(); - aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; + function listWeekdaysMin (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); } - function normalizeUnits(units) { - return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; - } + getSetGlobalLocale('en', { + dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, + ordinal : function (number) { + var b = number % 10, + output = (toInt(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + } + }); - function normalizeObjectUnits(inputObject) { - var normalizedInput = {}, - normalizedProp, - prop; + // Side effect imports - for (prop in inputObject) { - if (hasOwnProp(inputObject, prop)) { - normalizedProp = normalizeUnits(prop); - if (normalizedProp) { - normalizedInput[normalizedProp] = inputObject[prop]; - } - } - } + hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); + hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); - return normalizedInput; - } + var mathAbs = Math.abs; - var priorities = {}; + function abs () { + var data = this._data; - function addUnitPriority(unit, priority) { - priorities[unit] = priority; - } + this._milliseconds = mathAbs(this._milliseconds); + this._days = mathAbs(this._days); + this._months = mathAbs(this._months); - function getPrioritizedUnits(unitsObj) { - var units = []; - for (var u in unitsObj) { - units.push({unit: u, priority: priorities[u]}); - } - units.sort(function (a, b) { - return a.priority - b.priority; - }); - return units; - } + data.milliseconds = mathAbs(data.milliseconds); + data.seconds = mathAbs(data.seconds); + data.minutes = mathAbs(data.minutes); + data.hours = mathAbs(data.hours); + data.months = mathAbs(data.months); + data.years = mathAbs(data.years); - function zeroFill(number, targetLength, forceSign) { - var absNumber = '' + Math.abs(number), - zerosToFill = targetLength - absNumber.length, - sign = number >= 0; - return (sign ? (forceSign ? '+' : '') : '-') + - Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; + return this; } - var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; + function addSubtract$1 (duration, input, value, direction) { + var other = createDuration(input, value); - var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; + duration._milliseconds += direction * other._milliseconds; + duration._days += direction * other._days; + duration._months += direction * other._months; - var formatFunctions = {}; + return duration._bubble(); + } - var formatTokenFunctions = {}; + // supports only 2.0-style add(1, 's') or add(duration) + function add$1 (input, value) { + return addSubtract$1(this, input, value, 1); + } - // token: 'M' - // padded: ['MM', 2] - // ordinal: 'Mo' - // callback: function () { this.month() + 1 } - function addFormatToken (token, padded, ordinal, callback) { - var func = callback; - if (typeof callback === 'string') { - func = function () { - return this[callback](); - }; - } - if (token) { - formatTokenFunctions[token] = func; - } - if (padded) { - formatTokenFunctions[padded[0]] = function () { - return zeroFill(func.apply(this, arguments), padded[1], padded[2]); - }; - } - if (ordinal) { - formatTokenFunctions[ordinal] = function () { - return this.localeData().ordinal(func.apply(this, arguments), token); - }; - } + // supports only 2.0-style subtract(1, 's') or subtract(duration) + function subtract$1 (input, value) { + return addSubtract$1(this, input, value, -1); } - function removeFormattingTokens(input) { - if (input.match(/\[[\s\S]/)) { - return input.replace(/^\[|\]$/g, ''); + function absCeil (number) { + if (number < 0) { + return Math.floor(number); + } else { + return Math.ceil(number); } - return input.replace(/\\/g, ''); } - function makeFormatFunction(format) { - var array = format.match(formattingTokens), i, length; + function bubble () { + var milliseconds = this._milliseconds; + var days = this._days; + var months = this._months; + var data = this._data; + var seconds, minutes, hours, years, monthsFromDays; - for (i = 0, length = array.length; i < length; i++) { - if (formatTokenFunctions[array[i]]) { - array[i] = formatTokenFunctions[array[i]]; - } else { - array[i] = removeFormattingTokens(array[i]); - } + // if we have a mix of positive and negative values, bubble down first + // check: https://github.com/moment/moment/issues/2166 + if (!((milliseconds >= 0 && days >= 0 && months >= 0) || + (milliseconds <= 0 && days <= 0 && months <= 0))) { + milliseconds += absCeil(monthsToDays(months) + days) * 864e5; + days = 0; + months = 0; } - return function (mom) { - var output = '', i; - for (i = 0; i < length; i++) { - output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; - } - return output; - }; - } + // The following code bubbles up values, see the tests for + // examples of what that means. + data.milliseconds = milliseconds % 1000; - // format date using native date object - function formatMoment(m, format) { - if (!m.isValid()) { - return m.localeData().invalidDate(); - } + seconds = absFloor(milliseconds / 1000); + data.seconds = seconds % 60; - format = expandFormat(format, m.localeData()); - formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); + minutes = absFloor(seconds / 60); + data.minutes = minutes % 60; - return formatFunctions[format](m); - } + hours = absFloor(minutes / 60); + data.hours = hours % 24; - function expandFormat(format, locale) { - var i = 5; + days += absFloor(hours / 24); - function replaceLongDateFormatTokens(input) { - return locale.longDateFormat(input) || input; - } + // convert days to months + monthsFromDays = absFloor(daysToMonths(days)); + months += monthsFromDays; + days -= absCeil(monthsToDays(monthsFromDays)); - localFormattingTokens.lastIndex = 0; - while (i >= 0 && localFormattingTokens.test(format)) { - format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); - localFormattingTokens.lastIndex = 0; - i -= 1; - } - - return format; - } - - var match1 = /\d/; // 0 - 9 - var match2 = /\d\d/; // 00 - 99 - var match3 = /\d{3}/; // 000 - 999 - var match4 = /\d{4}/; // 0000 - 9999 - var match6 = /[+-]?\d{6}/; // -999999 - 999999 - var match1to2 = /\d\d?/; // 0 - 99 - var match3to4 = /\d\d\d\d?/; // 999 - 9999 - var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 - var match1to3 = /\d{1,3}/; // 0 - 999 - var match1to4 = /\d{1,4}/; // 0 - 9999 - var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 - - var matchUnsigned = /\d+/; // 0 - inf - var matchSigned = /[+-]?\d+/; // -inf - inf - - var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z - var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z - - var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 - - // any word (or two) characters or numbers including two/three word month in arabic. - // includes scottish gaelic two word and hyphenated months - var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i; + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; - var regexes = {}; + data.days = days; + data.months = months; + data.years = years; - function addRegexToken (token, regex, strictRegex) { - regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { - return (isStrict && strictRegex) ? strictRegex : regex; - }; + return this; } - function getParseRegexForToken (token, config) { - if (!hasOwnProp(regexes, token)) { - return new RegExp(unescapeFormat(token)); - } - - return regexes[token](config._strict, config._locale); + function daysToMonths (days) { + // 400 years have 146097 days (taking into account leap year rules) + // 400 years have 12 months === 4800 + return days * 4800 / 146097; } - // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript - function unescapeFormat(s) { - return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { - return p1 || p2 || p3 || p4; - })); + function monthsToDays (months) { + // the reverse of daysToMonths + return months * 146097 / 4800; } - function regexEscape(s) { - return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); - } + function as (units) { + if (!this.isValid()) { + return NaN; + } + var days; + var months; + var milliseconds = this._milliseconds; - var tokens = {}; + units = normalizeUnits(units); - function addParseToken (token, callback) { - var i, func = callback; - if (typeof token === 'string') { - token = [token]; - } - if (isNumber(callback)) { - func = function (input, array) { - array[callback] = toInt(input); - }; - } - for (i = 0; i < token.length; i++) { - tokens[token[i]] = func; + if (units === 'month' || units === 'quarter' || units === 'year') { + days = this._days + milliseconds / 864e5; + months = this._months + daysToMonths(days); + switch (units) { + case 'month': return months; + case 'quarter': return months / 3; + case 'year': return months / 12; + } + } else { + // handle milliseconds separately because of floating point math errors (issue #1867) + days = this._days + Math.round(monthsToDays(this._months)); + switch (units) { + case 'week' : return days / 7 + milliseconds / 6048e5; + case 'day' : return days + milliseconds / 864e5; + case 'hour' : return days * 24 + milliseconds / 36e5; + case 'minute' : return days * 1440 + milliseconds / 6e4; + case 'second' : return days * 86400 + milliseconds / 1000; + // Math.floor prevents floating point math errors here + case 'millisecond': return Math.floor(days * 864e5) + milliseconds; + default: throw new Error('Unknown unit ' + units); + } } } - function addWeekParseToken (token, callback) { - addParseToken(token, function (input, array, config, token) { - config._w = config._w || {}; - callback(input, config._w, config, token); - }); - } - - function addTimeToArrayFromToken(token, input, config) { - if (input != null && hasOwnProp(tokens, token)) { - tokens[token](input, config._a, config, token); + // TODO: Use this.as('ms')? + function valueOf$1 () { + if (!this.isValid()) { + return NaN; } + return ( + this._milliseconds + + this._days * 864e5 + + (this._months % 12) * 2592e6 + + toInt(this._months / 12) * 31536e6 + ); } - var YEAR = 0; - var MONTH = 1; - var DATE = 2; - var HOUR = 3; - var MINUTE = 4; - var SECOND = 5; - var MILLISECOND = 6; - var WEEK = 7; - var WEEKDAY = 8; - - // FORMATTING - - addFormatToken('Y', 0, 0, function () { - var y = this.year(); - return y <= 9999 ? '' + y : '+' + y; - }); + function makeAs (alias) { + return function () { + return this.as(alias); + }; + } - addFormatToken(0, ['YY', 2], 0, function () { - return this.year() % 100; - }); + var asMilliseconds = makeAs('ms'); + var asSeconds = makeAs('s'); + var asMinutes = makeAs('m'); + var asHours = makeAs('h'); + var asDays = makeAs('d'); + var asWeeks = makeAs('w'); + var asMonths = makeAs('M'); + var asQuarters = makeAs('Q'); + var asYears = makeAs('y'); - addFormatToken(0, ['YYYY', 4], 0, 'year'); - addFormatToken(0, ['YYYYY', 5], 0, 'year'); - addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); + function clone$1 () { + return createDuration(this); + } - // ALIASES + function get$2 (units) { + units = normalizeUnits(units); + return this.isValid() ? this[units + 's']() : NaN; + } - addUnitAlias('year', 'y'); + function makeGetter(name) { + return function () { + return this.isValid() ? this._data[name] : NaN; + }; + } - // PRIORITIES + var milliseconds = makeGetter('milliseconds'); + var seconds = makeGetter('seconds'); + var minutes = makeGetter('minutes'); + var hours = makeGetter('hours'); + var days = makeGetter('days'); + var months = makeGetter('months'); + var years = makeGetter('years'); - addUnitPriority('year', 1); + function weeks () { + return absFloor(this.days() / 7); + } - // PARSING + var round = Math.round; + var thresholds = { + ss: 44, // a few seconds to seconds + s : 45, // seconds to minute + m : 45, // minutes to hour + h : 22, // hours to day + d : 26, // days to month + M : 11 // months to year + }; - addRegexToken('Y', matchSigned); - addRegexToken('YY', match1to2, match2); - addRegexToken('YYYY', match1to4, match4); - addRegexToken('YYYYY', match1to6, match6); - addRegexToken('YYYYYY', match1to6, match6); + // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize + function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { + return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); + } - addParseToken(['YYYYY', 'YYYYYY'], YEAR); - addParseToken('YYYY', function (input, array) { - array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); - }); - addParseToken('YY', function (input, array) { - array[YEAR] = hooks.parseTwoDigitYear(input); - }); - addParseToken('Y', function (input, array) { - array[YEAR] = parseInt(input, 10); - }); + function relativeTime$1 (posNegDuration, withoutSuffix, locale) { + var duration = createDuration(posNegDuration).abs(); + var seconds = round(duration.as('s')); + var minutes = round(duration.as('m')); + var hours = round(duration.as('h')); + var days = round(duration.as('d')); + var months = round(duration.as('M')); + var years = round(duration.as('y')); - // HELPERS + var a = seconds <= thresholds.ss && ['s', seconds] || + seconds < thresholds.s && ['ss', seconds] || + minutes <= 1 && ['m'] || + minutes < thresholds.m && ['mm', minutes] || + hours <= 1 && ['h'] || + hours < thresholds.h && ['hh', hours] || + days <= 1 && ['d'] || + days < thresholds.d && ['dd', days] || + months <= 1 && ['M'] || + months < thresholds.M && ['MM', months] || + years <= 1 && ['y'] || ['yy', years]; - function daysInYear(year) { - return isLeapYear(year) ? 366 : 365; + a[2] = withoutSuffix; + a[3] = +posNegDuration > 0; + a[4] = locale; + return substituteTimeAgo.apply(null, a); } - function isLeapYear(year) { - return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; + // This function allows you to set the rounding function for relative time strings + function getSetRelativeTimeRounding (roundingFunction) { + if (roundingFunction === undefined) { + return round; + } + if (typeof(roundingFunction) === 'function') { + round = roundingFunction; + return true; + } + return false; } - // HOOKS - - hooks.parseTwoDigitYear = function (input) { - return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); - }; + // This function allows you to set a threshold for relative time strings + function getSetRelativeTimeThreshold (threshold, limit) { + if (thresholds[threshold] === undefined) { + return false; + } + if (limit === undefined) { + return thresholds[threshold]; + } + thresholds[threshold] = limit; + if (threshold === 's') { + thresholds.ss = limit - 1; + } + return true; + } - // MOMENTS + function humanize (withSuffix) { + if (!this.isValid()) { + return this.localeData().invalidDate(); + } - var getSetYear = makeGetSet('FullYear', true); + var locale = this.localeData(); + var output = relativeTime$1(this, !withSuffix, locale); - function getIsLeapYear () { - return isLeapYear(this.year()); - } + if (withSuffix) { + output = locale.pastFuture(+this, output); + } - function makeGetSet (unit, keepTime) { - return function (value) { - if (value != null) { - set$1(this, unit, value); - hooks.updateOffset(this, keepTime); - return this; - } else { - return get(this, unit); - } - }; + return locale.postformat(output); } - function get (mom, unit) { - return mom.isValid() ? - mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; - } + var abs$1 = Math.abs; - function set$1 (mom, unit, value) { - if (mom.isValid() && !isNaN(value)) { - if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { - mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); - } - else { - mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); - } - } + function sign(x) { + return ((x > 0) - (x < 0)) || +x; } - // MOMENTS - - function stringGet (units) { - units = normalizeUnits(units); - if (isFunction(this[units])) { - return this[units](); + function toISOString$1() { + // for ISO strings we do not use the normal bubbling rules: + // * milliseconds bubble up until they become hours + // * days do not bubble at all + // * months bubble up until they become years + // This is because there is no context-free conversion between hours and days + // (think of clock changes) + // and also not between days and months (28-31 days per month) + if (!this.isValid()) { + return this.localeData().invalidDate(); } - return this; - } + var seconds = abs$1(this._milliseconds) / 1000; + var days = abs$1(this._days); + var months = abs$1(this._months); + var minutes, hours, years; - function stringSet (units, value) { - if (typeof units === 'object') { - units = normalizeObjectUnits(units); - var prioritized = getPrioritizedUnits(units); - for (var i = 0; i < prioritized.length; i++) { - this[prioritized[i].unit](units[prioritized[i].unit]); - } - } else { - units = normalizeUnits(units); - if (isFunction(this[units])) { - return this[units](value); - } - } - return this; - } + // 3600 seconds -> 60 minutes -> 1 hour + minutes = absFloor(seconds / 60); + hours = absFloor(minutes / 60); + seconds %= 60; + minutes %= 60; - function mod(n, x) { - return ((n % x) + x) % x; - } + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; - var indexOf; - if (Array.prototype.indexOf) { - indexOf = Array.prototype.indexOf; - } else { - indexOf = function (o) { - // I know - var i; - for (i = 0; i < this.length; ++i) { - if (this[i] === o) { - return i; - } - } - return -1; - }; - } + // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js + var Y = years; + var M = months; + var D = days; + var h = hours; + var m = minutes; + var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; + var total = this.asSeconds(); - function daysInMonth(year, month) { - if (isNaN(year) || isNaN(month)) { - return NaN; + if (!total) { + // this is the same as C#'s (Noda) and python (isodate)... + // but not other JS (goog.date) + return 'P0D'; } - var modMonth = mod(month, 12); - year += (month - modMonth) / 12; - return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); - } - // FORMATTING + var totalSign = total < 0 ? '-' : ''; + var ymSign = sign(this._months) !== sign(total) ? '-' : ''; + var daysSign = sign(this._days) !== sign(total) ? '-' : ''; + var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; - addFormatToken('M', ['MM', 2], 'Mo', function () { - return this.month() + 1; - }); + return totalSign + 'P' + + (Y ? ymSign + Y + 'Y' : '') + + (M ? ymSign + M + 'M' : '') + + (D ? daysSign + D + 'D' : '') + + ((h || m || s) ? 'T' : '') + + (h ? hmsSign + h + 'H' : '') + + (m ? hmsSign + m + 'M' : '') + + (s ? hmsSign + s + 'S' : ''); + } - addFormatToken('MMM', 0, 0, function (format) { - return this.localeData().monthsShort(this, format); - }); + var proto$2 = Duration.prototype; - addFormatToken('MMMM', 0, 0, function (format) { - return this.localeData().months(this, format); - }); + proto$2.isValid = isValid$1; + proto$2.abs = abs; + proto$2.add = add$1; + proto$2.subtract = subtract$1; + proto$2.as = as; + proto$2.asMilliseconds = asMilliseconds; + proto$2.asSeconds = asSeconds; + proto$2.asMinutes = asMinutes; + proto$2.asHours = asHours; + proto$2.asDays = asDays; + proto$2.asWeeks = asWeeks; + proto$2.asMonths = asMonths; + proto$2.asQuarters = asQuarters; + proto$2.asYears = asYears; + proto$2.valueOf = valueOf$1; + proto$2._bubble = bubble; + proto$2.clone = clone$1; + proto$2.get = get$2; + proto$2.milliseconds = milliseconds; + proto$2.seconds = seconds; + proto$2.minutes = minutes; + proto$2.hours = hours; + proto$2.days = days; + proto$2.weeks = weeks; + proto$2.months = months; + proto$2.years = years; + proto$2.humanize = humanize; + proto$2.toISOString = toISOString$1; + proto$2.toString = toISOString$1; + proto$2.toJSON = toISOString$1; + proto$2.locale = locale; + proto$2.localeData = localeData; - // ALIASES + proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); + proto$2.lang = lang; - addUnitAlias('month', 'M'); + // Side effect imports - // PRIORITY + // FORMATTING - addUnitPriority('month', 8); + addFormatToken('X', 0, 0, 'unix'); + addFormatToken('x', 0, 0, 'valueOf'); // PARSING - addRegexToken('M', match1to2); - addRegexToken('MM', match1to2, match2); - addRegexToken('MMM', function (isStrict, locale) { - return locale.monthsShortRegex(isStrict); - }); - addRegexToken('MMMM', function (isStrict, locale) { - return locale.monthsRegex(isStrict); + addRegexToken('x', matchSigned); + addRegexToken('X', matchTimestamp); + addParseToken('X', function (input, array, config) { + config._d = new Date(parseFloat(input, 10) * 1000); }); - - addParseToken(['M', 'MM'], function (input, array) { - array[MONTH] = toInt(input) - 1; + addParseToken('x', function (input, array, config) { + config._d = new Date(toInt(input)); }); - addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { - var month = config._locale.monthsParse(input, token, config._strict); - // if we didn't find a month name, mark the date as invalid. - if (month != null) { - array[MONTH] = month; - } else { - getParsingFlags(config).invalidMonth = input; - } - }); + // Side effect imports - // LOCALES - var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; - var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); - function localeMonths (m, format) { - if (!m) { - return isArray(this._months) ? this._months : - this._months['standalone']; - } - return isArray(this._months) ? this._months[m.month()] : - this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; - } + hooks.version = '2.24.0'; - var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); - function localeMonthsShort (m, format) { - if (!m) { - return isArray(this._monthsShort) ? this._monthsShort : - this._monthsShort['standalone']; - } - return isArray(this._monthsShort) ? this._monthsShort[m.month()] : - this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; - } + setHookCallback(createLocal); - function handleStrictParse(monthName, format, strict) { - var i, ii, mom, llc = monthName.toLocaleLowerCase(); - if (!this._monthsParse) { - // this is not used - this._monthsParse = []; - this._longMonthsParse = []; - this._shortMonthsParse = []; - for (i = 0; i < 12; ++i) { - mom = createUTC([2000, i]); - this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); - this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); - } - } + hooks.fn = proto; + hooks.min = min; + hooks.max = max; + hooks.now = now; + hooks.utc = createUTC; + hooks.unix = createUnix; + hooks.months = listMonths; + hooks.isDate = isDate; + hooks.locale = getSetGlobalLocale; + hooks.invalid = createInvalid; + hooks.duration = createDuration; + hooks.isMoment = isMoment; + hooks.weekdays = listWeekdays; + hooks.parseZone = createInZone; + hooks.localeData = getLocale; + hooks.isDuration = isDuration; + hooks.monthsShort = listMonthsShort; + hooks.weekdaysMin = listWeekdaysMin; + hooks.defineLocale = defineLocale; + hooks.updateLocale = updateLocale; + hooks.locales = listLocales; + hooks.weekdaysShort = listWeekdaysShort; + hooks.normalizeUnits = normalizeUnits; + hooks.relativeTimeRounding = getSetRelativeTimeRounding; + hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; + hooks.calendarFormat = getCalendarFormat; + hooks.prototype = proto; - if (strict) { - if (format === 'MMM') { - ii = indexOf.call(this._shortMonthsParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._longMonthsParse, llc); - return ii !== -1 ? ii : null; - } - } else { - if (format === 'MMM') { - ii = indexOf.call(this._shortMonthsParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._longMonthsParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._longMonthsParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._shortMonthsParse, llc); - return ii !== -1 ? ii : null; - } - } - } + // currently HTML5 input type only supports 24-hour formats + hooks.HTML5_FMT = { + DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // + DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // + DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // + DATE: 'YYYY-MM-DD', // + TIME: 'HH:mm', // + TIME_SECONDS: 'HH:mm:ss', // + TIME_MS: 'HH:mm:ss.SSS', // + WEEK: 'GGGG-[W]WW', // + MONTH: 'YYYY-MM' // + }; - function localeMonthsParse (monthName, format, strict) { - var i, mom, regex; + return hooks; - if (this._monthsParseExact) { - return handleStrictParse.call(this, monthName, format, strict); - } +}))); - if (!this._monthsParse) { - this._monthsParse = []; - this._longMonthsParse = []; - this._shortMonthsParse = []; - } +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(11)(module))) - // TODO: add sorting - // Sorting makes sure if one month (or abbr) is a prefix of another - // see sorting in computeMonthsParse - for (i = 0; i < 12; i++) { - // make the regex if we don't have it already - mom = createUTC([2000, i]); - if (strict && !this._longMonthsParse[i]) { - this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); - this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); - } - if (!strict && !this._monthsParse[i]) { - regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); - this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); - } - // test the regex - if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { - return i; - } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { - return i; - } else if (!strict && this._monthsParse[i].test(monthName)) { - return i; - } - } - } +/***/ }), +/* 11 */ +/***/ (function(module, exports) { - // MOMENTS +module.exports = function(module) { + if (!module.webpackPolyfill) { + module.deprecate = function() {}; + module.paths = []; + // module.parent = undefined by default + if (!module.children) module.children = []; + Object.defineProperty(module, "loaded", { + enumerable: true, + get: function() { + return module.l; + } + }); + Object.defineProperty(module, "id", { + enumerable: true, + get: function() { + return module.i; + } + }); + module.webpackPolyfill = 1; + } + return module; +}; - function setMonth (mom, value) { - var dayOfMonth; - if (!mom.isValid()) { - // No op - return mom; - } +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { - if (typeof value === 'string') { - if (/^\d+$/.test(value)) { - value = toInt(value); - } else { - value = mom.localeData().monthsParse(value); - // TODO: Another silent failure? - if (!isNumber(value)) { - return mom; - } - } - } +var map = { + "./af": 13, + "./af.js": 13, + "./ar": 14, + "./ar-dz": 15, + "./ar-dz.js": 15, + "./ar-kw": 16, + "./ar-kw.js": 16, + "./ar-ly": 17, + "./ar-ly.js": 17, + "./ar-ma": 18, + "./ar-ma.js": 18, + "./ar-sa": 19, + "./ar-sa.js": 19, + "./ar-tn": 20, + "./ar-tn.js": 20, + "./ar.js": 14, + "./az": 21, + "./az.js": 21, + "./be": 22, + "./be.js": 22, + "./bg": 23, + "./bg.js": 23, + "./bm": 24, + "./bm.js": 24, + "./bn": 25, + "./bn.js": 25, + "./bo": 26, + "./bo.js": 26, + "./br": 27, + "./br.js": 27, + "./bs": 28, + "./bs.js": 28, + "./ca": 29, + "./ca.js": 29, + "./cs": 30, + "./cs.js": 30, + "./cv": 31, + "./cv.js": 31, + "./cy": 32, + "./cy.js": 32, + "./da": 33, + "./da.js": 33, + "./de": 34, + "./de-at": 35, + "./de-at.js": 35, + "./de-ch": 36, + "./de-ch.js": 36, + "./de.js": 34, + "./dv": 37, + "./dv.js": 37, + "./el": 38, + "./el.js": 38, + "./en-SG": 39, + "./en-SG.js": 39, + "./en-au": 40, + "./en-au.js": 40, + "./en-ca": 41, + "./en-ca.js": 41, + "./en-gb": 42, + "./en-gb.js": 42, + "./en-ie": 43, + "./en-ie.js": 43, + "./en-il": 44, + "./en-il.js": 44, + "./en-nz": 45, + "./en-nz.js": 45, + "./eo": 46, + "./eo.js": 46, + "./es": 47, + "./es-do": 48, + "./es-do.js": 48, + "./es-us": 49, + "./es-us.js": 49, + "./es.js": 47, + "./et": 50, + "./et.js": 50, + "./eu": 51, + "./eu.js": 51, + "./fa": 52, + "./fa.js": 52, + "./fi": 53, + "./fi.js": 53, + "./fo": 54, + "./fo.js": 54, + "./fr": 55, + "./fr-ca": 56, + "./fr-ca.js": 56, + "./fr-ch": 57, + "./fr-ch.js": 57, + "./fr.js": 55, + "./fy": 58, + "./fy.js": 58, + "./ga": 59, + "./ga.js": 59, + "./gd": 60, + "./gd.js": 60, + "./gl": 61, + "./gl.js": 61, + "./gom-latn": 62, + "./gom-latn.js": 62, + "./gu": 63, + "./gu.js": 63, + "./he": 64, + "./he.js": 64, + "./hi": 65, + "./hi.js": 65, + "./hr": 66, + "./hr.js": 66, + "./hu": 67, + "./hu.js": 67, + "./hy-am": 68, + "./hy-am.js": 68, + "./id": 69, + "./id.js": 69, + "./is": 70, + "./is.js": 70, + "./it": 71, + "./it-ch": 72, + "./it-ch.js": 72, + "./it.js": 71, + "./ja": 73, + "./ja.js": 73, + "./jv": 74, + "./jv.js": 74, + "./ka": 75, + "./ka.js": 75, + "./kk": 76, + "./kk.js": 76, + "./km": 77, + "./km.js": 77, + "./kn": 78, + "./kn.js": 78, + "./ko": 79, + "./ko.js": 79, + "./ku": 80, + "./ku.js": 80, + "./ky": 81, + "./ky.js": 81, + "./lb": 82, + "./lb.js": 82, + "./lo": 83, + "./lo.js": 83, + "./lt": 84, + "./lt.js": 84, + "./lv": 85, + "./lv.js": 85, + "./me": 86, + "./me.js": 86, + "./mi": 87, + "./mi.js": 87, + "./mk": 88, + "./mk.js": 88, + "./ml": 89, + "./ml.js": 89, + "./mn": 90, + "./mn.js": 90, + "./mr": 91, + "./mr.js": 91, + "./ms": 92, + "./ms-my": 93, + "./ms-my.js": 93, + "./ms.js": 92, + "./mt": 94, + "./mt.js": 94, + "./my": 95, + "./my.js": 95, + "./nb": 96, + "./nb.js": 96, + "./ne": 97, + "./ne.js": 97, + "./nl": 98, + "./nl-be": 99, + "./nl-be.js": 99, + "./nl.js": 98, + "./nn": 100, + "./nn.js": 100, + "./pa-in": 101, + "./pa-in.js": 101, + "./pl": 102, + "./pl.js": 102, + "./pt": 103, + "./pt-br": 104, + "./pt-br.js": 104, + "./pt.js": 103, + "./ro": 105, + "./ro.js": 105, + "./ru": 106, + "./ru.js": 106, + "./sd": 107, + "./sd.js": 107, + "./se": 108, + "./se.js": 108, + "./si": 109, + "./si.js": 109, + "./sk": 110, + "./sk.js": 110, + "./sl": 111, + "./sl.js": 111, + "./sq": 112, + "./sq.js": 112, + "./sr": 113, + "./sr-cyrl": 114, + "./sr-cyrl.js": 114, + "./sr.js": 113, + "./ss": 115, + "./ss.js": 115, + "./sv": 116, + "./sv.js": 116, + "./sw": 117, + "./sw.js": 117, + "./ta": 118, + "./ta.js": 118, + "./te": 119, + "./te.js": 119, + "./tet": 120, + "./tet.js": 120, + "./tg": 121, + "./tg.js": 121, + "./th": 122, + "./th.js": 122, + "./tl-ph": 123, + "./tl-ph.js": 123, + "./tlh": 124, + "./tlh.js": 124, + "./tr": 125, + "./tr.js": 125, + "./tzl": 126, + "./tzl.js": 126, + "./tzm": 127, + "./tzm-latn": 128, + "./tzm-latn.js": 128, + "./tzm.js": 127, + "./ug-cn": 129, + "./ug-cn.js": 129, + "./uk": 130, + "./uk.js": 130, + "./ur": 131, + "./ur.js": 131, + "./uz": 132, + "./uz-latn": 133, + "./uz-latn.js": 133, + "./uz.js": 132, + "./vi": 134, + "./vi.js": 134, + "./x-pseudo": 135, + "./x-pseudo.js": 135, + "./yo": 136, + "./yo.js": 136, + "./zh-cn": 137, + "./zh-cn.js": 137, + "./zh-hk": 138, + "./zh-hk.js": 138, + "./zh-tw": 139, + "./zh-tw.js": 139 +}; - dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); - mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); - return mom; - } - function getSetMonth (value) { - if (value != null) { - setMonth(this, value); - hooks.updateOffset(this, true); - return this; - } else { - return get(this, 'Month'); - } - } +function webpackContext(req) { + var id = webpackContextResolve(req); + return __webpack_require__(id); +} +function webpackContextResolve(req) { + if(!__webpack_require__.o(map, req)) { + var e = new Error("Cannot find module '" + req + "'"); + e.code = 'MODULE_NOT_FOUND'; + throw e; + } + return map[req]; +} +webpackContext.keys = function webpackContextKeys() { + return Object.keys(map); +}; +webpackContext.resolve = webpackContextResolve; +module.exports = webpackContext; +webpackContext.id = 12; - function getDaysInMonth () { - return daysInMonth(this.year(), this.month()); - } +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { - var defaultMonthsShortRegex = matchWord; - function monthsShortRegex (isStrict) { - if (this._monthsParseExact) { - if (!hasOwnProp(this, '_monthsRegex')) { - computeMonthsParse.call(this); - } - if (isStrict) { - return this._monthsShortStrictRegex; - } else { - return this._monthsShortRegex; - } - } else { - if (!hasOwnProp(this, '_monthsShortRegex')) { - this._monthsShortRegex = defaultMonthsShortRegex; - } - return this._monthsShortStrictRegex && isStrict ? - this._monthsShortStrictRegex : this._monthsShortRegex; - } - } +//! moment.js locale configuration - var defaultMonthsRegex = matchWord; - function monthsRegex (isStrict) { - if (this._monthsParseExact) { - if (!hasOwnProp(this, '_monthsRegex')) { - computeMonthsParse.call(this); - } - if (isStrict) { - return this._monthsStrictRegex; +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; + + + var af = moment.defineLocale('af', { + months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'), + monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'), + weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'), + weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'), + weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'), + meridiemParse: /vm|nm/i, + isPM : function (input) { + return /^nm$/i.test(input); + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 12) { + return isLower ? 'vm' : 'VM'; } else { - return this._monthsRegex; - } - } else { - if (!hasOwnProp(this, '_monthsRegex')) { - this._monthsRegex = defaultMonthsRegex; + return isLower ? 'nm' : 'NM'; } - return this._monthsStrictRegex && isStrict ? - this._monthsStrictRegex : this._monthsRegex; + }, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Vandag om] LT', + nextDay : '[Môre om] LT', + nextWeek : 'dddd [om] LT', + lastDay : '[Gister om] LT', + lastWeek : '[Laas] dddd [om] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'oor %s', + past : '%s gelede', + s : '\'n paar sekondes', + ss : '%d sekondes', + m : '\'n minuut', + mm : '%d minute', + h : '\'n uur', + hh : '%d ure', + d : '\'n dag', + dd : '%d dae', + M : '\'n maand', + MM : '%d maande', + y : '\'n jaar', + yy : '%d jaar' + }, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter + }, + week : { + dow : 1, // Maandag is die eerste dag van die week. + doy : 4 // Die week wat die 4de Januarie bevat is die eerste week van die jaar. } - } + }); - function computeMonthsParse () { - function cmpLenRev(a, b) { - return b.length - a.length; - } + return af; - var shortPieces = [], longPieces = [], mixedPieces = [], - i, mom; - for (i = 0; i < 12; i++) { - // make the regex if we don't have it already - mom = createUTC([2000, i]); - shortPieces.push(this.monthsShort(mom, '')); - longPieces.push(this.months(mom, '')); - mixedPieces.push(this.months(mom, '')); - mixedPieces.push(this.monthsShort(mom, '')); - } - // Sorting makes sure if one month (or abbr) is a prefix of another it - // will match the longer piece. - shortPieces.sort(cmpLenRev); - longPieces.sort(cmpLenRev); - mixedPieces.sort(cmpLenRev); - for (i = 0; i < 12; i++) { - shortPieces[i] = regexEscape(shortPieces[i]); - longPieces[i] = regexEscape(longPieces[i]); - } - for (i = 0; i < 24; i++) { - mixedPieces[i] = regexEscape(mixedPieces[i]); - } +}))); - this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); - this._monthsShortRegex = this._monthsRegex; - this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); - this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); - } - function createDate (y, m, d, h, M, s, ms) { - // can't just apply() to create a date: - // https://stackoverflow.com/q/181348 - var date; - // the date constructor remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0) { - // preserve leap years using a full 400 year cycle, then reset - date = new Date(y + 400, m, d, h, M, s, ms); - if (isFinite(date.getFullYear())) { - date.setFullYear(y); - } - } else { - date = new Date(y, m, d, h, M, s, ms); - } +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { - return date; - } +//! moment.js locale configuration - function createUTCDate (y) { - var date; - // the Date.UTC function remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0) { - var args = Array.prototype.slice.call(arguments); - // preserve leap years using a full 400 year cycle, then reset - args[0] = y + 400; - date = new Date(Date.UTC.apply(null, args)); - if (isFinite(date.getUTCFullYear())) { - date.setUTCFullYear(y); +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; + + + var symbolMap = { + '1': '١', + '2': '٢', + '3': '٣', + '4': '٤', + '5': '٥', + '6': '٦', + '7': '٧', + '8': '٨', + '9': '٩', + '0': '٠' + }, numberMap = { + '١': '1', + '٢': '2', + '٣': '3', + '٤': '4', + '٥': '5', + '٦': '6', + '٧': '7', + '٨': '8', + '٩': '9', + '٠': '0' + }, pluralForm = function (n) { + return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5; + }, plurals = { + s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'], + m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'], + h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'], + d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'], + M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'], + y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام'] + }, pluralize = function (u) { + return function (number, withoutSuffix, string, isFuture) { + var f = pluralForm(number), + str = plurals[u][pluralForm(number)]; + if (f === 2) { + str = str[withoutSuffix ? 0 : 1]; } - } else { - date = new Date(Date.UTC.apply(null, arguments)); + return str.replace(/%d/i, number); + }; + }, months = [ + 'يناير', + 'فبراير', + 'مارس', + 'أبريل', + 'مايو', + 'يونيو', + 'يوليو', + 'أغسطس', + 'سبتمبر', + 'أكتوبر', + 'نوفمبر', + 'ديسمبر' + ]; + + var ar = moment.defineLocale('ar', { + months : months, + monthsShort : months, + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'D/\u200FM/\u200FYYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ص|م/, + isPM : function (input) { + return 'م' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ص'; + } else { + return 'م'; + } + }, + calendar : { + sameDay: '[اليوم عند الساعة] LT', + nextDay: '[غدًا عند الساعة] LT', + nextWeek: 'dddd [عند الساعة] LT', + lastDay: '[أمس عند الساعة] LT', + lastWeek: 'dddd [عند الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'بعد %s', + past : 'منذ %s', + s : pluralize('s'), + ss : pluralize('s'), + m : pluralize('m'), + mm : pluralize('m'), + h : pluralize('h'), + hh : pluralize('h'), + d : pluralize('d'), + dd : pluralize('d'), + M : pluralize('M'), + MM : pluralize('M'), + y : pluralize('y'), + yy : pluralize('y') + }, + preparse: function (string) { + return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { + return numberMap[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }).replace(/,/g, '،'); + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 12th is the first week of the year. } + }); - return date; - } + return ar; - // start-of-first-week - start-of-year - function firstWeekOffset(year, dow, doy) { - var // first-week day -- which january is always in the first week (4 for iso, 1 for other) - fwd = 7 + dow - doy, - // first-week day local weekday -- which local weekday is fwd - fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; +}))); - return -fwdlw + fwd - 1; - } - // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday - function dayOfYearFromWeeks(year, week, weekday, dow, doy) { - var localWeekday = (7 + weekday - dow) % 7, - weekOffset = firstWeekOffset(year, dow, doy), - dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, - resYear, resDayOfYear; +/***/ }), +/* 15 */ +/***/ (function(module, exports, __webpack_require__) { - if (dayOfYear <= 0) { - resYear = year - 1; - resDayOfYear = daysInYear(resYear) + dayOfYear; - } else if (dayOfYear > daysInYear(year)) { - resYear = year + 1; - resDayOfYear = dayOfYear - daysInYear(year); - } else { - resYear = year; - resDayOfYear = dayOfYear; - } +//! moment.js locale configuration - return { - year: resYear, - dayOfYear: resDayOfYear - }; - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - function weekOfYear(mom, dow, doy) { - var weekOffset = firstWeekOffset(mom.year(), dow, doy), - week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, - resWeek, resYear; - if (week < 1) { - resYear = mom.year() - 1; - resWeek = week + weeksInYear(resYear, dow, doy); - } else if (week > weeksInYear(mom.year(), dow, doy)) { - resWeek = week - weeksInYear(mom.year(), dow, doy); - resYear = mom.year() + 1; - } else { - resYear = mom.year(); - resWeek = week; + var arDz = moment.defineLocale('ar-dz', { + months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + ss : '%d ثانية', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } + }); - return { - week: resWeek, - year: resYear - }; - } + return arDz; - function weeksInYear(year, dow, doy) { - var weekOffset = firstWeekOffset(year, dow, doy), - weekOffsetNext = firstWeekOffset(year + 1, dow, doy); - return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; - } +}))); - // FORMATTING - addFormatToken('w', ['ww', 2], 'wo', 'week'); - addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); +/***/ }), +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { - // ALIASES +//! moment.js locale configuration - addUnitAlias('week', 'w'); - addUnitAlias('isoWeek', 'W'); +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - // PRIORITIES - addUnitPriority('week', 5); - addUnitPriority('isoWeek', 5); + var arKw = moment.defineLocale('ar-kw', { + months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + ss : '%d ثانية', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 12 // The week that contains Jan 12th is the first week of the year. + } + }); - // PARSING + return arKw; - addRegexToken('w', match1to2); - addRegexToken('ww', match1to2, match2); - addRegexToken('W', match1to2); - addRegexToken('WW', match1to2, match2); +}))); - addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { - week[token.substr(0, 1)] = toInt(input); - }); - // HELPERS +/***/ }), +/* 17 */ +/***/ (function(module, exports, __webpack_require__) { - // LOCALES +//! moment.js locale configuration - function localeWeek (mom) { - return weekOfYear(mom, this._week.dow, this._week.doy).week; - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - var defaultLocaleWeek = { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - }; - function localeFirstDayOfWeek () { - return this._week.dow; - } + var symbolMap = { + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + '8': '8', + '9': '9', + '0': '0' + }, pluralForm = function (n) { + return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5; + }, plurals = { + s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'], + m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'], + h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'], + d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'], + M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'], + y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام'] + }, pluralize = function (u) { + return function (number, withoutSuffix, string, isFuture) { + var f = pluralForm(number), + str = plurals[u][pluralForm(number)]; + if (f === 2) { + str = str[withoutSuffix ? 0 : 1]; + } + return str.replace(/%d/i, number); + }; + }, months = [ + 'يناير', + 'فبراير', + 'مارس', + 'أبريل', + 'مايو', + 'يونيو', + 'يوليو', + 'أغسطس', + 'سبتمبر', + 'أكتوبر', + 'نوفمبر', + 'ديسمبر' + ]; - function localeFirstDayOfYear () { - return this._week.doy; - } + var arLy = moment.defineLocale('ar-ly', { + months : months, + monthsShort : months, + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'D/\u200FM/\u200FYYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ص|م/, + isPM : function (input) { + return 'م' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ص'; + } else { + return 'م'; + } + }, + calendar : { + sameDay: '[اليوم عند الساعة] LT', + nextDay: '[غدًا عند الساعة] LT', + nextWeek: 'dddd [عند الساعة] LT', + lastDay: '[أمس عند الساعة] LT', + lastWeek: 'dddd [عند الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'بعد %s', + past : 'منذ %s', + s : pluralize('s'), + ss : pluralize('s'), + m : pluralize('m'), + mm : pluralize('m'), + h : pluralize('h'), + hh : pluralize('h'), + d : pluralize('d'), + dd : pluralize('d'), + M : pluralize('M'), + MM : pluralize('M'), + y : pluralize('y'), + yy : pluralize('y') + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }).replace(/,/g, '،'); + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 12th is the first week of the year. + } + }); - // MOMENTS + return arLy; - function getSetWeek (input) { - var week = this.localeData().week(this); - return input == null ? week : this.add((input - week) * 7, 'd'); - } +}))); - function getSetISOWeek (input) { - var week = weekOfYear(this, 1, 4).week; - return input == null ? week : this.add((input - week) * 7, 'd'); - } - // FORMATTING +/***/ }), +/* 18 */ +/***/ (function(module, exports, __webpack_require__) { - addFormatToken('d', 0, 'do', 'day'); +//! moment.js locale configuration - addFormatToken('dd', 0, 0, function (format) { - return this.localeData().weekdaysMin(this, format); - }); +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - addFormatToken('ddd', 0, 0, function (format) { - return this.localeData().weekdaysShort(this, format); - }); - addFormatToken('dddd', 0, 0, function (format) { - return this.localeData().weekdays(this, format); + var arMa = moment.defineLocale('ar-ma', { + months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + ss : '%d ثانية', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 12th is the first week of the year. + } }); - addFormatToken('e', 0, 0, 'weekday'); - addFormatToken('E', 0, 0, 'isoWeekday'); + return arMa; - // ALIASES +}))); - addUnitAlias('day', 'd'); - addUnitAlias('weekday', 'e'); - addUnitAlias('isoWeekday', 'E'); - // PRIORITY - addUnitPriority('day', 11); - addUnitPriority('weekday', 11); - addUnitPriority('isoWeekday', 11); +/***/ }), +/* 19 */ +/***/ (function(module, exports, __webpack_require__) { - // PARSING +//! moment.js locale configuration - addRegexToken('d', match1to2); - addRegexToken('e', match1to2); - addRegexToken('E', match1to2); - addRegexToken('dd', function (isStrict, locale) { - return locale.weekdaysMinRegex(isStrict); - }); - addRegexToken('ddd', function (isStrict, locale) { - return locale.weekdaysShortRegex(isStrict); - }); - addRegexToken('dddd', function (isStrict, locale) { - return locale.weekdaysRegex(isStrict); - }); +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { - var weekday = config._locale.weekdaysParse(input, token, config._strict); - // if we didn't get a weekday name, mark the date as invalid - if (weekday != null) { - week.d = weekday; - } else { - getParsingFlags(config).invalidWeekday = input; - } - }); - addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { - week[token] = toInt(input); + var symbolMap = { + '1': '١', + '2': '٢', + '3': '٣', + '4': '٤', + '5': '٥', + '6': '٦', + '7': '٧', + '8': '٨', + '9': '٩', + '0': '٠' + }, numberMap = { + '١': '1', + '٢': '2', + '٣': '3', + '٤': '4', + '٥': '5', + '٦': '6', + '٧': '7', + '٨': '8', + '٩': '9', + '٠': '0' + }; + + var arSa = moment.defineLocale('ar-sa', { + months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ص|م/, + isPM : function (input) { + return 'م' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ص'; + } else { + return 'م'; + } + }, + calendar : { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + ss : '%d ثانية', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' + }, + preparse: function (string) { + return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { + return numberMap[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }).replace(/,/g, '،'); + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 6th is the first week of the year. + } }); - // HELPERS + return arSa; - function parseWeekday(input, locale) { - if (typeof input !== 'string') { - return input; - } +}))); - if (!isNaN(input)) { - return parseInt(input, 10); - } - input = locale.weekdaysParse(input); - if (typeof input === 'number') { - return input; - } +/***/ }), +/* 20 */ +/***/ (function(module, exports, __webpack_require__) { - return null; - } +//! moment.js locale configuration - function parseIsoWeekday(input, locale) { - if (typeof input === 'string') { - return locale.weekdaysParse(input) % 7 || 7; - } - return isNaN(input) ? null : input; - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - // LOCALES - function shiftWeekdays (ws, n) { - return ws.slice(n, 7).concat(ws.slice(0, n)); - } - var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); - function localeWeekdays (m, format) { - var weekdays = isArray(this._weekdays) ? this._weekdays : - this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone']; - return (m === true) ? shiftWeekdays(weekdays, this._week.dow) - : (m) ? weekdays[m.day()] : weekdays; - } - - var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); - function localeWeekdaysShort (m) { - return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow) - : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; - } + var arTn = moment.defineLocale('ar-tn', { + months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'), + weekdaysParseExact : true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm' + }, + calendar: { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime: { + future: 'في %s', + past: 'منذ %s', + s: 'ثوان', + ss : '%d ثانية', + m: 'دقيقة', + mm: '%d دقائق', + h: 'ساعة', + hh: '%d ساعات', + d: 'يوم', + dd: '%d أيام', + M: 'شهر', + MM: '%d أشهر', + y: 'سنة', + yy: '%d سنوات' + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } + }); - var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); - function localeWeekdaysMin (m) { - return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow) - : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; - } + return arTn; - function handleStrictParse$1(weekdayName, format, strict) { - var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); - if (!this._weekdaysParse) { - this._weekdaysParse = []; - this._shortWeekdaysParse = []; - this._minWeekdaysParse = []; +}))); - for (i = 0; i < 7; ++i) { - mom = createUTC([2000, 1]).day(i); - this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); - this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); - this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); - } - } - if (strict) { - if (format === 'dddd') { - ii = indexOf.call(this._weekdaysParse, llc); - return ii !== -1 ? ii : null; - } else if (format === 'ddd') { - ii = indexOf.call(this._shortWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._minWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } - } else { - if (format === 'dddd') { - ii = indexOf.call(this._weekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._shortWeekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._minWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } else if (format === 'ddd') { - ii = indexOf.call(this._shortWeekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._weekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._minWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._minWeekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._weekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._shortWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } - } - } +/***/ }), +/* 21 */ +/***/ (function(module, exports, __webpack_require__) { - function localeWeekdaysParse (weekdayName, format, strict) { - var i, mom, regex; +//! moment.js locale configuration - if (this._weekdaysParseExact) { - return handleStrictParse$1.call(this, weekdayName, format, strict); - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - if (!this._weekdaysParse) { - this._weekdaysParse = []; - this._minWeekdaysParse = []; - this._shortWeekdaysParse = []; - this._fullWeekdaysParse = []; - } - for (i = 0; i < 7; i++) { - // make the regex if we don't have it already + var suffixes = { + 1: '-inci', + 5: '-inci', + 8: '-inci', + 70: '-inci', + 80: '-inci', + 2: '-nci', + 7: '-nci', + 20: '-nci', + 50: '-nci', + 3: '-üncü', + 4: '-üncü', + 100: '-üncü', + 6: '-ncı', + 9: '-uncu', + 10: '-uncu', + 30: '-uncu', + 60: '-ıncı', + 90: '-ıncı' + }; - mom = createUTC([2000, 1]).day(i); - if (strict && !this._fullWeekdaysParse[i]) { - this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i'); - this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i'); - this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i'); - } - if (!this._weekdaysParse[i]) { - regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); - this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); + var az = moment.defineLocale('az', { + months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'), + monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'), + weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'), + weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'), + weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[bugün saat] LT', + nextDay : '[sabah saat] LT', + nextWeek : '[gələn həftə] dddd [saat] LT', + lastDay : '[dünən] LT', + lastWeek : '[keçən həftə] dddd [saat] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s sonra', + past : '%s əvvəl', + s : 'birneçə saniyə', + ss : '%d saniyə', + m : 'bir dəqiqə', + mm : '%d dəqiqə', + h : 'bir saat', + hh : '%d saat', + d : 'bir gün', + dd : '%d gün', + M : 'bir ay', + MM : '%d ay', + y : 'bir il', + yy : '%d il' + }, + meridiemParse: /gecə|səhər|gündüz|axşam/, + isPM : function (input) { + return /^(gündüz|axşam)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'gecə'; + } else if (hour < 12) { + return 'səhər'; + } else if (hour < 17) { + return 'gündüz'; + } else { + return 'axşam'; } - // test the regex - if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { - return i; - } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { - return i; - } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { - return i; - } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { - return i; + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/, + ordinal : function (number) { + if (number === 0) { // special case for zero + return number + '-ıncı'; } + var a = number % 10, + b = number % 100 - a, + c = number >= 100 ? 100 : null; + return number + (suffixes[a] || suffixes[b] || suffixes[c]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. } - } + }); - // MOMENTS + return az; - function getSetDayOfWeek (input) { - if (!this.isValid()) { - return input != null ? this : NaN; - } - var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); - if (input != null) { - input = parseWeekday(input, this.localeData()); - return this.add(input - day, 'd'); - } else { - return day; - } - } +}))); - function getSetLocaleDayOfWeek (input) { - if (!this.isValid()) { - return input != null ? this : NaN; - } - var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; - return input == null ? weekday : this.add(input - weekday, 'd'); - } - function getSetISODayOfWeek (input) { - if (!this.isValid()) { - return input != null ? this : NaN; - } +/***/ }), +/* 22 */ +/***/ (function(module, exports, __webpack_require__) { - // behaves the same as moment#day except - // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) - // as a setter, sunday should belong to the previous week. +//! moment.js locale configuration - if (input != null) { - var weekday = parseIsoWeekday(input, this.localeData()); - return this.day(this.day() % 7 ? weekday : weekday - 7); - } else { - return this.day() || 7; - } - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - var defaultWeekdaysRegex = matchWord; - function weekdaysRegex (isStrict) { - if (this._weekdaysParseExact) { - if (!hasOwnProp(this, '_weekdaysRegex')) { - computeWeekdaysParse.call(this); - } - if (isStrict) { - return this._weekdaysStrictRegex; - } else { - return this._weekdaysRegex; - } - } else { - if (!hasOwnProp(this, '_weekdaysRegex')) { - this._weekdaysRegex = defaultWeekdaysRegex; - } - return this._weekdaysStrictRegex && isStrict ? - this._weekdaysStrictRegex : this._weekdaysRegex; - } - } - var defaultWeekdaysShortRegex = matchWord; - function weekdaysShortRegex (isStrict) { - if (this._weekdaysParseExact) { - if (!hasOwnProp(this, '_weekdaysRegex')) { - computeWeekdaysParse.call(this); - } - if (isStrict) { - return this._weekdaysShortStrictRegex; - } else { - return this._weekdaysShortRegex; - } - } else { - if (!hasOwnProp(this, '_weekdaysShortRegex')) { - this._weekdaysShortRegex = defaultWeekdaysShortRegex; - } - return this._weekdaysShortStrictRegex && isStrict ? - this._weekdaysShortStrictRegex : this._weekdaysShortRegex; + function plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); + } + function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'ss': withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд', + 'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін', + 'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін', + 'dd': 'дзень_дні_дзён', + 'MM': 'месяц_месяцы_месяцаў', + 'yy': 'год_гады_гадоў' + }; + if (key === 'm') { + return withoutSuffix ? 'хвіліна' : 'хвіліну'; + } + else if (key === 'h') { + return withoutSuffix ? 'гадзіна' : 'гадзіну'; + } + else { + return number + ' ' + plural(format[key], +number); } } - var defaultWeekdaysMinRegex = matchWord; - function weekdaysMinRegex (isStrict) { - if (this._weekdaysParseExact) { - if (!hasOwnProp(this, '_weekdaysRegex')) { - computeWeekdaysParse.call(this); - } - if (isStrict) { - return this._weekdaysMinStrictRegex; + var be = moment.defineLocale('be', { + months : { + format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'), + standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_') + }, + monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'), + weekdays : { + format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'), + standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'), + isFormat: /\[ ?[Ууў] ?(?:мінулую|наступную)? ?\] ?dddd/ + }, + weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), + weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY г.', + LLL : 'D MMMM YYYY г., HH:mm', + LLLL : 'dddd, D MMMM YYYY г., HH:mm' + }, + calendar : { + sameDay: '[Сёння ў] LT', + nextDay: '[Заўтра ў] LT', + lastDay: '[Учора ў] LT', + nextWeek: function () { + return '[У] dddd [ў] LT'; + }, + lastWeek: function () { + switch (this.day()) { + case 0: + case 3: + case 5: + case 6: + return '[У мінулую] dddd [ў] LT'; + case 1: + case 2: + case 4: + return '[У мінулы] dddd [ў] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'праз %s', + past : '%s таму', + s : 'некалькі секунд', + m : relativeTimeWithPlural, + mm : relativeTimeWithPlural, + h : relativeTimeWithPlural, + hh : relativeTimeWithPlural, + d : 'дзень', + dd : relativeTimeWithPlural, + M : 'месяц', + MM : relativeTimeWithPlural, + y : 'год', + yy : relativeTimeWithPlural + }, + meridiemParse: /ночы|раніцы|дня|вечара/, + isPM : function (input) { + return /^(дня|вечара)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ночы'; + } else if (hour < 12) { + return 'раніцы'; + } else if (hour < 17) { + return 'дня'; } else { - return this._weekdaysMinRegex; + return 'вечара'; } - } else { - if (!hasOwnProp(this, '_weekdaysMinRegex')) { - this._weekdaysMinRegex = defaultWeekdaysMinRegex; + }, + dayOfMonthOrdinalParse: /\d{1,2}-(і|ы|га)/, + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + case 'w': + case 'W': + return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы'; + case 'D': + return number + '-га'; + default: + return number; } - return this._weekdaysMinStrictRegex && isStrict ? - this._weekdaysMinStrictRegex : this._weekdaysMinRegex; - } - } - - - function computeWeekdaysParse () { - function cmpLenRev(a, b) { - return b.length - a.length; - } - - var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], - i, mom, minp, shortp, longp; - for (i = 0; i < 7; i++) { - // make the regex if we don't have it already - mom = createUTC([2000, 1]).day(i); - minp = this.weekdaysMin(mom, ''); - shortp = this.weekdaysShort(mom, ''); - longp = this.weekdays(mom, ''); - minPieces.push(minp); - shortPieces.push(shortp); - longPieces.push(longp); - mixedPieces.push(minp); - mixedPieces.push(shortp); - mixedPieces.push(longp); - } - // Sorting makes sure if one weekday (or abbr) is a prefix of another it - // will match the longer piece. - minPieces.sort(cmpLenRev); - shortPieces.sort(cmpLenRev); - longPieces.sort(cmpLenRev); - mixedPieces.sort(cmpLenRev); - for (i = 0; i < 7; i++) { - shortPieces[i] = regexEscape(shortPieces[i]); - longPieces[i] = regexEscape(longPieces[i]); - mixedPieces[i] = regexEscape(mixedPieces[i]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. } + }); - this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); - this._weekdaysShortRegex = this._weekdaysRegex; - this._weekdaysMinRegex = this._weekdaysRegex; + return be; - this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); - this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); - this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); - } +}))); - // FORMATTING - function hFormat() { - return this.hours() % 12 || 12; - } +/***/ }), +/* 23 */ +/***/ (function(module, exports, __webpack_require__) { - function kFormat() { - return this.hours() || 24; - } +//! moment.js locale configuration - addFormatToken('H', ['HH', 2], 0, 'hour'); - addFormatToken('h', ['hh', 2], 0, hFormat); - addFormatToken('k', ['kk', 2], 0, kFormat); +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - addFormatToken('hmm', 0, 0, function () { - return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); - }); - addFormatToken('hmmss', 0, 0, function () { - return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + - zeroFill(this.seconds(), 2); - }); - - addFormatToken('Hmm', 0, 0, function () { - return '' + this.hours() + zeroFill(this.minutes(), 2); - }); - - addFormatToken('Hmmss', 0, 0, function () { - return '' + this.hours() + zeroFill(this.minutes(), 2) + - zeroFill(this.seconds(), 2); + var bg = moment.defineLocale('bg', { + months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'), + monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'), + weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'), + weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'), + weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'D.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd, D MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[Днес в] LT', + nextDay : '[Утре в] LT', + nextWeek : 'dddd [в] LT', + lastDay : '[Вчера в] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + case 6: + return '[В изминалата] dddd [в] LT'; + case 1: + case 2: + case 4: + case 5: + return '[В изминалия] dddd [в] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'след %s', + past : 'преди %s', + s : 'няколко секунди', + ss : '%d секунди', + m : 'минута', + mm : '%d минути', + h : 'час', + hh : '%d часа', + d : 'ден', + dd : '%d дни', + M : 'месец', + MM : '%d месеца', + y : 'година', + yy : '%d години' + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, + ordinal : function (number) { + var lastDigit = number % 10, + last2Digits = number % 100; + if (number === 0) { + return number + '-ев'; + } else if (last2Digits === 0) { + return number + '-ен'; + } else if (last2Digits > 10 && last2Digits < 20) { + return number + '-ти'; + } else if (lastDigit === 1) { + return number + '-ви'; + } else if (lastDigit === 2) { + return number + '-ри'; + } else if (lastDigit === 7 || lastDigit === 8) { + return number + '-ми'; + } else { + return number + '-ти'; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. + } }); - function meridiem (token, lowercase) { - addFormatToken(token, 0, 0, function () { - return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); - }); - } - - meridiem('a', true); - meridiem('A', false); - - // ALIASES - - addUnitAlias('hour', 'h'); - - // PRIORITY - addUnitPriority('hour', 13); - - // PARSING + return bg; - function matchMeridiem (isStrict, locale) { - return locale._meridiemParse; - } +}))); - addRegexToken('a', matchMeridiem); - addRegexToken('A', matchMeridiem); - addRegexToken('H', match1to2); - addRegexToken('h', match1to2); - addRegexToken('k', match1to2); - addRegexToken('HH', match1to2, match2); - addRegexToken('hh', match1to2, match2); - addRegexToken('kk', match1to2, match2); - addRegexToken('hmm', match3to4); - addRegexToken('hmmss', match5to6); - addRegexToken('Hmm', match3to4); - addRegexToken('Hmmss', match5to6); +/***/ }), +/* 24 */ +/***/ (function(module, exports, __webpack_require__) { - addParseToken(['H', 'HH'], HOUR); - addParseToken(['k', 'kk'], function (input, array, config) { - var kInput = toInt(input); - array[HOUR] = kInput === 24 ? 0 : kInput; - }); - addParseToken(['a', 'A'], function (input, array, config) { - config._isPm = config._locale.isPM(input); - config._meridiem = input; - }); - addParseToken(['h', 'hh'], function (input, array, config) { - array[HOUR] = toInt(input); - getParsingFlags(config).bigHour = true; - }); - addParseToken('hmm', function (input, array, config) { - var pos = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos)); - array[MINUTE] = toInt(input.substr(pos)); - getParsingFlags(config).bigHour = true; - }); - addParseToken('hmmss', function (input, array, config) { - var pos1 = input.length - 4; - var pos2 = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos1)); - array[MINUTE] = toInt(input.substr(pos1, 2)); - array[SECOND] = toInt(input.substr(pos2)); - getParsingFlags(config).bigHour = true; - }); - addParseToken('Hmm', function (input, array, config) { - var pos = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos)); - array[MINUTE] = toInt(input.substr(pos)); - }); - addParseToken('Hmmss', function (input, array, config) { - var pos1 = input.length - 4; - var pos2 = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos1)); - array[MINUTE] = toInt(input.substr(pos1, 2)); - array[SECOND] = toInt(input.substr(pos2)); - }); +//! moment.js locale configuration - // LOCALES +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - function localeIsPM (input) { - // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays - // Using charAt should be more compatible. - return ((input + '').toLowerCase().charAt(0) === 'p'); - } - var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; - function localeMeridiem (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'pm' : 'PM'; - } else { - return isLower ? 'am' : 'AM'; + var bm = moment.defineLocale('bm', { + months : 'Zanwuyekalo_Fewuruyekalo_Marisikalo_Awirilikalo_Mɛkalo_Zuwɛnkalo_Zuluyekalo_Utikalo_Sɛtanburukalo_ɔkutɔburukalo_Nowanburukalo_Desanburukalo'.split('_'), + monthsShort : 'Zan_Few_Mar_Awi_Mɛ_Zuw_Zul_Uti_Sɛt_ɔku_Now_Des'.split('_'), + weekdays : 'Kari_Ntɛnɛn_Tarata_Araba_Alamisa_Juma_Sibiri'.split('_'), + weekdaysShort : 'Kar_Ntɛ_Tar_Ara_Ala_Jum_Sib'.split('_'), + weekdaysMin : 'Ka_Nt_Ta_Ar_Al_Ju_Si'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'MMMM [tile] D [san] YYYY', + LLL : 'MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm', + LLLL : 'dddd MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm' + }, + calendar : { + sameDay : '[Bi lɛrɛ] LT', + nextDay : '[Sini lɛrɛ] LT', + nextWeek : 'dddd [don lɛrɛ] LT', + lastDay : '[Kunu lɛrɛ] LT', + lastWeek : 'dddd [tɛmɛnen lɛrɛ] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s kɔnɔ', + past : 'a bɛ %s bɔ', + s : 'sanga dama dama', + ss : 'sekondi %d', + m : 'miniti kelen', + mm : 'miniti %d', + h : 'lɛrɛ kelen', + hh : 'lɛrɛ %d', + d : 'tile kelen', + dd : 'tile %d', + M : 'kalo kelen', + MM : 'kalo %d', + y : 'san kelen', + yy : 'san %d' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } - } + }); + return bm; - // MOMENTS +}))); - // Setting the hour should keep the time, because the user explicitly - // specified which hour they want. So trying to maintain the same hour (in - // a new timezone) makes sense. Adding/subtracting hours does not follow - // this rule. - var getSetHour = makeGetSet('Hours', true); - var baseConfig = { - calendar: defaultCalendar, - longDateFormat: defaultLongDateFormat, - invalidDate: defaultInvalidDate, - ordinal: defaultOrdinal, - dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, - relativeTime: defaultRelativeTime, +/***/ }), +/* 25 */ +/***/ (function(module, exports, __webpack_require__) { - months: defaultLocaleMonths, - monthsShort: defaultLocaleMonthsShort, +//! moment.js locale configuration - week: defaultLocaleWeek, +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - weekdays: defaultLocaleWeekdays, - weekdaysMin: defaultLocaleWeekdaysMin, - weekdaysShort: defaultLocaleWeekdaysShort, - meridiemParse: defaultLocaleMeridiemParse + var symbolMap = { + '1': '১', + '2': '২', + '3': '৩', + '4': '৪', + '5': '৫', + '6': '৬', + '7': '৭', + '8': '৮', + '9': '৯', + '0': '০' + }, + numberMap = { + '১': '1', + '২': '2', + '৩': '3', + '৪': '4', + '৫': '5', + '৬': '6', + '৭': '7', + '৮': '8', + '৯': '9', + '০': '0' }; - // internal storage for locale config files - var locales = {}; - var localeFamilies = {}; - var globalLocale; - - function normalizeLocale(key) { - return key ? key.toLowerCase().replace('_', '-') : key; - } - - // pick the locale from the array - // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each - // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root - function chooseLocale(names) { - var i = 0, j, next, locale, split; - - while (i < names.length) { - split = normalizeLocale(names[i]).split('-'); - j = split.length; - next = normalizeLocale(names[i + 1]); - next = next ? next.split('-') : null; - while (j > 0) { - locale = loadLocale(split.slice(0, j).join('-')); - if (locale) { - return locale; - } - if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { - //the next array item is better than a shallower substring of this one - break; - } - j--; - } - i++; - } - return globalLocale; - } - - function loadLocale(name) { - var oldLocale = null; - // TODO: Find a better way to register and load all the locales in Node - if (!locales[name] && (typeof module !== 'undefined') && - module && module.exports) { - try { - oldLocale = globalLocale._abbr; - var aliasedRequire = require; - __webpack_require__(41)("./" + name); - getSetGlobalLocale(oldLocale); - } catch (e) {} - } - return locales[name]; - } - - // This function will load locale and then set the global locale. If - // no arguments are passed in, it will simply return the current global - // locale key. - function getSetGlobalLocale (key, values) { - var data; - if (key) { - if (isUndefined(values)) { - data = getLocale(key); - } - else { - data = defineLocale(key, values); + var bn = moment.defineLocale('bn', { + months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'), + monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'), + weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'), + weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'), + weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'), + longDateFormat : { + LT : 'A h:mm সময়', + LTS : 'A h:mm:ss সময়', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm সময়', + LLLL : 'dddd, D MMMM YYYY, A h:mm সময়' + }, + calendar : { + sameDay : '[আজ] LT', + nextDay : '[আগামীকাল] LT', + nextWeek : 'dddd, LT', + lastDay : '[গতকাল] LT', + lastWeek : '[গত] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s পরে', + past : '%s আগে', + s : 'কয়েক সেকেন্ড', + ss : '%d সেকেন্ড', + m : 'এক মিনিট', + mm : '%d মিনিট', + h : 'এক ঘন্টা', + hh : '%d ঘন্টা', + d : 'এক দিন', + dd : '%d দিন', + M : 'এক মাস', + MM : '%d মাস', + y : 'এক বছর', + yy : '%d বছর' + }, + preparse: function (string) { + return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; } - - if (data) { - // moment.duration._locale = moment._locale = data; - globalLocale = data; + if ((meridiem === 'রাত' && hour >= 4) || + (meridiem === 'দুপুর' && hour < 5) || + meridiem === 'বিকাল') { + return hour + 12; + } else { + return hour; } - else { - if ((typeof console !== 'undefined') && console.warn) { - //warn user if arguments are passed but the locale could not be set - console.warn('Locale ' + key + ' not found. Did you forget to load it?'); - } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'রাত'; + } else if (hour < 10) { + return 'সকাল'; + } else if (hour < 17) { + return 'দুপুর'; + } else if (hour < 20) { + return 'বিকাল'; + } else { + return 'রাত'; } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 6th is the first week of the year. } + }); - return globalLocale._abbr; - } - - function defineLocale (name, config) { - if (config !== null) { - var locale, parentConfig = baseConfig; - config.abbr = name; - if (locales[name] != null) { - deprecateSimple('defineLocaleOverride', - 'use moment.updateLocale(localeName, config) to change ' + - 'an existing locale. moment.defineLocale(localeName, ' + - 'config) should only be used for creating a new locale ' + - 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); - parentConfig = locales[name]._config; - } else if (config.parentLocale != null) { - if (locales[config.parentLocale] != null) { - parentConfig = locales[config.parentLocale]._config; - } else { - locale = loadLocale(config.parentLocale); - if (locale != null) { - parentConfig = locale._config; - } else { - if (!localeFamilies[config.parentLocale]) { - localeFamilies[config.parentLocale] = []; - } - localeFamilies[config.parentLocale].push({ - name: name, - config: config - }); - return null; - } - } - } - locales[name] = new Locale(mergeConfigs(parentConfig, config)); - - if (localeFamilies[name]) { - localeFamilies[name].forEach(function (x) { - defineLocale(x.name, x.config); - }); - } - - // backwards compat for now: also set the locale - // make sure we set the locale AFTER all child locales have been - // created, so we won't end up with the child locale set. - getSetGlobalLocale(name); + return bn; +}))); - return locales[name]; - } else { - // useful for testing - delete locales[name]; - return null; - } - } - function updateLocale(name, config) { - if (config != null) { - var locale, tmpLocale, parentConfig = baseConfig; - // MERGE - tmpLocale = loadLocale(name); - if (tmpLocale != null) { - parentConfig = tmpLocale._config; - } - config = mergeConfigs(parentConfig, config); - locale = new Locale(config); - locale.parentLocale = locales[name]; - locales[name] = locale; +/***/ }), +/* 26 */ +/***/ (function(module, exports, __webpack_require__) { - // backwards compat for now: also set the locale - getSetGlobalLocale(name); - } else { - // pass null for config to unupdate, useful for tests - if (locales[name] != null) { - if (locales[name].parentLocale != null) { - locales[name] = locales[name].parentLocale; - } else if (locales[name] != null) { - delete locales[name]; - } - } - } - return locales[name]; - } +//! moment.js locale configuration - // returns locale data - function getLocale (key) { - var locale; +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - if (key && key._locale && key._locale._abbr) { - key = key._locale._abbr; - } - if (!key) { - return globalLocale; - } + var symbolMap = { + '1': '༡', + '2': '༢', + '3': '༣', + '4': '༤', + '5': '༥', + '6': '༦', + '7': '༧', + '8': '༨', + '9': '༩', + '0': '༠' + }, + numberMap = { + '༡': '1', + '༢': '2', + '༣': '3', + '༤': '4', + '༥': '5', + '༦': '6', + '༧': '7', + '༨': '8', + '༩': '9', + '༠': '0' + }; - if (!isArray(key)) { - //short-circuit everything else - locale = loadLocale(key); - if (locale) { - return locale; + var bo = moment.defineLocale('bo', { + months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), + monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), + weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'), + weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), + weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), + longDateFormat : { + LT : 'A h:mm', + LTS : 'A h:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm', + LLLL : 'dddd, D MMMM YYYY, A h:mm' + }, + calendar : { + sameDay : '[དི་རིང] LT', + nextDay : '[སང་ཉིན] LT', + nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT', + lastDay : '[ཁ་སང] LT', + lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ལ་', + past : '%s སྔན་ལ', + s : 'ལམ་སང', + ss : '%d སྐར་ཆ།', + m : 'སྐར་མ་གཅིག', + mm : '%d སྐར་མ', + h : 'ཆུ་ཚོད་གཅིག', + hh : '%d ཆུ་ཚོད', + d : 'ཉིན་གཅིག', + dd : '%d ཉིན་', + M : 'ཟླ་བ་གཅིག', + MM : '%d ཟླ་བ', + y : 'ལོ་གཅིག', + yy : '%d ལོ' + }, + preparse: function (string) { + return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; } - key = [key]; + if ((meridiem === 'མཚན་མོ' && hour >= 4) || + (meridiem === 'ཉིན་གུང' && hour < 5) || + meridiem === 'དགོང་དག') { + return hour + 12; + } else { + return hour; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'མཚན་མོ'; + } else if (hour < 10) { + return 'ཞོགས་ཀས'; + } else if (hour < 17) { + return 'ཉིན་གུང'; + } else if (hour < 20) { + return 'དགོང་དག'; + } else { + return 'མཚན་མོ'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 6th is the first week of the year. } + }); - return chooseLocale(key); - } + return bo; - function listLocales() { - return keys(locales); - } +}))); - function checkOverflow (m) { - var overflow; - var a = m._a; - if (a && getParsingFlags(m).overflow === -2) { - overflow = - a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : - a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : - a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : - a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : - a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : - a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : - -1; +/***/ }), +/* 27 */ +/***/ (function(module, exports, __webpack_require__) { - if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { - overflow = DATE; - } - if (getParsingFlags(m)._overflowWeeks && overflow === -1) { - overflow = WEEK; - } - if (getParsingFlags(m)._overflowWeekday && overflow === -1) { - overflow = WEEKDAY; - } +//! moment.js locale configuration - getParsingFlags(m).overflow = overflow; - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - return m; - } - // Pick the first defined of two or three arguments. - function defaults(a, b, c) { - if (a != null) { - return a; + function relativeTimeWithMutation(number, withoutSuffix, key) { + var format = { + 'mm': 'munutenn', + 'MM': 'miz', + 'dd': 'devezh' + }; + return number + ' ' + mutation(format[key], number); + } + function specialMutationForYears(number) { + switch (lastNumber(number)) { + case 1: + case 3: + case 4: + case 5: + case 9: + return number + ' bloaz'; + default: + return number + ' vloaz'; } - if (b != null) { - return b; + } + function lastNumber(number) { + if (number > 9) { + return lastNumber(number % 10); } - return c; + return number; } - - function currentDateArray(config) { - // hooks is actually the exported moment object - var nowValue = new Date(hooks.now()); - if (config._useUTC) { - return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; + function mutation(text, number) { + if (number === 2) { + return softMutation(text); } - return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; + return text; } - - // convert an array to a date. - // the array should mirror the parameters below - // note: all values past the year are optional and will default to the lowest possible value. - // [year, month, day , hour, minute, second, millisecond] - function configFromArray (config) { - var i, date, input = [], currentDate, expectedWeekday, yearToUse; - - if (config._d) { - return; + function softMutation(text) { + var mutationTable = { + 'm': 'v', + 'b': 'v', + 'd': 'z' + }; + if (mutationTable[text.charAt(0)] === undefined) { + return text; } + return mutationTable[text.charAt(0)] + text.substring(1); + } - currentDate = currentDateArray(config); - - //compute day of the year from weeks and weekdays - if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { - dayOfYearFromWeekInfo(config); + var br = moment.defineLocale('br', { + months : 'Genver_C\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'), + monthsShort : 'Gen_C\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'), + weekdays : 'Sul_Lun_Meurzh_Merc\'her_Yaou_Gwener_Sadorn'.split('_'), + weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'), + weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'h[e]mm A', + LTS : 'h[e]mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D [a viz] MMMM YYYY', + LLL : 'D [a viz] MMMM YYYY h[e]mm A', + LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A' + }, + calendar : { + sameDay : '[Hiziv da] LT', + nextDay : '[Warc\'hoazh da] LT', + nextWeek : 'dddd [da] LT', + lastDay : '[Dec\'h da] LT', + lastWeek : 'dddd [paset da] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'a-benn %s', + past : '%s \'zo', + s : 'un nebeud segondennoù', + ss : '%d eilenn', + m : 'ur vunutenn', + mm : relativeTimeWithMutation, + h : 'un eur', + hh : '%d eur', + d : 'un devezh', + dd : relativeTimeWithMutation, + M : 'ur miz', + MM : relativeTimeWithMutation, + y : 'ur bloaz', + yy : specialMutationForYears + }, + dayOfMonthOrdinalParse: /\d{1,2}(añ|vet)/, + ordinal : function (number) { + var output = (number === 1) ? 'añ' : 'vet'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } + }); - //if the day of the year is set, figure out what it is - if (config._dayOfYear != null) { - yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); - - if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { - getParsingFlags(config)._overflowDayOfYear = true; - } - - date = createUTCDate(yearToUse, 0, config._dayOfYear); - config._a[MONTH] = date.getUTCMonth(); - config._a[DATE] = date.getUTCDate(); - } + return br; - // Default to current date. - // * if no year, month, day of month are given, default to today - // * if day of month is given, default month and year - // * if month is given, default only year - // * if year is given, don't default anything - for (i = 0; i < 3 && config._a[i] == null; ++i) { - config._a[i] = input[i] = currentDate[i]; - } +}))); - // Zero out whatever was not defaulted, including time - for (; i < 7; i++) { - config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; - } - // Check for 24:00:00.000 - if (config._a[HOUR] === 24 && - config._a[MINUTE] === 0 && - config._a[SECOND] === 0 && - config._a[MILLISECOND] === 0) { - config._nextDay = true; - config._a[HOUR] = 0; - } +/***/ }), +/* 28 */ +/***/ (function(module, exports, __webpack_require__) { - config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); - expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); +//! moment.js locale configuration - // Apply timezone offset from input. The actual utcOffset can be changed - // with parseZone. - if (config._tzm != null) { - config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - if (config._nextDay) { - config._a[HOUR] = 24; - } - // check for mismatching day of week - if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { - getParsingFlags(config).weekdayMismatch = true; + function translate(number, withoutSuffix, key) { + var result = number + ' '; + switch (key) { + case 'ss': + if (number === 1) { + result += 'sekunda'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sekunde'; + } else { + result += 'sekundi'; + } + return result; + case 'm': + return withoutSuffix ? 'jedna minuta' : 'jedne minute'; + case 'mm': + if (number === 1) { + result += 'minuta'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'minute'; + } else { + result += 'minuta'; + } + return result; + case 'h': + return withoutSuffix ? 'jedan sat' : 'jednog sata'; + case 'hh': + if (number === 1) { + result += 'sat'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sata'; + } else { + result += 'sati'; + } + return result; + case 'dd': + if (number === 1) { + result += 'dan'; + } else { + result += 'dana'; + } + return result; + case 'MM': + if (number === 1) { + result += 'mjesec'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'mjeseca'; + } else { + result += 'mjeseci'; + } + return result; + case 'yy': + if (number === 1) { + result += 'godina'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'godine'; + } else { + result += 'godina'; + } + return result; } } - function dayOfYearFromWeekInfo(config) { - var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; + var bs = moment.defineLocale('bs', { + months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'), + monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'), + monthsParseExact: true, + weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), + weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[danas u] LT', + nextDay : '[sutra u] LT', + nextWeek : function () { + switch (this.day()) { + case 0: + return '[u] [nedjelju] [u] LT'; + case 3: + return '[u] [srijedu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[jučer u] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + return '[prošlu] dddd [u] LT'; + case 6: + return '[prošle] [subote] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prošli] dddd [u] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'za %s', + past : 'prije %s', + s : 'par sekundi', + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : 'dan', + dd : translate, + M : 'mjesec', + MM : translate, + y : 'godinu', + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. + } + }); - w = config._w; - if (w.GG != null || w.W != null || w.E != null) { - dow = 1; - doy = 4; + return bs; - // TODO: We need to take the current isoWeekYear, but that depends on - // how we interpret now (local, utc, fixed offset). So create - // a now version of current config (take local/utc/offset flags, and - // create now). - weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); - week = defaults(w.W, 1); - weekday = defaults(w.E, 1); - if (weekday < 1 || weekday > 7) { - weekdayOverflow = true; - } - } else { - dow = config._locale._week.dow; - doy = config._locale._week.doy; +}))); - var curWeek = weekOfYear(createLocal(), dow, doy); - weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); +/***/ }), +/* 29 */ +/***/ (function(module, exports, __webpack_require__) { - // Default to current week. - week = defaults(w.w, curWeek.week); +//! moment.js locale configuration - if (w.d != null) { - // weekday -- low day numbers are considered next week - weekday = w.d; - if (weekday < 0 || weekday > 6) { - weekdayOverflow = true; - } - } else if (w.e != null) { - // local weekday -- counting starts from beginning of week - weekday = w.e + dow; - if (w.e < 0 || w.e > 6) { - weekdayOverflow = true; - } - } else { - // default to beginning of week - weekday = dow; - } - } - if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { - getParsingFlags(config)._overflowWeeks = true; - } else if (weekdayOverflow != null) { - getParsingFlags(config)._overflowWeekday = true; - } else { - temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); - config._a[YEAR] = temp.year; - config._dayOfYear = temp.dayOfYear; - } - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - // iso 8601 regex - // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) - var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; - var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; - var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; - - var isoDates = [ - ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], - ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], - ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], - ['GGGG-[W]WW', /\d{4}-W\d\d/, false], - ['YYYY-DDD', /\d{4}-\d{3}/], - ['YYYY-MM', /\d{4}-\d\d/, false], - ['YYYYYYMMDD', /[+-]\d{10}/], - ['YYYYMMDD', /\d{8}/], - // YYYYMM is NOT allowed by the standard - ['GGGG[W]WWE', /\d{4}W\d{3}/], - ['GGGG[W]WW', /\d{4}W\d{2}/, false], - ['YYYYDDD', /\d{7}/] - ]; - - // iso time formats and regexes - var isoTimes = [ - ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], - ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], - ['HH:mm:ss', /\d\d:\d\d:\d\d/], - ['HH:mm', /\d\d:\d\d/], - ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], - ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], - ['HHmmss', /\d\d\d\d\d\d/], - ['HHmm', /\d\d\d\d/], - ['HH', /\d\d/] - ]; + var ca = moment.defineLocale('ca', { + months : { + standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'), + format: 'de gener_de febrer_de març_d\'abril_de maig_de juny_de juliol_d\'agost_de setembre_d\'octubre_de novembre_de desembre'.split('_'), + isFormat: /D[oD]?(\s)+MMMM/ + }, + monthsShort : 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split('_'), + monthsParseExact : true, + weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'), + weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'), + weekdaysMin : 'dg_dl_dt_dc_dj_dv_ds'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM [de] YYYY', + ll : 'D MMM YYYY', + LLL : 'D MMMM [de] YYYY [a les] H:mm', + lll : 'D MMM YYYY, H:mm', + LLLL : 'dddd D MMMM [de] YYYY [a les] H:mm', + llll : 'ddd D MMM YYYY, H:mm' + }, + calendar : { + sameDay : function () { + return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + nextDay : function () { + return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + lastDay : function () { + return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'd\'aquí %s', + past : 'fa %s', + s : 'uns segons', + ss : '%d segons', + m : 'un minut', + mm : '%d minuts', + h : 'una hora', + hh : '%d hores', + d : 'un dia', + dd : '%d dies', + M : 'un mes', + MM : '%d mesos', + y : 'un any', + yy : '%d anys' + }, + dayOfMonthOrdinalParse: /\d{1,2}(r|n|t|è|a)/, + ordinal : function (number, period) { + var output = (number === 1) ? 'r' : + (number === 2) ? 'n' : + (number === 3) ? 'r' : + (number === 4) ? 't' : 'è'; + if (period === 'w' || period === 'W') { + output = 'a'; + } + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); - var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; + return ca; - // date from iso format - function configFromISO(config) { - var i, l, - string = config._i, - match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), - allowTime, dateFormat, timeFormat, tzFormat; +}))); - if (match) { - getParsingFlags(config).iso = true; - for (i = 0, l = isoDates.length; i < l; i++) { - if (isoDates[i][1].exec(match[1])) { - dateFormat = isoDates[i][0]; - allowTime = isoDates[i][2] !== false; - break; - } - } - if (dateFormat == null) { - config._isValid = false; - return; - } - if (match[3]) { - for (i = 0, l = isoTimes.length; i < l; i++) { - if (isoTimes[i][1].exec(match[3])) { - // match[2] should be 'T' or space - timeFormat = (match[2] || ' ') + isoTimes[i][0]; - break; - } - } - if (timeFormat == null) { - config._isValid = false; - return; - } - } - if (!allowTime && timeFormat != null) { - config._isValid = false; - return; - } - if (match[4]) { - if (tzRegex.exec(match[4])) { - tzFormat = 'Z'; - } else { - config._isValid = false; - return; - } - } - config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); - configFromStringAndFormat(config); - } else { - config._isValid = false; - } - } +/***/ }), +/* 30 */ +/***/ (function(module, exports, __webpack_require__) { - // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 - var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; +//! moment.js locale configuration - function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { - var result = [ - untruncateYear(yearStr), - defaultLocaleMonthsShort.indexOf(monthStr), - parseInt(dayStr, 10), - parseInt(hourStr, 10), - parseInt(minuteStr, 10) - ]; +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - if (secondStr) { - result.push(parseInt(secondStr, 10)); - } - return result; - } + var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'), + monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_'); - function untruncateYear(yearStr) { - var year = parseInt(yearStr, 10); - if (year <= 49) { - return 2000 + year; - } else if (year <= 999) { - return 1900 + year; - } - return year; - } + var monthsParse = [/^led/i, /^úno/i, /^bře/i, /^dub/i, /^kvě/i, /^(čvn|červen$|června)/i, /^(čvc|červenec|července)/i, /^srp/i, /^zář/i, /^říj/i, /^lis/i, /^pro/i]; + // NOTE: 'červen' is substring of 'červenec'; therefore 'červenec' must precede 'červen' in the regex to be fully matched. + // Otherwise parser matches '1. červenec' as '1. červen' + 'ec'. + var monthsRegex = /^(leden|únor|březen|duben|květen|červenec|července|červen|června|srpen|září|říjen|listopad|prosinec|led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i; - function preprocessRFC2822(s) { - // Remove comments and folding whitespace and replace multiple-spaces with a single space - return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + function plural(n) { + return (n > 1) && (n < 5) && (~~(n / 10) !== 1); } - - function checkWeekday(weekdayStr, parsedInput, config) { - if (weekdayStr) { - // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. - var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), - weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); - if (weekdayProvided !== weekdayActual) { - getParsingFlags(config).weekdayMismatch = true; - config._isValid = false; - return false; - } + function translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': // a few seconds / in a few seconds / a few seconds ago + return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami'; + case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'sekundy' : 'sekund'); + } else { + return result + 'sekundami'; + } + break; + case 'm': // a minute / in a minute / a minute ago + return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou'); + case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'minuty' : 'minut'); + } else { + return result + 'minutami'; + } + break; + case 'h': // an hour / in an hour / an hour ago + return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); + case 'hh': // 9 hours / in 9 hours / 9 hours ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'hodiny' : 'hodin'); + } else { + return result + 'hodinami'; + } + break; + case 'd': // a day / in a day / a day ago + return (withoutSuffix || isFuture) ? 'den' : 'dnem'; + case 'dd': // 9 days / in 9 days / 9 days ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'dny' : 'dní'); + } else { + return result + 'dny'; + } + break; + case 'M': // a month / in a month / a month ago + return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem'; + case 'MM': // 9 months / in 9 months / 9 months ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'měsíce' : 'měsíců'); + } else { + return result + 'měsíci'; + } + break; + case 'y': // a year / in a year / a year ago + return (withoutSuffix || isFuture) ? 'rok' : 'rokem'; + case 'yy': // 9 years / in 9 years / 9 years ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'roky' : 'let'); + } else { + return result + 'lety'; + } + break; } - return true; } - var obsOffsets = { - UT: 0, - GMT: 0, - EDT: -4 * 60, - EST: -5 * 60, - CDT: -5 * 60, - CST: -6 * 60, - MDT: -6 * 60, - MST: -7 * 60, - PDT: -7 * 60, - PST: -8 * 60 - }; - - function calculateOffset(obsOffset, militaryOffset, numOffset) { - if (obsOffset) { - return obsOffsets[obsOffset]; - } else if (militaryOffset) { - // the only allowed military tz is Z - return 0; - } else { - var hm = parseInt(numOffset, 10); - var m = hm % 100, h = (hm - m) / 100; - return h * 60 + m; + var cs = moment.defineLocale('cs', { + months : months, + monthsShort : monthsShort, + monthsRegex : monthsRegex, + monthsShortRegex : monthsRegex, + // NOTE: 'červen' is substring of 'červenec'; therefore 'červenec' must precede 'červen' in the regex to be fully matched. + // Otherwise parser matches '1. červenec' as '1. červen' + 'ec'. + monthsStrictRegex : /^(leden|ledna|února|únor|březen|března|duben|dubna|květen|května|červenec|července|červen|června|srpen|srpna|září|říjen|října|listopadu|listopad|prosinec|prosince)/i, + monthsShortStrictRegex : /^(led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i, + monthsParse : monthsParse, + longMonthsParse : monthsParse, + shortMonthsParse : monthsParse, + weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'), + weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'), + weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'), + longDateFormat : { + LT: 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd D. MMMM YYYY H:mm', + l : 'D. M. YYYY' + }, + calendar : { + sameDay: '[dnes v] LT', + nextDay: '[zítra v] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[v neděli v] LT'; + case 1: + case 2: + return '[v] dddd [v] LT'; + case 3: + return '[ve středu v] LT'; + case 4: + return '[ve čtvrtek v] LT'; + case 5: + return '[v pátek v] LT'; + case 6: + return '[v sobotu v] LT'; + } + }, + lastDay: '[včera v] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[minulou neděli v] LT'; + case 1: + case 2: + return '[minulé] dddd [v] LT'; + case 3: + return '[minulou středu v] LT'; + case 4: + case 5: + return '[minulý] dddd [v] LT'; + case 6: + return '[minulou sobotu v] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'za %s', + past : 'před %s', + s : translate, + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate + }, + dayOfMonthOrdinalParse : /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } - } + }); - // date and time from ref 2822 format - function configFromRFC2822(config) { - var match = rfc2822.exec(preprocessRFC2822(config._i)); - if (match) { - var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); - if (!checkWeekday(match[1], parsedArray, config)) { - return; - } + return cs; - config._a = parsedArray; - config._tzm = calculateOffset(match[8], match[9], match[10]); +}))); - config._d = createUTCDate.apply(null, config._a); - config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); - getParsingFlags(config).rfc2822 = true; - } else { - config._isValid = false; - } - } +/***/ }), +/* 31 */ +/***/ (function(module, exports, __webpack_require__) { - // date from iso format or fallback - function configFromString(config) { - var matched = aspNetJsonRegex.exec(config._i); +//! moment.js locale configuration - if (matched !== null) { - config._d = new Date(+matched[1]); - return; - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - configFromISO(config); - if (config._isValid === false) { - delete config._isValid; - } else { - return; - } - configFromRFC2822(config); - if (config._isValid === false) { - delete config._isValid; - } else { - return; + var cv = moment.defineLocale('cv', { + months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'), + monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'), + weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'), + weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'), + weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]', + LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm', + LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm' + }, + calendar : { + sameDay: '[Паян] LT [сехетре]', + nextDay: '[Ыран] LT [сехетре]', + lastDay: '[Ӗнер] LT [сехетре]', + nextWeek: '[Ҫитес] dddd LT [сехетре]', + lastWeek: '[Иртнӗ] dddd LT [сехетре]', + sameElse: 'L' + }, + relativeTime : { + future : function (output) { + var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран'; + return output + affix; + }, + past : '%s каялла', + s : 'пӗр-ик ҫеккунт', + ss : '%d ҫеккунт', + m : 'пӗр минут', + mm : '%d минут', + h : 'пӗр сехет', + hh : '%d сехет', + d : 'пӗр кун', + dd : '%d кун', + M : 'пӗр уйӑх', + MM : '%d уйӑх', + y : 'пӗр ҫул', + yy : '%d ҫул' + }, + dayOfMonthOrdinalParse: /\d{1,2}-мӗш/, + ordinal : '%d-мӗш', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. } + }); - // Final attempt, use Input Fallback - hooks.createFromInputFallback(config); - } + return cv; - hooks.createFromInputFallback = deprecate( - 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + - 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + - 'discouraged and will be removed in an upcoming major release. Please refer to ' + - 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', - function (config) { - config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); - } - ); +}))); - // constant that refers to the ISO standard - hooks.ISO_8601 = function () {}; - // constant that refers to the RFC 2822 form - hooks.RFC_2822 = function () {}; +/***/ }), +/* 32 */ +/***/ (function(module, exports, __webpack_require__) { - // date from string and format string - function configFromStringAndFormat(config) { - // TODO: Move this to another part of the creation flow to prevent circular deps - if (config._f === hooks.ISO_8601) { - configFromISO(config); - return; - } - if (config._f === hooks.RFC_2822) { - configFromRFC2822(config); - return; - } - config._a = []; - getParsingFlags(config).empty = true; +//! moment.js locale configuration - // This array is used to make a Date, either with `new Date` or `Date.UTC` - var string = '' + config._i, - i, parsedInput, tokens, token, skipped, - stringLength = string.length, - totalParsedInputLength = 0; +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; - for (i = 0; i < tokens.length; i++) { - token = tokens[i]; - parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; - // console.log('token', token, 'parsedInput', parsedInput, - // 'regex', getParseRegexForToken(token, config)); - if (parsedInput) { - skipped = string.substr(0, string.indexOf(parsedInput)); - if (skipped.length > 0) { - getParsingFlags(config).unusedInput.push(skipped); - } - string = string.slice(string.indexOf(parsedInput) + parsedInput.length); - totalParsedInputLength += parsedInput.length; - } - // don't parse if it's not a known token - if (formatTokenFunctions[token]) { - if (parsedInput) { - getParsingFlags(config).empty = false; - } - else { - getParsingFlags(config).unusedTokens.push(token); + var cy = moment.defineLocale('cy', { + months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'), + monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'), + weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'), + weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'), + weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'), + weekdaysParseExact : true, + // time formats are the same as en-gb + longDateFormat: { + LT: 'HH:mm', + LTS : 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm' + }, + calendar: { + sameDay: '[Heddiw am] LT', + nextDay: '[Yfory am] LT', + nextWeek: 'dddd [am] LT', + lastDay: '[Ddoe am] LT', + lastWeek: 'dddd [diwethaf am] LT', + sameElse: 'L' + }, + relativeTime: { + future: 'mewn %s', + past: '%s yn ôl', + s: 'ychydig eiliadau', + ss: '%d eiliad', + m: 'munud', + mm: '%d munud', + h: 'awr', + hh: '%d awr', + d: 'diwrnod', + dd: '%d diwrnod', + M: 'mis', + MM: '%d mis', + y: 'blwyddyn', + yy: '%d flynedd' + }, + dayOfMonthOrdinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/, + // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh + ordinal: function (number) { + var b = number, + output = '', + lookup = [ + '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed + 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed + ]; + if (b > 20) { + if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) { + output = 'fed'; // not 30ain, 70ain or 90ain + } else { + output = 'ain'; } - addTimeToArrayFromToken(token, parsedInput, config); - } - else if (config._strict && !parsedInput) { - getParsingFlags(config).unusedTokens.push(token); + } else if (b > 0) { + output = lookup[b]; } + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } + }); - // add remaining unparsed input length to the string - getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; - if (string.length > 0) { - getParsingFlags(config).unusedInput.push(string); - } + return cy; - // clear _12h flag if hour is <= 12 - if (config._a[HOUR] <= 12 && - getParsingFlags(config).bigHour === true && - config._a[HOUR] > 0) { - getParsingFlags(config).bigHour = undefined; - } +}))); - getParsingFlags(config).parsedDateParts = config._a.slice(0); - getParsingFlags(config).meridiem = config._meridiem; - // handle meridiem - config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); - configFromArray(config); - checkOverflow(config); - } +/***/ }), +/* 33 */ +/***/ (function(module, exports, __webpack_require__) { +//! moment.js locale configuration - function meridiemFixWrap (locale, hour, meridiem) { - var isPm; +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - if (meridiem == null) { - // nothing to do - return hour; - } - if (locale.meridiemHour != null) { - return locale.meridiemHour(hour, meridiem); - } else if (locale.isPM != null) { - // Fallback - isPm = locale.isPM(meridiem); - if (isPm && hour < 12) { - hour += 12; - } - if (!isPm && hour === 12) { - hour = 0; - } - return hour; - } else { - // this is not supposed to happen - return hour; + + var da = moment.defineLocale('da', { + months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'), + monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), + weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), + weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'), + weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd [d.] D. MMMM YYYY [kl.] HH:mm' + }, + calendar : { + sameDay : '[i dag kl.] LT', + nextDay : '[i morgen kl.] LT', + nextWeek : 'på dddd [kl.] LT', + lastDay : '[i går kl.] LT', + lastWeek : '[i] dddd[s kl.] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'om %s', + past : '%s siden', + s : 'få sekunder', + ss : '%d sekunder', + m : 'et minut', + mm : '%d minutter', + h : 'en time', + hh : '%d timer', + d : 'en dag', + dd : '%d dage', + M : 'en måned', + MM : '%d måneder', + y : 'et år', + yy : '%d år' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } - } + }); - // date from string and array of format strings - function configFromStringAndArray(config) { - var tempConfig, - bestMoment, + return da; - scoreToBeat, - i, - currentScore; +}))); - if (config._f.length === 0) { - getParsingFlags(config).invalidFormat = true; - config._d = new Date(NaN); - return; - } - for (i = 0; i < config._f.length; i++) { - currentScore = 0; - tempConfig = copyConfig({}, config); - if (config._useUTC != null) { - tempConfig._useUTC = config._useUTC; - } - tempConfig._f = config._f[i]; - configFromStringAndFormat(tempConfig); +/***/ }), +/* 34 */ +/***/ (function(module, exports, __webpack_require__) { - if (!isValid(tempConfig)) { - continue; - } +//! moment.js locale configuration - // if there is any input that was not parsed add a penalty for that format - currentScore += getParsingFlags(tempConfig).charsLeftOver; +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - //or tokens - currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; - getParsingFlags(tempConfig).score = currentScore; + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eine Minute', 'einer Minute'], + 'h': ['eine Stunde', 'einer Stunde'], + 'd': ['ein Tag', 'einem Tag'], + 'dd': [number + ' Tage', number + ' Tagen'], + 'M': ['ein Monat', 'einem Monat'], + 'MM': [number + ' Monate', number + ' Monaten'], + 'y': ['ein Jahr', 'einem Jahr'], + 'yy': [number + ' Jahre', number + ' Jahren'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } - if (scoreToBeat == null || currentScore < scoreToBeat) { - scoreToBeat = currentScore; - bestMoment = tempConfig; - } + var de = moment.defineLocale('de', { + months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort : 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'), + monthsParseExact : true, + weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), + weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), + weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd, D. MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]' + }, + relativeTime : { + future : 'in %s', + past : 'vor %s', + s : 'ein paar Sekunden', + ss : '%d Sekunden', + m : processRelativeTime, + mm : '%d Minuten', + h : processRelativeTime, + hh : '%d Stunden', + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } + }); - extend(config, bestMoment || tempConfig); - } + return de; - function configFromObject(config) { - if (config._d) { - return; - } +}))); - var i = normalizeObjectUnits(config._i); - config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { - return obj && parseInt(obj, 10); - }); - configFromArray(config); +/***/ }), +/* 35 */ +/***/ (function(module, exports, __webpack_require__) { + +//! moment.js locale configuration + +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; + + + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eine Minute', 'einer Minute'], + 'h': ['eine Stunde', 'einer Stunde'], + 'd': ['ein Tag', 'einem Tag'], + 'dd': [number + ' Tage', number + ' Tagen'], + 'M': ['ein Monat', 'einem Monat'], + 'MM': [number + ' Monate', number + ' Monaten'], + 'y': ['ein Jahr', 'einem Jahr'], + 'yy': [number + ' Jahre', number + ' Jahren'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; } - function createFromConfig (config) { - var res = new Moment(checkOverflow(prepareConfig(config))); - if (res._nextDay) { - // Adding is smart enough around DST - res.add(1, 'd'); - res._nextDay = undefined; + var deAt = moment.defineLocale('de-at', { + months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort : 'Jän._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'), + monthsParseExact : true, + weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), + weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), + weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd, D. MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]' + }, + relativeTime : { + future : 'in %s', + past : 'vor %s', + s : 'ein paar Sekunden', + ss : '%d Sekunden', + m : processRelativeTime, + mm : '%d Minuten', + h : processRelativeTime, + hh : '%d Stunden', + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } + }); - return res; - } + return deAt; - function prepareConfig (config) { - var input = config._i, - format = config._f; +}))); - config._locale = config._locale || getLocale(config._l); - if (input === null || (format === undefined && input === '')) { - return createInvalid({nullInput: true}); - } +/***/ }), +/* 36 */ +/***/ (function(module, exports, __webpack_require__) { - if (typeof input === 'string') { - config._i = input = config._locale.preparse(input); - } +//! moment.js locale configuration - if (isMoment(input)) { - return new Moment(checkOverflow(input)); - } else if (isDate(input)) { - config._d = input; - } else if (isArray(format)) { - configFromStringAndArray(config); - } else if (format) { - configFromStringAndFormat(config); - } else { - configFromInput(config); - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - if (!isValid(config)) { - config._d = null; - } - return config; + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eine Minute', 'einer Minute'], + 'h': ['eine Stunde', 'einer Stunde'], + 'd': ['ein Tag', 'einem Tag'], + 'dd': [number + ' Tage', number + ' Tagen'], + 'M': ['ein Monat', 'einem Monat'], + 'MM': [number + ' Monate', number + ' Monaten'], + 'y': ['ein Jahr', 'einem Jahr'], + 'yy': [number + ' Jahre', number + ' Jahren'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; } - function configFromInput(config) { - var input = config._i; - if (isUndefined(input)) { - config._d = new Date(hooks.now()); - } else if (isDate(input)) { - config._d = new Date(input.valueOf()); - } else if (typeof input === 'string') { - configFromString(config); - } else if (isArray(input)) { - config._a = map(input.slice(0), function (obj) { - return parseInt(obj, 10); - }); - configFromArray(config); - } else if (isObject(input)) { - configFromObject(config); - } else if (isNumber(input)) { - // from milliseconds - config._d = new Date(input); - } else { - hooks.createFromInputFallback(config); + var deCh = moment.defineLocale('de-ch', { + months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort : 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'), + monthsParseExact : true, + weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), + weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd, D. MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]' + }, + relativeTime : { + future : 'in %s', + past : 'vor %s', + s : 'ein paar Sekunden', + ss : '%d Sekunden', + m : processRelativeTime, + mm : '%d Minuten', + h : processRelativeTime, + hh : '%d Stunden', + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } - } + }); - function createLocalOrUTC (input, format, locale, strict, isUTC) { - var c = {}; + return deCh; - if (locale === true || locale === false) { - strict = locale; - locale = undefined; - } +}))); - if ((isObject(input) && isObjectEmpty(input)) || - (isArray(input) && input.length === 0)) { - input = undefined; - } - // object construction must be done this way. - // https://github.com/moment/moment/issues/1423 - c._isAMomentObject = true; - c._useUTC = c._isUTC = isUTC; - c._l = locale; - c._i = input; - c._f = format; - c._strict = strict; - return createFromConfig(c); - } +/***/ }), +/* 37 */ +/***/ (function(module, exports, __webpack_require__) { - function createLocal (input, format, locale, strict) { - return createLocalOrUTC(input, format, locale, strict, false); - } +//! moment.js locale configuration - var prototypeMin = deprecate( - 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', - function () { - var other = createLocal.apply(null, arguments); - if (this.isValid() && other.isValid()) { - return other < this ? this : other; - } else { - return createInvalid(); - } - } - ); +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - var prototypeMax = deprecate( - 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', - function () { - var other = createLocal.apply(null, arguments); - if (this.isValid() && other.isValid()) { - return other > this ? this : other; + + var months = [ + 'ޖެނުއަރީ', + 'ފެބްރުއަރީ', + 'މާރިޗު', + 'އޭޕްރީލު', + 'މޭ', + 'ޖޫން', + 'ޖުލައި', + 'އޯގަސްޓު', + 'ސެޕްޓެމްބަރު', + 'އޮކްޓޯބަރު', + 'ނޮވެމްބަރު', + 'ޑިސެމްބަރު' + ], weekdays = [ + 'އާދިއްތަ', + 'ހޯމަ', + 'އަންގާރަ', + 'ބުދަ', + 'ބުރާސްފަތި', + 'ހުކުރު', + 'ހޮނިހިރު' + ]; + + var dv = moment.defineLocale('dv', { + months : months, + monthsShort : months, + weekdays : weekdays, + weekdaysShort : weekdays, + weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'), + longDateFormat : { + + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'D/M/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /މކ|މފ/, + isPM : function (input) { + return 'މފ' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'މކ'; } else { - return createInvalid(); + return 'މފ'; } + }, + calendar : { + sameDay : '[މިއަދު] LT', + nextDay : '[މާދަމާ] LT', + nextWeek : 'dddd LT', + lastDay : '[އިއްޔެ] LT', + lastWeek : '[ފާއިތުވި] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ތެރޭގައި %s', + past : 'ކުރިން %s', + s : 'ސިކުންތުކޮޅެއް', + ss : 'd% ސިކުންތު', + m : 'މިނިޓެއް', + mm : 'މިނިޓު %d', + h : 'ގަޑިއިރެއް', + hh : 'ގަޑިއިރު %d', + d : 'ދުވަހެއް', + dd : 'ދުވަސް %d', + M : 'މަހެއް', + MM : 'މަސް %d', + y : 'އަހަރެއް', + yy : 'އަހަރު %d' + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week : { + dow : 7, // Sunday is the first day of the week. + doy : 12 // The week that contains Jan 12th is the first week of the year. } - ); + }); - // Pick a moment m from moments so that m[fn](other) is true for all - // other. This relies on the function fn to be transitive. - // - // moments should either be an array of moment objects or an array, whose - // first element is an array of moment objects. - function pickBy(fn, moments) { - var res, i; - if (moments.length === 1 && isArray(moments[0])) { - moments = moments[0]; - } - if (!moments.length) { - return createLocal(); - } - res = moments[0]; - for (i = 1; i < moments.length; ++i) { - if (!moments[i].isValid() || moments[i][fn](res)) { - res = moments[i]; - } - } - return res; - } + return dv; - // TODO: Use [].sort instead? - function min () { - var args = [].slice.call(arguments, 0); +}))); - return pickBy('isBefore', args); - } - function max () { - var args = [].slice.call(arguments, 0); +/***/ }), +/* 38 */ +/***/ (function(module, exports, __webpack_require__) { - return pickBy('isAfter', args); - } +//! moment.js locale configuration - var now = function () { - return Date.now ? Date.now() : +(new Date()); - }; +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; + function isFunction(input) { + return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; + } - function isDurationValid(m) { - for (var key in m) { - if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { - return false; - } - } - var unitHasDecimal = false; - for (var i = 0; i < ordering.length; ++i) { - if (m[ordering[i]]) { - if (unitHasDecimal) { - return false; // only allow non-integers for smallest unit - } - if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { - unitHasDecimal = true; + var el = moment.defineLocale('el', { + monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'), + monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'), + months : function (momentToFormat, format) { + if (!momentToFormat) { + return this._monthsNominativeEl; + } else if (typeof format === 'string' && /D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM' + return this._monthsGenitiveEl[momentToFormat.month()]; + } else { + return this._monthsNominativeEl[momentToFormat.month()]; + } + }, + monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'), + weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'), + weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'), + weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'), + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'μμ' : 'ΜΜ'; + } else { + return isLower ? 'πμ' : 'ΠΜ'; + } + }, + isPM : function (input) { + return ((input + '').toLowerCase()[0] === 'μ'); + }, + meridiemParse : /[ΠΜ]\.?Μ?\.?/i, + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendarEl : { + sameDay : '[Σήμερα {}] LT', + nextDay : '[Αύριο {}] LT', + nextWeek : 'dddd [{}] LT', + lastDay : '[Χθες {}] LT', + lastWeek : function () { + switch (this.day()) { + case 6: + return '[το προηγούμενο] dddd [{}] LT'; + default: + return '[την προηγούμενη] dddd [{}] LT'; } + }, + sameElse : 'L' + }, + calendar : function (key, mom) { + var output = this._calendarEl[key], + hours = mom && mom.hours(); + if (isFunction(output)) { + output = output.apply(mom); } + return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις')); + }, + relativeTime : { + future : 'σε %s', + past : '%s πριν', + s : 'λίγα δευτερόλεπτα', + ss : '%d δευτερόλεπτα', + m : 'ένα λεπτό', + mm : '%d λεπτά', + h : 'μία ώρα', + hh : '%d ώρες', + d : 'μία μέρα', + dd : '%d μέρες', + M : 'ένας μήνας', + MM : '%d μήνες', + y : 'ένας χρόνος', + yy : '%d χρόνια' + }, + dayOfMonthOrdinalParse: /\d{1,2}η/, + ordinal: '%dη', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4st is the first week of the year. } + }); - return true; - } - - function isValid$1() { - return this._isValid; - } - - function createInvalid$1() { - return createDuration(NaN); - } - - function Duration (duration) { - var normalizedInput = normalizeObjectUnits(duration), - years = normalizedInput.year || 0, - quarters = normalizedInput.quarter || 0, - months = normalizedInput.month || 0, - weeks = normalizedInput.week || normalizedInput.isoWeek || 0, - days = normalizedInput.day || 0, - hours = normalizedInput.hour || 0, - minutes = normalizedInput.minute || 0, - seconds = normalizedInput.second || 0, - milliseconds = normalizedInput.millisecond || 0; + return el; - this._isValid = isDurationValid(normalizedInput); +}))); - // representation for dateAddRemove - this._milliseconds = +milliseconds + - seconds * 1e3 + // 1000 - minutes * 6e4 + // 1000 * 60 - hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 - // Because of dateAddRemove treats 24 hours as different from a - // day when working around DST, we need to store them separately - this._days = +days + - weeks * 7; - // It is impossible to translate months into days without knowing - // which months you are are talking about, so we have to store - // it separately. - this._months = +months + - quarters * 3 + - years * 12; - this._data = {}; +/***/ }), +/* 39 */ +/***/ (function(module, exports, __webpack_require__) { - this._locale = getLocale(); +//! moment.js locale configuration - this._bubble(); - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - function isDuration (obj) { - return obj instanceof Duration; - } - function absRound (number) { - if (number < 0) { - return Math.round(-1 * number) * -1; - } else { - return Math.round(number); + var enSG = moment.defineLocale('en-SG', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } - } - - // FORMATTING + }); - function offset (token, separator) { - addFormatToken(token, 0, 0, function () { - var offset = this.utcOffset(); - var sign = '+'; - if (offset < 0) { - offset = -offset; - sign = '-'; - } - return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); - }); - } + return enSG; - offset('Z', ':'); - offset('ZZ', ''); +}))); - // PARSING - addRegexToken('Z', matchShortOffset); - addRegexToken('ZZ', matchShortOffset); - addParseToken(['Z', 'ZZ'], function (input, array, config) { - config._useUTC = true; - config._tzm = offsetFromString(matchShortOffset, input); - }); +/***/ }), +/* 40 */ +/***/ (function(module, exports, __webpack_require__) { - // HELPERS +//! moment.js locale configuration - // timezone chunker - // '+10:00' > ['10', '00'] - // '-1530' > ['-15', '30'] - var chunkOffset = /([\+\-]|\d\d)/gi; +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - function offsetFromString(matcher, string) { - var matches = (string || '').match(matcher); - if (matches === null) { - return null; + var enAu = moment.defineLocale('en-au', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } + }); - var chunk = matches[matches.length - 1] || []; - var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; - var minutes = +(parts[1] * 60) + toInt(parts[2]); + return enAu; - return minutes === 0 ? - 0 : - parts[0] === '+' ? minutes : -minutes; - } +}))); - // Return a moment from input, that is local/utc/zone equivalent to model. - function cloneWithOffset(input, model) { - var res, diff; - if (model._isUTC) { - res = model.clone(); - diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); - // Use low-level api, because this fn is low-level api. - res._d.setTime(res._d.valueOf() + diff); - hooks.updateOffset(res, false); - return res; - } else { - return createLocal(input).local(); - } - } - function getDateOffset (m) { - // On Firefox.24 Date#getTimezoneOffset returns a floating point. - // https://github.com/moment/moment/pull/1871 - return -Math.round(m._d.getTimezoneOffset() / 15) * 15; - } +/***/ }), +/* 41 */ +/***/ (function(module, exports, __webpack_require__) { - // HOOKS +//! moment.js locale configuration - // This function will be called whenever a moment is mutated. - // It is intended to keep the offset in sync with the timezone. - hooks.updateOffset = function () {}; +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - // MOMENTS - // keepLocalTime = true means only change the timezone, without - // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> - // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset - // +0200, so we adjust the time as needed, to be valid. - // - // Keeping the time actually adds/subtracts (one hour) - // from the actual represented time. That is why we call updateOffset - // a second time. In case it wants us to change the offset again - // _changeInProgress == true case, then we have to adjust, because - // there is no such time in the given timezone. - function getSetOffset (input, keepLocalTime, keepMinutes) { - var offset = this._offset || 0, - localAdjust; - if (!this.isValid()) { - return input != null ? this : NaN; - } - if (input != null) { - if (typeof input === 'string') { - input = offsetFromString(matchShortOffset, input); - if (input === null) { - return this; - } - } else if (Math.abs(input) < 16 && !keepMinutes) { - input = input * 60; - } - if (!this._isUTC && keepLocalTime) { - localAdjust = getDateOffset(this); - } - this._offset = input; - this._isUTC = true; - if (localAdjust != null) { - this.add(localAdjust, 'm'); - } - if (offset !== input) { - if (!keepLocalTime || this._changeInProgress) { - addSubtract(this, createDuration(input - offset, 'm'), 1, false); - } else if (!this._changeInProgress) { - this._changeInProgress = true; - hooks.updateOffset(this, true); - this._changeInProgress = null; - } - } - return this; - } else { - return this._isUTC ? offset : getDateOffset(this); + var enCa = moment.defineLocale('en-ca', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'YYYY-MM-DD', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY h:mm A', + LLLL : 'dddd, MMMM D, YYYY h:mm A' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; } - } + }); - function getSetZone (input, keepLocalTime) { - if (input != null) { - if (typeof input !== 'string') { - input = -input; - } + return enCa; - this.utcOffset(input, keepLocalTime); +}))); - return this; - } else { - return -this.utcOffset(); - } - } - function setOffsetToUTC (keepLocalTime) { - return this.utcOffset(0, keepLocalTime); - } +/***/ }), +/* 42 */ +/***/ (function(module, exports, __webpack_require__) { - function setOffsetToLocal (keepLocalTime) { - if (this._isUTC) { - this.utcOffset(0, keepLocalTime); - this._isUTC = false; +//! moment.js locale configuration - if (keepLocalTime) { - this.subtract(getDateOffset(this), 'm'); - } - } - return this; - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - function setOffsetToParsedOffset () { - if (this._tzm != null) { - this.utcOffset(this._tzm, false, true); - } else if (typeof this._i === 'string') { - var tZone = offsetFromString(matchOffset, this._i); - if (tZone != null) { - this.utcOffset(tZone); - } - else { - this.utcOffset(0, true); - } - } - return this; - } - function hasAlignedHourOffset (input) { - if (!this.isValid()) { - return false; + var enGb = moment.defineLocale('en-gb', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } - input = input ? createLocal(input).utcOffset() : 0; - - return (this.utcOffset() - input) % 60 === 0; - } + }); - function isDaylightSavingTime () { - return ( - this.utcOffset() > this.clone().month(0).utcOffset() || - this.utcOffset() > this.clone().month(5).utcOffset() - ); - } + return enGb; - function isDaylightSavingTimeShifted () { - if (!isUndefined(this._isDSTShifted)) { - return this._isDSTShifted; - } +}))); - var c = {}; - copyConfig(c, this); - c = prepareConfig(c); +/***/ }), +/* 43 */ +/***/ (function(module, exports, __webpack_require__) { - if (c._a) { - var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); - this._isDSTShifted = this.isValid() && - compareArrays(c._a, other.toArray()) > 0; - } else { - this._isDSTShifted = false; - } +//! moment.js locale configuration - return this._isDSTShifted; - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - function isLocal () { - return this.isValid() ? !this._isUTC : false; - } - function isUtcOffset () { - return this.isValid() ? this._isUTC : false; - } + var enIe = moment.defineLocale('en-ie', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); - function isUtc () { - return this.isValid() ? this._isUTC && this._offset === 0 : false; - } + return enIe; - // ASP.NET json date format regex - var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; +}))); - // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html - // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere - // and further modified to allow for strings containing both week and day - var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; - function createDuration (input, key) { - var duration = input, - // matching against regexp is expensive, do it on demand - match = null, - sign, - ret, - diffRes; +/***/ }), +/* 44 */ +/***/ (function(module, exports, __webpack_require__) { - if (isDuration(input)) { - duration = { - ms : input._milliseconds, - d : input._days, - M : input._months - }; - } else if (isNumber(input)) { - duration = {}; - if (key) { - duration[key] = input; - } else { - duration.milliseconds = input; - } - } else if (!!(match = aspNetRegex.exec(input))) { - sign = (match[1] === '-') ? -1 : 1; - duration = { - y : 0, - d : toInt(match[DATE]) * sign, - h : toInt(match[HOUR]) * sign, - m : toInt(match[MINUTE]) * sign, - s : toInt(match[SECOND]) * sign, - ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match - }; - } else if (!!(match = isoRegex.exec(input))) { - sign = (match[1] === '-') ? -1 : 1; - duration = { - y : parseIso(match[2], sign), - M : parseIso(match[3], sign), - w : parseIso(match[4], sign), - d : parseIso(match[5], sign), - h : parseIso(match[6], sign), - m : parseIso(match[7], sign), - s : parseIso(match[8], sign) - }; - } else if (duration == null) {// checks for null or undefined - duration = {}; - } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { - diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); +//! moment.js locale configuration - duration = {}; - duration.ms = diffRes.milliseconds; - duration.M = diffRes.months; - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - ret = new Duration(duration); - if (isDuration(input) && hasOwnProp(input, '_locale')) { - ret._locale = input._locale; + var enIl = moment.defineLocale('en-il', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; } + }); - return ret; - } + return enIl; - createDuration.fn = Duration.prototype; - createDuration.invalid = createInvalid$1; +}))); - function parseIso (inp, sign) { - // We'd normally use ~~inp for this, but unfortunately it also - // converts floats to ints. - // inp may be undefined, so careful calling replace on it. - var res = inp && parseFloat(inp.replace(',', '.')); - // apply sign while we're at it - return (isNaN(res) ? 0 : res) * sign; - } - function positiveMomentsDifference(base, other) { - var res = {}; +/***/ }), +/* 45 */ +/***/ (function(module, exports, __webpack_require__) { - res.months = other.month() - base.month() + - (other.year() - base.year()) * 12; - if (base.clone().add(res.months, 'M').isAfter(other)) { - --res.months; - } +//! moment.js locale configuration - res.milliseconds = +other - +(base.clone().add(res.months, 'M')); +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - return res; - } - function momentsDifference(base, other) { - var res; - if (!(base.isValid() && other.isValid())) { - return {milliseconds: 0, months: 0}; + var enNz = moment.defineLocale('en-nz', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } + }); - other = cloneWithOffset(other, base); - if (base.isBefore(other)) { - res = positiveMomentsDifference(base, other); - } else { - res = positiveMomentsDifference(other, base); - res.milliseconds = -res.milliseconds; - res.months = -res.months; - } + return enNz; - return res; - } +}))); - // TODO: remove 'name' arg after deprecation is removed - function createAdder(direction, name) { - return function (val, period) { - var dur, tmp; - //invert the arguments, but complain about it - if (period !== null && !isNaN(+period)) { - deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + - 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); - tmp = val; val = period; period = tmp; - } - val = typeof val === 'string' ? +val : val; - dur = createDuration(val, period); - addSubtract(this, dur, direction); - return this; - }; - } +/***/ }), +/* 46 */ +/***/ (function(module, exports, __webpack_require__) { - function addSubtract (mom, duration, isAdding, updateOffset) { - var milliseconds = duration._milliseconds, - days = absRound(duration._days), - months = absRound(duration._months); +//! moment.js locale configuration - if (!mom.isValid()) { - // No op - return; - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - updateOffset = updateOffset == null ? true : updateOffset; - if (months) { - setMonth(mom, get(mom, 'Month') + months * isAdding); - } - if (days) { - set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); - } - if (milliseconds) { - mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); - } - if (updateOffset) { - hooks.updateOffset(mom, days || months); + var eo = moment.defineLocale('eo', { + months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'), + monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'), + weekdays : 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'), + weekdaysShort : 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'), + weekdaysMin : 'di_lu_ma_me_ĵa_ve_sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'D[-a de] MMMM, YYYY', + LLL : 'D[-a de] MMMM, YYYY HH:mm', + LLLL : 'dddd, [la] D[-a de] MMMM, YYYY HH:mm' + }, + meridiemParse: /[ap]\.t\.m/i, + isPM: function (input) { + return input.charAt(0).toLowerCase() === 'p'; + }, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'p.t.m.' : 'P.T.M.'; + } else { + return isLower ? 'a.t.m.' : 'A.T.M.'; + } + }, + calendar : { + sameDay : '[Hodiaŭ je] LT', + nextDay : '[Morgaŭ je] LT', + nextWeek : 'dddd [je] LT', + lastDay : '[Hieraŭ je] LT', + lastWeek : '[pasinta] dddd [je] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'post %s', + past : 'antaŭ %s', + s : 'sekundoj', + ss : '%d sekundoj', + m : 'minuto', + mm : '%d minutoj', + h : 'horo', + hh : '%d horoj', + d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo + dd : '%d tagoj', + M : 'monato', + MM : '%d monatoj', + y : 'jaro', + yy : '%d jaroj' + }, + dayOfMonthOrdinalParse: /\d{1,2}a/, + ordinal : '%da', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. } - } + }); - var add = createAdder(1, 'add'); - var subtract = createAdder(-1, 'subtract'); + return eo; - function getCalendarFormat(myMoment, now) { - var diff = myMoment.diff(now, 'days', true); - return diff < -6 ? 'sameElse' : - diff < -1 ? 'lastWeek' : - diff < 0 ? 'lastDay' : - diff < 1 ? 'sameDay' : - diff < 2 ? 'nextDay' : - diff < 7 ? 'nextWeek' : 'sameElse'; - } +}))); - function calendar$1 (time, formats) { - // We want to compare the start of today, vs this. - // Getting start-of-today depends on whether we're local/utc/offset or not. - var now = time || createLocal(), - sod = cloneWithOffset(now, this).startOf('day'), - format = hooks.calendarFormat(this, sod) || 'sameElse'; - var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); +/***/ }), +/* 47 */ +/***/ (function(module, exports, __webpack_require__) { - return this.format(output || this.localeData().calendar(format, this, createLocal(now))); - } +//! moment.js locale configuration - function clone () { - return new Moment(this); - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - function isAfter (input, units) { - var localInput = isMoment(input) ? input : createLocal(input); - if (!(this.isValid() && localInput.isValid())) { - return false; - } - units = normalizeUnits(units) || 'millisecond'; - if (units === 'millisecond') { - return this.valueOf() > localInput.valueOf(); - } else { - return localInput.valueOf() < this.clone().startOf(units).valueOf(); - } - } - function isBefore (input, units) { - var localInput = isMoment(input) ? input : createLocal(input); - if (!(this.isValid() && localInput.isValid())) { - return false; - } - units = normalizeUnits(units) || 'millisecond'; - if (units === 'millisecond') { - return this.valueOf() < localInput.valueOf(); - } else { - return this.clone().endOf(units).valueOf() < localInput.valueOf(); - } - } + var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), + monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); - function isBetween (from, to, units, inclusivity) { - var localFrom = isMoment(from) ? from : createLocal(from), - localTo = isMoment(to) ? to : createLocal(to); - if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) { - return false; - } - inclusivity = inclusivity || '()'; - return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && - (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units)); - } + var monthsParse = [/^ene/i, /^feb/i, /^mar/i, /^abr/i, /^may/i, /^jun/i, /^jul/i, /^ago/i, /^sep/i, /^oct/i, /^nov/i, /^dic/i]; + var monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; - function isSame (input, units) { - var localInput = isMoment(input) ? input : createLocal(input), - inputMs; - if (!(this.isValid() && localInput.isValid())) { - return false; - } - units = normalizeUnits(units) || 'millisecond'; - if (units === 'millisecond') { - return this.valueOf() === localInput.valueOf(); - } else { - inputMs = localInput.valueOf(); - return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); + var es = moment.defineLocale('es', { + months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortDot; + } else if (/-MMM-/.test(format)) { + return monthsShort[m.month()]; + } else { + return monthsShortDot[m.month()]; + } + }, + monthsRegex : monthsRegex, + monthsShortRegex : monthsRegex, + monthsStrictRegex : /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, + monthsShortStrictRegex : /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, + monthsParse : monthsParse, + longMonthsParse : monthsParse, + shortMonthsParse : monthsParse, + weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), + weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), + weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY H:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm' + }, + calendar : { + sameDay : function () { + return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextDay : function () { + return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastDay : function () { + return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'en %s', + past : 'hace %s', + s : 'unos segundos', + ss : '%d segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'una hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un año', + yy : '%d años' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } - } + }); - function isSameOrAfter (input, units) { - return this.isSame(input, units) || this.isAfter(input, units); - } + return es; - function isSameOrBefore (input, units) { - return this.isSame(input, units) || this.isBefore(input, units); - } +}))); - function diff (input, units, asFloat) { - var that, - zoneDelta, - output; - if (!this.isValid()) { - return NaN; - } +/***/ }), +/* 48 */ +/***/ (function(module, exports, __webpack_require__) { - that = cloneWithOffset(input, this); +//! moment.js locale configuration - if (!that.isValid()) { - return NaN; - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; - units = normalizeUnits(units); + var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), + monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); - switch (units) { - case 'year': output = monthDiff(this, that) / 12; break; - case 'month': output = monthDiff(this, that); break; - case 'quarter': output = monthDiff(this, that) / 3; break; - case 'second': output = (this - that) / 1e3; break; // 1000 - case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 - case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 - case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst - case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst - default: output = this - that; + var monthsParse = [/^ene/i, /^feb/i, /^mar/i, /^abr/i, /^may/i, /^jun/i, /^jul/i, /^ago/i, /^sep/i, /^oct/i, /^nov/i, /^dic/i]; + var monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; + + var esDo = moment.defineLocale('es-do', { + months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortDot; + } else if (/-MMM-/.test(format)) { + return monthsShort[m.month()]; + } else { + return monthsShortDot[m.month()]; + } + }, + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, + monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: monthsParse, + weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), + weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), + weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY h:mm A', + LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A' + }, + calendar : { + sameDay : function () { + return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextDay : function () { + return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastDay : function () { + return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'en %s', + past : 'hace %s', + s : 'unos segundos', + ss : '%d segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'una hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un año', + yy : '%d años' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } + }); - return asFloat ? output : absFloor(output); - } + return esDo; - function monthDiff (a, b) { - // difference in months - var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), - // b is in (anchor - 1 month, anchor + 1 month) - anchor = a.clone().add(wholeMonthDiff, 'months'), - anchor2, adjust; +}))); - if (b - anchor < 0) { - anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); - // linear across the month - adjust = (b - anchor) / (anchor - anchor2); - } else { - anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); - // linear across the month - adjust = (b - anchor) / (anchor2 - anchor); - } - //check for negative zero, return zero if negative zero - return -(wholeMonthDiff + adjust) || 0; - } +/***/ }), +/* 49 */ +/***/ (function(module, exports, __webpack_require__) { - hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; - hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; +//! moment.js locale configuration - function toString () { - return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - function toISOString(keepOffset) { - if (!this.isValid()) { - return null; - } - var utc = keepOffset !== true; - var m = utc ? this.clone().utc() : this; - if (m.year() < 0 || m.year() > 9999) { - return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); - } - if (isFunction(Date.prototype.toISOString)) { - // native implementation is ~50x faster, use it when we can - if (utc) { - return this.toDate().toISOString(); + + var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), + monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); + + var monthsParse = [/^ene/i, /^feb/i, /^mar/i, /^abr/i, /^may/i, /^jun/i, /^jul/i, /^ago/i, /^sep/i, /^oct/i, /^nov/i, /^dic/i]; + var monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; + + var esUs = moment.defineLocale('es-us', { + months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortDot; + } else if (/-MMM-/.test(format)) { + return monthsShort[m.month()]; } else { - return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z')); + return monthsShortDot[m.month()]; } + }, + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, + monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, + monthsParse: monthsParse, + longMonthsParse: monthsParse, + shortMonthsParse: monthsParse, + weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), + weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), + weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'MM/DD/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY h:mm A', + LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A' + }, + calendar : { + sameDay : function () { + return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextDay : function () { + return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastDay : function () { + return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'en %s', + past : 'hace %s', + s : 'unos segundos', + ss : '%d segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'una hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un año', + yy : '%d años' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 6th is the first week of the year. } - return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); - } + }); - /** - * Return a human readable representation of a moment that can - * also be evaluated to get a new moment which is the same - * - * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects - */ - function inspect () { - if (!this.isValid()) { - return 'moment.invalid(/* ' + this._i + ' */)'; - } - var func = 'moment'; - var zone = ''; - if (!this.isLocal()) { - func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; - zone = 'Z'; - } - var prefix = '[' + func + '("]'; - var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; - var datetime = '-MM-DD[T]HH:mm:ss.SSS'; - var suffix = zone + '[")]'; + return esUs; - return this.format(prefix + year + datetime + suffix); - } +}))); - function format (inputString) { - if (!inputString) { - inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; - } - var output = formatMoment(this, inputString); - return this.localeData().postformat(output); - } - function from (time, withoutSuffix) { - if (this.isValid() && - ((isMoment(time) && time.isValid()) || - createLocal(time).isValid())) { - return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); - } else { - return this.localeData().invalidDate(); - } - } +/***/ }), +/* 50 */ +/***/ (function(module, exports, __webpack_require__) { - function fromNow (withoutSuffix) { - return this.from(createLocal(), withoutSuffix); - } +//! moment.js locale configuration - function to (time, withoutSuffix) { - if (this.isValid() && - ((isMoment(time) && time.isValid()) || - createLocal(time).isValid())) { - return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); - } else { - return this.localeData().invalidDate(); - } - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - function toNow (withoutSuffix) { - return this.to(createLocal(), withoutSuffix); - } - // If passed a locale key, it will set the locale for this - // instance. Otherwise, it will return the locale configuration - // variables for this instance. - function locale (key) { - var newLocaleData; - - if (key === undefined) { - return this._locale._abbr; - } else { - newLocaleData = getLocale(key); - if (newLocaleData != null) { - this._locale = newLocaleData; - } - return this; + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'], + 'ss': [number + 'sekundi', number + 'sekundit'], + 'm' : ['ühe minuti', 'üks minut'], + 'mm': [number + ' minuti', number + ' minutit'], + 'h' : ['ühe tunni', 'tund aega', 'üks tund'], + 'hh': [number + ' tunni', number + ' tundi'], + 'd' : ['ühe päeva', 'üks päev'], + 'M' : ['kuu aja', 'kuu aega', 'üks kuu'], + 'MM': [number + ' kuu', number + ' kuud'], + 'y' : ['ühe aasta', 'aasta', 'üks aasta'], + 'yy': [number + ' aasta', number + ' aastat'] + }; + if (withoutSuffix) { + return format[key][2] ? format[key][2] : format[key][1]; } + return isFuture ? format[key][0] : format[key][1]; } - var lang = deprecate( - 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', - function (key) { - if (key === undefined) { - return this.localeData(); - } else { - return this.locale(key); - } + var et = moment.defineLocale('et', { + months : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'), + monthsShort : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'), + weekdays : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'), + weekdaysShort : 'P_E_T_K_N_R_L'.split('_'), + weekdaysMin : 'P_E_T_K_N_R_L'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[Täna,] LT', + nextDay : '[Homme,] LT', + nextWeek : '[Järgmine] dddd LT', + lastDay : '[Eile,] LT', + lastWeek : '[Eelmine] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s pärast', + past : '%s tagasi', + s : processRelativeTime, + ss : processRelativeTime, + m : processRelativeTime, + mm : processRelativeTime, + h : processRelativeTime, + hh : processRelativeTime, + d : processRelativeTime, + dd : '%d päeva', + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } - ); + }); - function localeData () { - return this._locale; - } + return et; - var MS_PER_SECOND = 1000; - var MS_PER_MINUTE = 60 * MS_PER_SECOND; - var MS_PER_HOUR = 60 * MS_PER_MINUTE; - var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; +}))); - // actual modulo - handles negative numbers (for dates before 1970): - function mod$1(dividend, divisor) { - return (dividend % divisor + divisor) % divisor; - } - function localStartOfDate(y, m, d) { - // the date constructor remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0) { - // preserve leap years using a full 400 year cycle, then reset - return new Date(y + 400, m, d) - MS_PER_400_YEARS; - } else { - return new Date(y, m, d).valueOf(); - } - } +/***/ }), +/* 51 */ +/***/ (function(module, exports, __webpack_require__) { - function utcStartOfDate(y, m, d) { - // Date.UTC remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0) { - // preserve leap years using a full 400 year cycle, then reset - return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS; - } else { - return Date.UTC(y, m, d); - } - } +//! moment.js locale configuration - function startOf (units) { - var time; - units = normalizeUnits(units); - if (units === undefined || units === 'millisecond' || !this.isValid()) { - return this; - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; - switch (units) { - case 'year': - time = startOfDate(this.year(), 0, 1); - break; - case 'quarter': - time = startOfDate(this.year(), this.month() - this.month() % 3, 1); - break; - case 'month': - time = startOfDate(this.year(), this.month(), 1); - break; - case 'week': - time = startOfDate(this.year(), this.month(), this.date() - this.weekday()); - break; - case 'isoWeek': - time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1)); - break; - case 'day': - case 'date': - time = startOfDate(this.year(), this.month(), this.date()); - break; - case 'hour': - time = this._d.valueOf(); - time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR); - break; - case 'minute': - time = this._d.valueOf(); - time -= mod$1(time, MS_PER_MINUTE); - break; - case 'second': - time = this._d.valueOf(); - time -= mod$1(time, MS_PER_SECOND); - break; + var eu = moment.defineLocale('eu', { + months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'), + monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'), + monthsParseExact : true, + weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'), + weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'), + weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'YYYY[ko] MMMM[ren] D[a]', + LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm', + LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm', + l : 'YYYY-M-D', + ll : 'YYYY[ko] MMM D[a]', + lll : 'YYYY[ko] MMM D[a] HH:mm', + llll : 'ddd, YYYY[ko] MMM D[a] HH:mm' + }, + calendar : { + sameDay : '[gaur] LT[etan]', + nextDay : '[bihar] LT[etan]', + nextWeek : 'dddd LT[etan]', + lastDay : '[atzo] LT[etan]', + lastWeek : '[aurreko] dddd LT[etan]', + sameElse : 'L' + }, + relativeTime : { + future : '%s barru', + past : 'duela %s', + s : 'segundo batzuk', + ss : '%d segundo', + m : 'minutu bat', + mm : '%d minutu', + h : 'ordu bat', + hh : '%d ordu', + d : 'egun bat', + dd : '%d egun', + M : 'hilabete bat', + MM : '%d hilabete', + y : 'urte bat', + yy : '%d urte' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. } + }); - this._d.setTime(time); - hooks.updateOffset(this, true); - return this; - } + return eu; - function endOf (units) { - var time; - units = normalizeUnits(units); - if (units === undefined || units === 'millisecond' || !this.isValid()) { - return this; +}))); + + +/***/ }), +/* 52 */ +/***/ (function(module, exports, __webpack_require__) { + +//! moment.js locale configuration + +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; + + + var symbolMap = { + '1': '۱', + '2': '۲', + '3': '۳', + '4': '۴', + '5': '۵', + '6': '۶', + '7': '۷', + '8': '۸', + '9': '۹', + '0': '۰' + }, numberMap = { + '۱': '1', + '۲': '2', + '۳': '3', + '۴': '4', + '۵': '5', + '۶': '6', + '۷': '7', + '۸': '8', + '۹': '9', + '۰': '0' + }; + + var fa = moment.defineLocale('fa', { + months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), + monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), + weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), + weekdaysShort : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), + weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + meridiemParse: /قبل از ظهر|بعد از ظهر/, + isPM: function (input) { + return /بعد از ظهر/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'قبل از ظهر'; + } else { + return 'بعد از ظهر'; + } + }, + calendar : { + sameDay : '[امروز ساعت] LT', + nextDay : '[فردا ساعت] LT', + nextWeek : 'dddd [ساعت] LT', + lastDay : '[دیروز ساعت] LT', + lastWeek : 'dddd [پیش] [ساعت] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'در %s', + past : '%s پیش', + s : 'چند ثانیه', + ss : 'ثانیه d%', + m : 'یک دقیقه', + mm : '%d دقیقه', + h : 'یک ساعت', + hh : '%d ساعت', + d : 'یک روز', + dd : '%d روز', + M : 'یک ماه', + MM : '%d ماه', + y : 'یک سال', + yy : '%d سال' + }, + preparse: function (string) { + return string.replace(/[۰-۹]/g, function (match) { + return numberMap[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }).replace(/,/g, '،'); + }, + dayOfMonthOrdinalParse: /\d{1,2}م/, + ordinal : '%dم', + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 12th is the first week of the year. } + }); - var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; + return fa; - switch (units) { - case 'year': - time = startOfDate(this.year() + 1, 0, 1) - 1; - break; - case 'quarter': - time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1; - break; - case 'month': - time = startOfDate(this.year(), this.month() + 1, 1) - 1; - break; - case 'week': - time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1; - break; - case 'isoWeek': - time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1; +}))); + + +/***/ }), +/* 53 */ +/***/ (function(module, exports, __webpack_require__) { + +//! moment.js locale configuration + +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; + + + var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '), + numbersFuture = [ + 'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden', + numbersPast[7], numbersPast[8], numbersPast[9] + ]; + function translate(number, withoutSuffix, key, isFuture) { + var result = ''; + switch (key) { + case 's': + return isFuture ? 'muutaman sekunnin' : 'muutama sekunti'; + case 'ss': + return isFuture ? 'sekunnin' : 'sekuntia'; + case 'm': + return isFuture ? 'minuutin' : 'minuutti'; + case 'mm': + result = isFuture ? 'minuutin' : 'minuuttia'; break; - case 'day': - case 'date': - time = startOfDate(this.year(), this.month(), this.date() + 1) - 1; + case 'h': + return isFuture ? 'tunnin' : 'tunti'; + case 'hh': + result = isFuture ? 'tunnin' : 'tuntia'; break; - case 'hour': - time = this._d.valueOf(); - time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1; + case 'd': + return isFuture ? 'päivän' : 'päivä'; + case 'dd': + result = isFuture ? 'päivän' : 'päivää'; break; - case 'minute': - time = this._d.valueOf(); - time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1; + case 'M': + return isFuture ? 'kuukauden' : 'kuukausi'; + case 'MM': + result = isFuture ? 'kuukauden' : 'kuukautta'; break; - case 'second': - time = this._d.valueOf(); - time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1; + case 'y': + return isFuture ? 'vuoden' : 'vuosi'; + case 'yy': + result = isFuture ? 'vuoden' : 'vuotta'; break; } - - this._d.setTime(time); - hooks.updateOffset(this, true); - return this; - } - - function valueOf () { - return this._d.valueOf() - ((this._offset || 0) * 60000); + result = verbalNumber(number, isFuture) + ' ' + result; + return result; } - - function unix () { - return Math.floor(this.valueOf() / 1000); + function verbalNumber(number, isFuture) { + return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number; } - function toDate () { - return new Date(this.valueOf()); - } + var fi = moment.defineLocale('fi', { + months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'), + monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'), + weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'), + weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'), + weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD.MM.YYYY', + LL : 'Do MMMM[ta] YYYY', + LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm', + LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm', + l : 'D.M.YYYY', + ll : 'Do MMM YYYY', + lll : 'Do MMM YYYY, [klo] HH.mm', + llll : 'ddd, Do MMM YYYY, [klo] HH.mm' + }, + calendar : { + sameDay : '[tänään] [klo] LT', + nextDay : '[huomenna] [klo] LT', + nextWeek : 'dddd [klo] LT', + lastDay : '[eilen] [klo] LT', + lastWeek : '[viime] dddd[na] [klo] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s päästä', + past : '%s sitten', + s : translate, + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); - function toArray () { - var m = this; - return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; - } + return fi; - function toObject () { - var m = this; - return { - years: m.year(), - months: m.month(), - date: m.date(), - hours: m.hours(), - minutes: m.minutes(), - seconds: m.seconds(), - milliseconds: m.milliseconds() - }; - } +}))); - function toJSON () { - // new Date(NaN).toJSON() === null - return this.isValid() ? this.toISOString() : null; - } - function isValid$2 () { - return isValid(this); - } +/***/ }), +/* 54 */ +/***/ (function(module, exports, __webpack_require__) { - function parsingFlags () { - return extend({}, getParsingFlags(this)); - } +//! moment.js locale configuration - function invalidAt () { - return getParsingFlags(this).overflow; - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - function creationData() { - return { - input: this._i, - format: this._f, - locale: this._locale, - isUTC: this._isUTC, - strict: this._strict - }; - } - // FORMATTING - - addFormatToken(0, ['gg', 2], 0, function () { - return this.weekYear() % 100; - }); - - addFormatToken(0, ['GG', 2], 0, function () { - return this.isoWeekYear() % 100; + var fo = moment.defineLocale('fo', { + months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'), + monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), + weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'), + weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'), + weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D. MMMM, YYYY HH:mm' + }, + calendar : { + sameDay : '[Í dag kl.] LT', + nextDay : '[Í morgin kl.] LT', + nextWeek : 'dddd [kl.] LT', + lastDay : '[Í gjár kl.] LT', + lastWeek : '[síðstu] dddd [kl] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'um %s', + past : '%s síðani', + s : 'fá sekund', + ss : '%d sekundir', + m : 'ein minuttur', + mm : '%d minuttir', + h : 'ein tími', + hh : '%d tímar', + d : 'ein dagur', + dd : '%d dagar', + M : 'ein mánaður', + MM : '%d mánaðir', + y : 'eitt ár', + yy : '%d ár' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } }); - function addWeekYearFormatToken (token, getter) { - addFormatToken(0, [token, token.length], 0, getter); - } - - addWeekYearFormatToken('gggg', 'weekYear'); - addWeekYearFormatToken('ggggg', 'weekYear'); - addWeekYearFormatToken('GGGG', 'isoWeekYear'); - addWeekYearFormatToken('GGGGG', 'isoWeekYear'); - - // ALIASES - - addUnitAlias('weekYear', 'gg'); - addUnitAlias('isoWeekYear', 'GG'); - - // PRIORITY - - addUnitPriority('weekYear', 1); - addUnitPriority('isoWeekYear', 1); - - - // PARSING + return fo; - addRegexToken('G', matchSigned); - addRegexToken('g', matchSigned); - addRegexToken('GG', match1to2, match2); - addRegexToken('gg', match1to2, match2); - addRegexToken('GGGG', match1to4, match4); - addRegexToken('gggg', match1to4, match4); - addRegexToken('GGGGG', match1to6, match6); - addRegexToken('ggggg', match1to6, match6); +}))); - addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { - week[token.substr(0, 2)] = toInt(input); - }); - addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { - week[token] = hooks.parseTwoDigitYear(input); - }); +/***/ }), +/* 55 */ +/***/ (function(module, exports, __webpack_require__) { - // MOMENTS +//! moment.js locale configuration - function getSetWeekYear (input) { - return getSetWeekYearHelper.call(this, - input, - this.week(), - this.weekday(), - this.localeData()._week.dow, - this.localeData()._week.doy); - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - function getSetISOWeekYear (input) { - return getSetWeekYearHelper.call(this, - input, this.isoWeek(), this.isoWeekday(), 1, 4); - } - function getISOWeeksInYear () { - return weeksInYear(this.year(), 1, 4); - } + var fr = moment.defineLocale('fr', { + months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), + monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), + monthsParseExact : true, + weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin : 'di_lu_ma_me_je_ve_sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Aujourd’hui à] LT', + nextDay : '[Demain à] LT', + nextWeek : 'dddd [à] LT', + lastDay : '[Hier à] LT', + lastWeek : 'dddd [dernier à] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dans %s', + past : 'il y a %s', + s : 'quelques secondes', + ss : '%d secondes', + m : 'une minute', + mm : '%d minutes', + h : 'une heure', + hh : '%d heures', + d : 'un jour', + dd : '%d jours', + M : 'un mois', + MM : '%d mois', + y : 'un an', + yy : '%d ans' + }, + dayOfMonthOrdinalParse: /\d{1,2}(er|)/, + ordinal : function (number, period) { + switch (period) { + // TODO: Return 'e' when day of month > 1. Move this case inside + // block for masculine words below. + // See https://github.com/moment/moment/issues/3375 + case 'D': + return number + (number === 1 ? 'er' : ''); - function getWeeksInYear () { - var weekInfo = this.localeData()._week; - return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); - } + // Words with masculine grammatical gender: mois, trimestre, jour + default: + case 'M': + case 'Q': + case 'DDD': + case 'd': + return number + (number === 1 ? 'er' : 'e'); - function getSetWeekYearHelper(input, week, weekday, dow, doy) { - var weeksTarget; - if (input == null) { - return weekOfYear(this, dow, doy).year; - } else { - weeksTarget = weeksInYear(input, dow, doy); - if (week > weeksTarget) { - week = weeksTarget; + // Words with feminine grammatical gender: semaine + case 'w': + case 'W': + return number + (number === 1 ? 're' : 'e'); } - return setWeekAll.call(this, input, week, weekday, dow, doy); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } - } - - function setWeekAll(weekYear, week, weekday, dow, doy) { - var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), - date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); - - this.year(date.getUTCFullYear()); - this.month(date.getUTCMonth()); - this.date(date.getUTCDate()); - return this; - } - - // FORMATTING - - addFormatToken('Q', 0, 'Qo', 'quarter'); - - // ALIASES - - addUnitAlias('quarter', 'Q'); - - // PRIORITY - - addUnitPriority('quarter', 7); - - // PARSING - - addRegexToken('Q', match1); - addParseToken('Q', function (input, array) { - array[MONTH] = (toInt(input) - 1) * 3; }); - // MOMENTS - - function getSetQuarter (input) { - return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); - } + return fr; - // FORMATTING +}))); - addFormatToken('D', ['DD', 2], 'Do', 'date'); - // ALIASES +/***/ }), +/* 56 */ +/***/ (function(module, exports, __webpack_require__) { - addUnitAlias('date', 'D'); +//! moment.js locale configuration - // PRIORITY - addUnitPriority('date', 9); +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - // PARSING - addRegexToken('D', match1to2); - addRegexToken('DD', match1to2, match2); - addRegexToken('Do', function (isStrict, locale) { - // TODO: Remove "ordinalParse" fallback in next major release. - return isStrict ? - (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : - locale._dayOfMonthOrdinalParseLenient; - }); + var frCa = moment.defineLocale('fr-ca', { + months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), + monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), + monthsParseExact : true, + weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin : 'di_lu_ma_me_je_ve_sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Aujourd’hui à] LT', + nextDay : '[Demain à] LT', + nextWeek : 'dddd [à] LT', + lastDay : '[Hier à] LT', + lastWeek : 'dddd [dernier à] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dans %s', + past : 'il y a %s', + s : 'quelques secondes', + ss : '%d secondes', + m : 'une minute', + mm : '%d minutes', + h : 'une heure', + hh : '%d heures', + d : 'un jour', + dd : '%d jours', + M : 'un mois', + MM : '%d mois', + y : 'un an', + yy : '%d ans' + }, + dayOfMonthOrdinalParse: /\d{1,2}(er|e)/, + ordinal : function (number, period) { + switch (period) { + // Words with masculine grammatical gender: mois, trimestre, jour + default: + case 'M': + case 'Q': + case 'D': + case 'DDD': + case 'd': + return number + (number === 1 ? 'er' : 'e'); - addParseToken(['D', 'DD'], DATE); - addParseToken('Do', function (input, array) { - array[DATE] = toInt(input.match(match1to2)[0]); + // Words with feminine grammatical gender: semaine + case 'w': + case 'W': + return number + (number === 1 ? 're' : 'e'); + } + } }); - // MOMENTS + return frCa; - var getSetDayOfMonth = makeGetSet('Date', true); +}))); - // FORMATTING - addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); +/***/ }), +/* 57 */ +/***/ (function(module, exports, __webpack_require__) { - // ALIASES +//! moment.js locale configuration - addUnitAlias('dayOfYear', 'DDD'); +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - // PRIORITY - addUnitPriority('dayOfYear', 4); - // PARSING + var frCh = moment.defineLocale('fr-ch', { + months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), + monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), + monthsParseExact : true, + weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin : 'di_lu_ma_me_je_ve_sa'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Aujourd’hui à] LT', + nextDay : '[Demain à] LT', + nextWeek : 'dddd [à] LT', + lastDay : '[Hier à] LT', + lastWeek : 'dddd [dernier à] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dans %s', + past : 'il y a %s', + s : 'quelques secondes', + ss : '%d secondes', + m : 'une minute', + mm : '%d minutes', + h : 'une heure', + hh : '%d heures', + d : 'un jour', + dd : '%d jours', + M : 'un mois', + MM : '%d mois', + y : 'un an', + yy : '%d ans' + }, + dayOfMonthOrdinalParse: /\d{1,2}(er|e)/, + ordinal : function (number, period) { + switch (period) { + // Words with masculine grammatical gender: mois, trimestre, jour + default: + case 'M': + case 'Q': + case 'D': + case 'DDD': + case 'd': + return number + (number === 1 ? 'er' : 'e'); - addRegexToken('DDD', match1to3); - addRegexToken('DDDD', match3); - addParseToken(['DDD', 'DDDD'], function (input, array, config) { - config._dayOfYear = toInt(input); + // Words with feminine grammatical gender: semaine + case 'w': + case 'W': + return number + (number === 1 ? 're' : 'e'); + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } }); - // HELPERS - - // MOMENTS - - function getSetDayOfYear (input) { - var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; - return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); - } - - // FORMATTING + return frCh; - addFormatToken('m', ['mm', 2], 0, 'minute'); +}))); - // ALIASES - addUnitAlias('minute', 'm'); +/***/ }), +/* 58 */ +/***/ (function(module, exports, __webpack_require__) { - // PRIORITY +//! moment.js locale configuration - addUnitPriority('minute', 14); +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - // PARSING - addRegexToken('m', match1to2); - addRegexToken('mm', match1to2, match2); - addParseToken(['m', 'mm'], MINUTE); + var monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_'), + monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'); - // MOMENTS + var fy = moment.defineLocale('fy', { + months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortWithDots; + } else if (/-MMM-/.test(format)) { + return monthsShortWithoutDots[m.month()]; + } else { + return monthsShortWithDots[m.month()]; + } + }, + monthsParseExact : true, + weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'), + weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'), + weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[hjoed om] LT', + nextDay: '[moarn om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[juster om] LT', + lastWeek: '[ôfrûne] dddd [om] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'oer %s', + past : '%s lyn', + s : 'in pear sekonden', + ss : '%d sekonden', + m : 'ien minút', + mm : '%d minuten', + h : 'ien oere', + hh : '%d oeren', + d : 'ien dei', + dd : '%d dagen', + M : 'ien moanne', + MM : '%d moannen', + y : 'ien jier', + yy : '%d jierren' + }, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); - var getSetMinute = makeGetSet('Minutes', false); + return fy; - // FORMATTING +}))); - addFormatToken('s', ['ss', 2], 0, 'second'); - // ALIASES +/***/ }), +/* 59 */ +/***/ (function(module, exports, __webpack_require__) { - addUnitAlias('second', 's'); +//! moment.js locale configuration - // PRIORITY +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - addUnitPriority('second', 15); - // PARSING - addRegexToken('s', match1to2); - addRegexToken('ss', match1to2, match2); - addParseToken(['s', 'ss'], SECOND); + var months = [ + 'Eanáir', 'Feabhra', 'Márta', 'Aibreán', 'Bealtaine', 'Méitheamh', 'Iúil', 'Lúnasa', 'Meán Fómhair', 'Deaireadh Fómhair', 'Samhain', 'Nollaig' + ]; - // MOMENTS + var monthsShort = ['Eaná', 'Feab', 'Márt', 'Aibr', 'Beal', 'Méit', 'Iúil', 'Lúna', 'Meán', 'Deai', 'Samh', 'Noll']; - var getSetSecond = makeGetSet('Seconds', false); + var weekdays = ['Dé Domhnaigh', 'Dé Luain', 'Dé Máirt', 'Dé Céadaoin', 'Déardaoin', 'Dé hAoine', 'Dé Satharn']; - // FORMATTING + var weekdaysShort = ['Dom', 'Lua', 'Mái', 'Céa', 'Déa', 'hAo', 'Sat']; - addFormatToken('S', 0, 0, function () { - return ~~(this.millisecond() / 100); - }); + var weekdaysMin = ['Do', 'Lu', 'Má', 'Ce', 'Dé', 'hA', 'Sa']; - addFormatToken(0, ['SS', 2], 0, function () { - return ~~(this.millisecond() / 10); + var ga = moment.defineLocale('ga', { + months: months, + monthsShort: monthsShort, + monthsParseExact: true, + weekdays: weekdays, + weekdaysShort: weekdaysShort, + weekdaysMin: weekdaysMin, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm' + }, + calendar: { + sameDay: '[Inniu ag] LT', + nextDay: '[Amárach ag] LT', + nextWeek: 'dddd [ag] LT', + lastDay: '[Inné aig] LT', + lastWeek: 'dddd [seo caite] [ag] LT', + sameElse: 'L' + }, + relativeTime: { + future: 'i %s', + past: '%s ó shin', + s: 'cúpla soicind', + ss: '%d soicind', + m: 'nóiméad', + mm: '%d nóiméad', + h: 'uair an chloig', + hh: '%d uair an chloig', + d: 'lá', + dd: '%d lá', + M: 'mí', + MM: '%d mí', + y: 'bliain', + yy: '%d bliain' + }, + dayOfMonthOrdinalParse: /\d{1,2}(d|na|mh)/, + ordinal: function (number) { + var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh'; + return number + output; + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } }); - addFormatToken(0, ['SSS', 3], 0, 'millisecond'); - addFormatToken(0, ['SSSS', 4], 0, function () { - return this.millisecond() * 10; - }); - addFormatToken(0, ['SSSSS', 5], 0, function () { - return this.millisecond() * 100; - }); - addFormatToken(0, ['SSSSSS', 6], 0, function () { - return this.millisecond() * 1000; - }); - addFormatToken(0, ['SSSSSSS', 7], 0, function () { - return this.millisecond() * 10000; - }); - addFormatToken(0, ['SSSSSSSS', 8], 0, function () { - return this.millisecond() * 100000; - }); - addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { - return this.millisecond() * 1000000; - }); + return ga; +}))); - // ALIASES - addUnitAlias('millisecond', 'ms'); +/***/ }), +/* 60 */ +/***/ (function(module, exports, __webpack_require__) { - // PRIORITY +//! moment.js locale configuration - addUnitPriority('millisecond', 16); +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - // PARSING - addRegexToken('S', match1to3, match1); - addRegexToken('SS', match1to3, match2); - addRegexToken('SSS', match1to3, match3); + var months = [ + 'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd' + ]; - var token; - for (token = 'SSSS'; token.length <= 9; token += 'S') { - addRegexToken(token, matchUnsigned); - } + var monthsShort = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh']; - function parseMs(input, array) { - array[MILLISECOND] = toInt(('0.' + input) * 1000); - } + var weekdays = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne']; - for (token = 'S'; token.length <= 9; token += 'S') { - addParseToken(token, parseMs); - } - // MOMENTS + var weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis']; - var getSetMillisecond = makeGetSet('Milliseconds', false); + var weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa']; - // FORMATTING + var gd = moment.defineLocale('gd', { + months : months, + monthsShort : monthsShort, + monthsParseExact : true, + weekdays : weekdays, + weekdaysShort : weekdaysShort, + weekdaysMin : weekdaysMin, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[An-diugh aig] LT', + nextDay : '[A-màireach aig] LT', + nextWeek : 'dddd [aig] LT', + lastDay : '[An-dè aig] LT', + lastWeek : 'dddd [seo chaidh] [aig] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ann an %s', + past : 'bho chionn %s', + s : 'beagan diogan', + ss : '%d diogan', + m : 'mionaid', + mm : '%d mionaidean', + h : 'uair', + hh : '%d uairean', + d : 'latha', + dd : '%d latha', + M : 'mìos', + MM : '%d mìosan', + y : 'bliadhna', + yy : '%d bliadhna' + }, + dayOfMonthOrdinalParse : /\d{1,2}(d|na|mh)/, + ordinal : function (number) { + var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); - addFormatToken('z', 0, 0, 'zoneAbbr'); - addFormatToken('zz', 0, 0, 'zoneName'); + return gd; - // MOMENTS +}))); - function getZoneAbbr () { - return this._isUTC ? 'UTC' : ''; - } - function getZoneName () { - return this._isUTC ? 'Coordinated Universal Time' : ''; - } +/***/ }), +/* 61 */ +/***/ (function(module, exports, __webpack_require__) { - var proto = Moment.prototype; +//! moment.js locale configuration - proto.add = add; - proto.calendar = calendar$1; - proto.clone = clone; - proto.diff = diff; - proto.endOf = endOf; - proto.format = format; - proto.from = from; - proto.fromNow = fromNow; - proto.to = to; - proto.toNow = toNow; - proto.get = stringGet; - proto.invalidAt = invalidAt; - proto.isAfter = isAfter; - proto.isBefore = isBefore; - proto.isBetween = isBetween; - proto.isSame = isSame; - proto.isSameOrAfter = isSameOrAfter; - proto.isSameOrBefore = isSameOrBefore; - proto.isValid = isValid$2; - proto.lang = lang; - proto.locale = locale; - proto.localeData = localeData; - proto.max = prototypeMax; - proto.min = prototypeMin; - proto.parsingFlags = parsingFlags; - proto.set = stringSet; - proto.startOf = startOf; - proto.subtract = subtract; - proto.toArray = toArray; - proto.toObject = toObject; - proto.toDate = toDate; - proto.toISOString = toISOString; - proto.inspect = inspect; - proto.toJSON = toJSON; - proto.toString = toString; - proto.unix = unix; - proto.valueOf = valueOf; - proto.creationData = creationData; - proto.year = getSetYear; - proto.isLeapYear = getIsLeapYear; - proto.weekYear = getSetWeekYear; - proto.isoWeekYear = getSetISOWeekYear; - proto.quarter = proto.quarters = getSetQuarter; - proto.month = getSetMonth; - proto.daysInMonth = getDaysInMonth; - proto.week = proto.weeks = getSetWeek; - proto.isoWeek = proto.isoWeeks = getSetISOWeek; - proto.weeksInYear = getWeeksInYear; - proto.isoWeeksInYear = getISOWeeksInYear; - proto.date = getSetDayOfMonth; - proto.day = proto.days = getSetDayOfWeek; - proto.weekday = getSetLocaleDayOfWeek; - proto.isoWeekday = getSetISODayOfWeek; - proto.dayOfYear = getSetDayOfYear; - proto.hour = proto.hours = getSetHour; - proto.minute = proto.minutes = getSetMinute; - proto.second = proto.seconds = getSetSecond; - proto.millisecond = proto.milliseconds = getSetMillisecond; - proto.utcOffset = getSetOffset; - proto.utc = setOffsetToUTC; - proto.local = setOffsetToLocal; - proto.parseZone = setOffsetToParsedOffset; - proto.hasAlignedHourOffset = hasAlignedHourOffset; - proto.isDST = isDaylightSavingTime; - proto.isLocal = isLocal; - proto.isUtcOffset = isUtcOffset; - proto.isUtc = isUtc; - proto.isUTC = isUtc; - proto.zoneAbbr = getZoneAbbr; - proto.zoneName = getZoneName; - proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); - proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); - proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); - proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); - proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - function createUnix (input) { - return createLocal(input * 1000); - } - function createInZone () { - return createLocal.apply(null, arguments).parseZone(); - } + var gl = moment.defineLocale('gl', { + months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'), + monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'), + monthsParseExact: true, + weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'), + weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'), + weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY H:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm' + }, + calendar : { + sameDay : function () { + return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; + }, + nextDay : function () { + return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; + }, + nextWeek : function () { + return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; + }, + lastDay : function () { + return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT'; + }, + lastWeek : function () { + return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : function (str) { + if (str.indexOf('un') === 0) { + return 'n' + str; + } + return 'en ' + str; + }, + past : 'hai %s', + s : 'uns segundos', + ss : '%d segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'unha hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un ano', + yy : '%d anos' + }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); - function preParsePostFormat (string) { - return string; - } + return gl; - var proto$1 = Locale.prototype; +}))); - proto$1.calendar = calendar; - proto$1.longDateFormat = longDateFormat; - proto$1.invalidDate = invalidDate; - proto$1.ordinal = ordinal; - proto$1.preparse = preParsePostFormat; - proto$1.postformat = preParsePostFormat; - proto$1.relativeTime = relativeTime; - proto$1.pastFuture = pastFuture; - proto$1.set = set; - proto$1.months = localeMonths; - proto$1.monthsShort = localeMonthsShort; - proto$1.monthsParse = localeMonthsParse; - proto$1.monthsRegex = monthsRegex; - proto$1.monthsShortRegex = monthsShortRegex; - proto$1.week = localeWeek; - proto$1.firstDayOfYear = localeFirstDayOfYear; - proto$1.firstDayOfWeek = localeFirstDayOfWeek; +/***/ }), +/* 62 */ +/***/ (function(module, exports, __webpack_require__) { - proto$1.weekdays = localeWeekdays; - proto$1.weekdaysMin = localeWeekdaysMin; - proto$1.weekdaysShort = localeWeekdaysShort; - proto$1.weekdaysParse = localeWeekdaysParse; +//! moment.js locale configuration - proto$1.weekdaysRegex = weekdaysRegex; - proto$1.weekdaysShortRegex = weekdaysShortRegex; - proto$1.weekdaysMinRegex = weekdaysMinRegex; +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - proto$1.isPM = localeIsPM; - proto$1.meridiem = localeMeridiem; - function get$1 (format, index, field, setter) { - var locale = getLocale(); - var utc = createUTC().set(setter, index); - return locale[field](utc, format); + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 's': ['thodde secondanim', 'thodde second'], + 'ss': [number + ' secondanim', number + ' second'], + 'm': ['eka mintan', 'ek minute'], + 'mm': [number + ' mintanim', number + ' mintam'], + 'h': ['eka voran', 'ek vor'], + 'hh': [number + ' voranim', number + ' voram'], + 'd': ['eka disan', 'ek dis'], + 'dd': [number + ' disanim', number + ' dis'], + 'M': ['eka mhoinean', 'ek mhoino'], + 'MM': [number + ' mhoineanim', number + ' mhoine'], + 'y': ['eka vorsan', 'ek voros'], + 'yy': [number + ' vorsanim', number + ' vorsam'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; } - function listMonthsImpl (format, index, field) { - if (isNumber(format)) { - index = format; - format = undefined; + var gomLatn = moment.defineLocale('gom-latn', { + months : 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split('_'), + monthsShort : 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split('_'), + monthsParseExact : true, + weekdays : 'Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son\'var'.split('_'), + weekdaysShort : 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'), + weekdaysMin : 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'A h:mm [vazta]', + LTS : 'A h:mm:ss [vazta]', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY A h:mm [vazta]', + LLLL : 'dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]', + llll: 'ddd, D MMM YYYY, A h:mm [vazta]' + }, + calendar : { + sameDay: '[Aiz] LT', + nextDay: '[Faleam] LT', + nextWeek: '[Ieta to] dddd[,] LT', + lastDay: '[Kal] LT', + lastWeek: '[Fatlo] dddd[,] LT', + sameElse: 'L' + }, + relativeTime : { + future : '%s', + past : '%s adim', + s : processRelativeTime, + ss : processRelativeTime, + m : processRelativeTime, + mm : processRelativeTime, + h : processRelativeTime, + hh : processRelativeTime, + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime + }, + dayOfMonthOrdinalParse : /\d{1,2}(er)/, + ordinal : function (number, period) { + switch (period) { + // the ordinal 'er' only applies to day of the month + case 'D': + return number + 'er'; + default: + case 'M': + case 'Q': + case 'DDD': + case 'd': + case 'w': + case 'W': + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + }, + meridiemParse: /rati|sokalli|donparam|sanje/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'rati') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'sokalli') { + return hour; + } else if (meridiem === 'donparam') { + return hour > 12 ? hour : hour + 12; + } else if (meridiem === 'sanje') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'rati'; + } else if (hour < 12) { + return 'sokalli'; + } else if (hour < 16) { + return 'donparam'; + } else if (hour < 20) { + return 'sanje'; + } else { + return 'rati'; + } } + }); - format = format || ''; + return gomLatn; - if (index != null) { - return get$1(format, index, field, 'month'); - } +}))); - var i; - var out = []; - for (i = 0; i < 12; i++) { - out[i] = get$1(format, i, field, 'month'); - } - return out; - } - // () - // (5) - // (fmt, 5) - // (fmt) - // (true) - // (true, 5) - // (true, fmt, 5) - // (true, fmt) - function listWeekdaysImpl (localeSorted, format, index, field) { - if (typeof localeSorted === 'boolean') { - if (isNumber(format)) { - index = format; - format = undefined; - } +/***/ }), +/* 63 */ +/***/ (function(module, exports, __webpack_require__) { - format = format || ''; - } else { - format = localeSorted; - index = format; - localeSorted = false; +//! moment.js locale configuration - if (isNumber(format)) { - index = format; - format = undefined; - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - format = format || ''; - } - var locale = getLocale(), - shift = localeSorted ? locale._week.dow : 0; + var symbolMap = { + '1': '૧', + '2': '૨', + '3': '૩', + '4': '૪', + '5': '૫', + '6': '૬', + '7': '૭', + '8': '૮', + '9': '૯', + '0': '૦' + }, + numberMap = { + '૧': '1', + '૨': '2', + '૩': '3', + '૪': '4', + '૫': '5', + '૬': '6', + '૭': '7', + '૮': '8', + '૯': '9', + '૦': '0' + }; - if (index != null) { - return get$1(format, (index + shift) % 7, field, 'day'); + var gu = moment.defineLocale('gu', { + months: 'જાન્યુઆરી_ફેબ્રુઆરી_માર્ચ_એપ્રિલ_મે_જૂન_જુલાઈ_ઑગસ્ટ_સપ્ટેમ્બર_ઑક્ટ્બર_નવેમ્બર_ડિસેમ્બર'.split('_'), + monthsShort: 'જાન્યુ._ફેબ્રુ._માર્ચ_એપ્રિ._મે_જૂન_જુલા._ઑગ._સપ્ટે._ઑક્ટ્._નવે._ડિસે.'.split('_'), + monthsParseExact: true, + weekdays: 'રવિવાર_સોમવાર_મંગળવાર_બુધ્વાર_ગુરુવાર_શુક્રવાર_શનિવાર'.split('_'), + weekdaysShort: 'રવિ_સોમ_મંગળ_બુધ્_ગુરુ_શુક્ર_શનિ'.split('_'), + weekdaysMin: 'ર_સો_મં_બુ_ગુ_શુ_શ'.split('_'), + longDateFormat: { + LT: 'A h:mm વાગ્યે', + LTS: 'A h:mm:ss વાગ્યે', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, A h:mm વાગ્યે', + LLLL: 'dddd, D MMMM YYYY, A h:mm વાગ્યે' + }, + calendar: { + sameDay: '[આજ] LT', + nextDay: '[કાલે] LT', + nextWeek: 'dddd, LT', + lastDay: '[ગઇકાલે] LT', + lastWeek: '[પાછલા] dddd, LT', + sameElse: 'L' + }, + relativeTime: { + future: '%s મા', + past: '%s પેહલા', + s: 'અમુક પળો', + ss: '%d સેકંડ', + m: 'એક મિનિટ', + mm: '%d મિનિટ', + h: 'એક કલાક', + hh: '%d કલાક', + d: 'એક દિવસ', + dd: '%d દિવસ', + M: 'એક મહિનો', + MM: '%d મહિનો', + y: 'એક વર્ષ', + yy: '%d વર્ષ' + }, + preparse: function (string) { + return string.replace(/[૧૨૩૪૫૬૭૮૯૦]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + // Gujarati notation for meridiems are quite fuzzy in practice. While there exists + // a rigid notion of a 'Pahar' it is not used as rigidly in modern Gujarati. + meridiemParse: /રાત|બપોર|સવાર|સાંજ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'રાત') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'સવાર') { + return hour; + } else if (meridiem === 'બપોર') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'સાંજ') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'રાત'; + } else if (hour < 10) { + return 'સવાર'; + } else if (hour < 17) { + return 'બપોર'; + } else if (hour < 20) { + return 'સાંજ'; + } else { + return 'રાત'; + } + }, + week: { + dow: 0, // Sunday is the first day of the week. + doy: 6 // The week that contains Jan 6th is the first week of the year. } + }); - var i; - var out = []; - for (i = 0; i < 7; i++) { - out[i] = get$1(format, (i + shift) % 7, field, 'day'); - } - return out; - } + return gu; - function listMonths (format, index) { - return listMonthsImpl(format, index, 'months'); - } +}))); - function listMonthsShort (format, index) { - return listMonthsImpl(format, index, 'monthsShort'); - } - function listWeekdays (localeSorted, format, index) { - return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); - } +/***/ }), +/* 64 */ +/***/ (function(module, exports, __webpack_require__) { - function listWeekdaysShort (localeSorted, format, index) { - return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); - } +//! moment.js locale configuration - function listWeekdaysMin (localeSorted, format, index) { - return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - getSetGlobalLocale('en', { - dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, - ordinal : function (number) { - var b = number % 10, - output = (toInt(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; + + var he = moment.defineLocale('he', { + months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'), + monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'), + weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'), + weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'), + weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [ב]MMMM YYYY', + LLL : 'D [ב]MMMM YYYY HH:mm', + LLLL : 'dddd, D [ב]MMMM YYYY HH:mm', + l : 'D/M/YYYY', + ll : 'D MMM YYYY', + lll : 'D MMM YYYY HH:mm', + llll : 'ddd, D MMM YYYY HH:mm' + }, + calendar : { + sameDay : '[היום ב־]LT', + nextDay : '[מחר ב־]LT', + nextWeek : 'dddd [בשעה] LT', + lastDay : '[אתמול ב־]LT', + lastWeek : '[ביום] dddd [האחרון בשעה] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'בעוד %s', + past : 'לפני %s', + s : 'מספר שניות', + ss : '%d שניות', + m : 'דקה', + mm : '%d דקות', + h : 'שעה', + hh : function (number) { + if (number === 2) { + return 'שעתיים'; + } + return number + ' שעות'; + }, + d : 'יום', + dd : function (number) { + if (number === 2) { + return 'יומיים'; + } + return number + ' ימים'; + }, + M : 'חודש', + MM : function (number) { + if (number === 2) { + return 'חודשיים'; + } + return number + ' חודשים'; + }, + y : 'שנה', + yy : function (number) { + if (number === 2) { + return 'שנתיים'; + } else if (number % 10 === 0 && number !== 10) { + return number + ' שנה'; + } + return number + ' שנים'; + } + }, + meridiemParse: /אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i, + isPM : function (input) { + return /^(אחה"צ|אחרי הצהריים|בערב)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 5) { + return 'לפנות בוקר'; + } else if (hour < 10) { + return 'בבוקר'; + } else if (hour < 12) { + return isLower ? 'לפנה"צ' : 'לפני הצהריים'; + } else if (hour < 18) { + return isLower ? 'אחה"צ' : 'אחרי הצהריים'; + } else { + return 'בערב'; + } } }); - // Side effect imports - - hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); - hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); - - var mathAbs = Math.abs; - - function abs () { - var data = this._data; - - this._milliseconds = mathAbs(this._milliseconds); - this._days = mathAbs(this._days); - this._months = mathAbs(this._months); - - data.milliseconds = mathAbs(data.milliseconds); - data.seconds = mathAbs(data.seconds); - data.minutes = mathAbs(data.minutes); - data.hours = mathAbs(data.hours); - data.months = mathAbs(data.months); - data.years = mathAbs(data.years); - - return this; - } + return he; - function addSubtract$1 (duration, input, value, direction) { - var other = createDuration(input, value); +}))); - duration._milliseconds += direction * other._milliseconds; - duration._days += direction * other._days; - duration._months += direction * other._months; - return duration._bubble(); - } +/***/ }), +/* 65 */ +/***/ (function(module, exports, __webpack_require__) { - // supports only 2.0-style add(1, 's') or add(duration) - function add$1 (input, value) { - return addSubtract$1(this, input, value, 1); - } +//! moment.js locale configuration - // supports only 2.0-style subtract(1, 's') or subtract(duration) - function subtract$1 (input, value) { - return addSubtract$1(this, input, value, -1); - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - function absCeil (number) { - if (number < 0) { - return Math.floor(number); - } else { - return Math.ceil(number); - } - } - function bubble () { - var milliseconds = this._milliseconds; - var days = this._days; - var months = this._months; - var data = this._data; - var seconds, minutes, hours, years, monthsFromDays; + var symbolMap = { + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + '0': '०' + }, + numberMap = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0' + }; - // if we have a mix of positive and negative values, bubble down first - // check: https://github.com/moment/moment/issues/2166 - if (!((milliseconds >= 0 && days >= 0 && months >= 0) || - (milliseconds <= 0 && days <= 0 && months <= 0))) { - milliseconds += absCeil(monthsToDays(months) + days) * 864e5; - days = 0; - months = 0; + var hi = moment.defineLocale('hi', { + months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'), + monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'), + monthsParseExact: true, + weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), + weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'), + weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), + longDateFormat : { + LT : 'A h:mm बजे', + LTS : 'A h:mm:ss बजे', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm बजे', + LLLL : 'dddd, D MMMM YYYY, A h:mm बजे' + }, + calendar : { + sameDay : '[आज] LT', + nextDay : '[कल] LT', + nextWeek : 'dddd, LT', + lastDay : '[कल] LT', + lastWeek : '[पिछले] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s में', + past : '%s पहले', + s : 'कुछ ही क्षण', + ss : '%d सेकंड', + m : 'एक मिनट', + mm : '%d मिनट', + h : 'एक घंटा', + hh : '%d घंटे', + d : 'एक दिन', + dd : '%d दिन', + M : 'एक महीने', + MM : '%d महीने', + y : 'एक वर्ष', + yy : '%d वर्ष' + }, + preparse: function (string) { + return string.replace(/[१२३४५६७८९०]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + // Hindi notation for meridiems are quite fuzzy in practice. While there exists + // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi. + meridiemParse: /रात|सुबह|दोपहर|शाम/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'रात') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'सुबह') { + return hour; + } else if (meridiem === 'दोपहर') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'शाम') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'रात'; + } else if (hour < 10) { + return 'सुबह'; + } else if (hour < 17) { + return 'दोपहर'; + } else if (hour < 20) { + return 'शाम'; + } else { + return 'रात'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 6th is the first week of the year. } + }); - // The following code bubbles up values, see the tests for - // examples of what that means. - data.milliseconds = milliseconds % 1000; - - seconds = absFloor(milliseconds / 1000); - data.seconds = seconds % 60; - - minutes = absFloor(seconds / 60); - data.minutes = minutes % 60; - - hours = absFloor(minutes / 60); - data.hours = hours % 24; + return hi; - days += absFloor(hours / 24); +}))); - // convert days to months - monthsFromDays = absFloor(daysToMonths(days)); - months += monthsFromDays; - days -= absCeil(monthsToDays(monthsFromDays)); - // 12 months -> 1 year - years = absFloor(months / 12); - months %= 12; +/***/ }), +/* 66 */ +/***/ (function(module, exports, __webpack_require__) { - data.days = days; - data.months = months; - data.years = years; +//! moment.js locale configuration - return this; - } +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - function daysToMonths (days) { - // 400 years have 146097 days (taking into account leap year rules) - // 400 years have 12 months === 4800 - return days * 4800 / 146097; - } - function monthsToDays (months) { - // the reverse of daysToMonths - return months * 146097 / 4800; + function translate(number, withoutSuffix, key) { + var result = number + ' '; + switch (key) { + case 'ss': + if (number === 1) { + result += 'sekunda'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sekunde'; + } else { + result += 'sekundi'; + } + return result; + case 'm': + return withoutSuffix ? 'jedna minuta' : 'jedne minute'; + case 'mm': + if (number === 1) { + result += 'minuta'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'minute'; + } else { + result += 'minuta'; + } + return result; + case 'h': + return withoutSuffix ? 'jedan sat' : 'jednog sata'; + case 'hh': + if (number === 1) { + result += 'sat'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sata'; + } else { + result += 'sati'; + } + return result; + case 'dd': + if (number === 1) { + result += 'dan'; + } else { + result += 'dana'; + } + return result; + case 'MM': + if (number === 1) { + result += 'mjesec'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'mjeseca'; + } else { + result += 'mjeseci'; + } + return result; + case 'yy': + if (number === 1) { + result += 'godina'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'godine'; + } else { + result += 'godina'; + } + return result; + } } - function as (units) { - if (!this.isValid()) { - return NaN; - } - var days; - var months; - var milliseconds = this._milliseconds; - - units = normalizeUnits(units); - - if (units === 'month' || units === 'quarter' || units === 'year') { - days = this._days + milliseconds / 864e5; - months = this._months + daysToMonths(days); - switch (units) { - case 'month': return months; - case 'quarter': return months / 3; - case 'year': return months / 12; - } - } else { - // handle milliseconds separately because of floating point math errors (issue #1867) - days = this._days + Math.round(monthsToDays(this._months)); - switch (units) { - case 'week' : return days / 7 + milliseconds / 6048e5; - case 'day' : return days + milliseconds / 864e5; - case 'hour' : return days * 24 + milliseconds / 36e5; - case 'minute' : return days * 1440 + milliseconds / 6e4; - case 'second' : return days * 86400 + milliseconds / 1000; - // Math.floor prevents floating point math errors here - case 'millisecond': return Math.floor(days * 864e5) + milliseconds; - default: throw new Error('Unknown unit ' + units); - } - } - } - - // TODO: Use this.as('ms')? - function valueOf$1 () { - if (!this.isValid()) { - return NaN; + var hr = moment.defineLocale('hr', { + months : { + format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'), + standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_') + }, + monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'), + monthsParseExact: true, + weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), + weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[danas u] LT', + nextDay : '[sutra u] LT', + nextWeek : function () { + switch (this.day()) { + case 0: + return '[u] [nedjelju] [u] LT'; + case 3: + return '[u] [srijedu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[jučer u] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + return '[prošlu] dddd [u] LT'; + case 6: + return '[prošle] [subote] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prošli] dddd [u] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'za %s', + past : 'prije %s', + s : 'par sekundi', + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : 'dan', + dd : translate, + M : 'mjesec', + MM : translate, + y : 'godinu', + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. } - return ( - this._milliseconds + - this._days * 864e5 + - (this._months % 12) * 2592e6 + - toInt(this._months / 12) * 31536e6 - ); - } - - function makeAs (alias) { - return function () { - return this.as(alias); - }; - } - - var asMilliseconds = makeAs('ms'); - var asSeconds = makeAs('s'); - var asMinutes = makeAs('m'); - var asHours = makeAs('h'); - var asDays = makeAs('d'); - var asWeeks = makeAs('w'); - var asMonths = makeAs('M'); - var asQuarters = makeAs('Q'); - var asYears = makeAs('y'); - - function clone$1 () { - return createDuration(this); - } - - function get$2 (units) { - units = normalizeUnits(units); - return this.isValid() ? this[units + 's']() : NaN; - } - - function makeGetter(name) { - return function () { - return this.isValid() ? this._data[name] : NaN; - }; - } + }); - var milliseconds = makeGetter('milliseconds'); - var seconds = makeGetter('seconds'); - var minutes = makeGetter('minutes'); - var hours = makeGetter('hours'); - var days = makeGetter('days'); - var months = makeGetter('months'); - var years = makeGetter('years'); + return hr; - function weeks () { - return absFloor(this.days() / 7); - } +}))); - var round = Math.round; - var thresholds = { - ss: 44, // a few seconds to seconds - s : 45, // seconds to minute - m : 45, // minutes to hour - h : 22, // hours to day - d : 26, // days to month - M : 11 // months to year - }; - // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize - function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { - return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); - } +/***/ }), +/* 67 */ +/***/ (function(module, exports, __webpack_require__) { - function relativeTime$1 (posNegDuration, withoutSuffix, locale) { - var duration = createDuration(posNegDuration).abs(); - var seconds = round(duration.as('s')); - var minutes = round(duration.as('m')); - var hours = round(duration.as('h')); - var days = round(duration.as('d')); - var months = round(duration.as('M')); - var years = round(duration.as('y')); +//! moment.js locale configuration - var a = seconds <= thresholds.ss && ['s', seconds] || - seconds < thresholds.s && ['ss', seconds] || - minutes <= 1 && ['m'] || - minutes < thresholds.m && ['mm', minutes] || - hours <= 1 && ['h'] || - hours < thresholds.h && ['hh', hours] || - days <= 1 && ['d'] || - days < thresholds.d && ['dd', days] || - months <= 1 && ['M'] || - months < thresholds.M && ['MM', months] || - years <= 1 && ['y'] || ['yy', years]; +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - a[2] = withoutSuffix; - a[3] = +posNegDuration > 0; - a[4] = locale; - return substituteTimeAgo.apply(null, a); - } - // This function allows you to set the rounding function for relative time strings - function getSetRelativeTimeRounding (roundingFunction) { - if (roundingFunction === undefined) { - return round; - } - if (typeof(roundingFunction) === 'function') { - round = roundingFunction; - return true; + var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' '); + function translate(number, withoutSuffix, key, isFuture) { + var num = number; + switch (key) { + case 's': + return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce'; + case 'ss': + return num + (isFuture || withoutSuffix) ? ' másodperc' : ' másodperce'; + case 'm': + return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce'); + case 'mm': + return num + (isFuture || withoutSuffix ? ' perc' : ' perce'); + case 'h': + return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája'); + case 'hh': + return num + (isFuture || withoutSuffix ? ' óra' : ' órája'); + case 'd': + return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja'); + case 'dd': + return num + (isFuture || withoutSuffix ? ' nap' : ' napja'); + case 'M': + return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); + case 'MM': + return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); + case 'y': + return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve'); + case 'yy': + return num + (isFuture || withoutSuffix ? ' év' : ' éve'); } - return false; + return ''; } - - // This function allows you to set a threshold for relative time strings - function getSetRelativeTimeThreshold (threshold, limit) { - if (thresholds[threshold] === undefined) { - return false; - } - if (limit === undefined) { - return thresholds[threshold]; - } - thresholds[threshold] = limit; - if (threshold === 's') { - thresholds.ss = limit - 1; - } - return true; + function week(isFuture) { + return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]'; } - function humanize (withSuffix) { - if (!this.isValid()) { - return this.localeData().invalidDate(); + var hu = moment.defineLocale('hu', { + months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'), + monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'), + weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'), + weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'), + weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'YYYY.MM.DD.', + LL : 'YYYY. MMMM D.', + LLL : 'YYYY. MMMM D. H:mm', + LLLL : 'YYYY. MMMM D., dddd H:mm' + }, + meridiemParse: /de|du/i, + isPM: function (input) { + return input.charAt(1).toLowerCase() === 'u'; + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 12) { + return isLower === true ? 'de' : 'DE'; + } else { + return isLower === true ? 'du' : 'DU'; + } + }, + calendar : { + sameDay : '[ma] LT[-kor]', + nextDay : '[holnap] LT[-kor]', + nextWeek : function () { + return week.call(this, true); + }, + lastDay : '[tegnap] LT[-kor]', + lastWeek : function () { + return week.call(this, false); + }, + sameElse : 'L' + }, + relativeTime : { + future : '%s múlva', + past : '%s', + s : translate, + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } + }); - var locale = this.localeData(); - var output = relativeTime$1(this, !withSuffix, locale); - - if (withSuffix) { - output = locale.pastFuture(+this, output); - } + return hu; - return locale.postformat(output); - } +}))); - var abs$1 = Math.abs; - function sign(x) { - return ((x > 0) - (x < 0)) || +x; - } +/***/ }), +/* 68 */ +/***/ (function(module, exports, __webpack_require__) { - function toISOString$1() { - // for ISO strings we do not use the normal bubbling rules: - // * milliseconds bubble up until they become hours - // * days do not bubble at all - // * months bubble up until they become years - // This is because there is no context-free conversion between hours and days - // (think of clock changes) - // and also not between days and months (28-31 days per month) - if (!this.isValid()) { - return this.localeData().invalidDate(); - } +//! moment.js locale configuration - var seconds = abs$1(this._milliseconds) / 1000; - var days = abs$1(this._days); - var months = abs$1(this._months); - var minutes, hours, years; +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - // 3600 seconds -> 60 minutes -> 1 hour - minutes = absFloor(seconds / 60); - hours = absFloor(minutes / 60); - seconds %= 60; - minutes %= 60; - // 12 months -> 1 year - years = absFloor(months / 12); - months %= 12; + var hyAm = moment.defineLocale('hy-am', { + months : { + format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'), + standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_') + }, + monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'), + weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'), + weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), + weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY թ.', + LLL : 'D MMMM YYYY թ., HH:mm', + LLLL : 'dddd, D MMMM YYYY թ., HH:mm' + }, + calendar : { + sameDay: '[այսօր] LT', + nextDay: '[վաղը] LT', + lastDay: '[երեկ] LT', + nextWeek: function () { + return 'dddd [օրը ժամը] LT'; + }, + lastWeek: function () { + return '[անցած] dddd [օրը ժամը] LT'; + }, + sameElse: 'L' + }, + relativeTime : { + future : '%s հետո', + past : '%s առաջ', + s : 'մի քանի վայրկյան', + ss : '%d վայրկյան', + m : 'րոպե', + mm : '%d րոպե', + h : 'ժամ', + hh : '%d ժամ', + d : 'օր', + dd : '%d օր', + M : 'ամիս', + MM : '%d ամիս', + y : 'տարի', + yy : '%d տարի' + }, + meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/, + isPM: function (input) { + return /^(ցերեկվա|երեկոյան)$/.test(input); + }, + meridiem : function (hour) { + if (hour < 4) { + return 'գիշերվա'; + } else if (hour < 12) { + return 'առավոտվա'; + } else if (hour < 17) { + return 'ցերեկվա'; + } else { + return 'երեկոյան'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}|\d{1,2}-(ին|րդ)/, + ordinal: function (number, period) { + switch (period) { + case 'DDD': + case 'w': + case 'W': + case 'DDDo': + if (number === 1) { + return number + '-ին'; + } + return number + '-րդ'; + default: + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. + } + }); + return hyAm; - // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js - var Y = years; - var M = months; - var D = days; - var h = hours; - var m = minutes; - var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; - var total = this.asSeconds(); +}))); - if (!total) { - // this is the same as C#'s (Noda) and python (isodate)... - // but not other JS (goog.date) - return 'P0D'; - } - var totalSign = total < 0 ? '-' : ''; - var ymSign = sign(this._months) !== sign(total) ? '-' : ''; - var daysSign = sign(this._days) !== sign(total) ? '-' : ''; - var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; +/***/ }), +/* 69 */ +/***/ (function(module, exports, __webpack_require__) { - return totalSign + 'P' + - (Y ? ymSign + Y + 'Y' : '') + - (M ? ymSign + M + 'M' : '') + - (D ? daysSign + D + 'D' : '') + - ((h || m || s) ? 'T' : '') + - (h ? hmsSign + h + 'H' : '') + - (m ? hmsSign + m + 'M' : '') + - (s ? hmsSign + s + 'S' : ''); - } +//! moment.js locale configuration - var proto$2 = Duration.prototype; +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; - proto$2.isValid = isValid$1; - proto$2.abs = abs; - proto$2.add = add$1; - proto$2.subtract = subtract$1; - proto$2.as = as; - proto$2.asMilliseconds = asMilliseconds; - proto$2.asSeconds = asSeconds; - proto$2.asMinutes = asMinutes; - proto$2.asHours = asHours; - proto$2.asDays = asDays; - proto$2.asWeeks = asWeeks; - proto$2.asMonths = asMonths; - proto$2.asQuarters = asQuarters; - proto$2.asYears = asYears; - proto$2.valueOf = valueOf$1; - proto$2._bubble = bubble; - proto$2.clone = clone$1; - proto$2.get = get$2; - proto$2.milliseconds = milliseconds; - proto$2.seconds = seconds; - proto$2.minutes = minutes; - proto$2.hours = hours; - proto$2.days = days; - proto$2.weeks = weeks; - proto$2.months = months; - proto$2.years = years; - proto$2.humanize = humanize; - proto$2.toISOString = toISOString$1; - proto$2.toString = toISOString$1; - proto$2.toJSON = toISOString$1; - proto$2.locale = locale; - proto$2.localeData = localeData; - proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); - proto$2.lang = lang; - - // Side effect imports - - // FORMATTING - - addFormatToken('X', 0, 0, 'unix'); - addFormatToken('x', 0, 0, 'valueOf'); - - // PARSING - - addRegexToken('x', matchSigned); - addRegexToken('X', matchTimestamp); - addParseToken('X', function (input, array, config) { - config._d = new Date(parseFloat(input, 10) * 1000); - }); - addParseToken('x', function (input, array, config) { - config._d = new Date(toInt(input)); - }); - - // Side effect imports - - - hooks.version = '2.24.0'; - - setHookCallback(createLocal); - - hooks.fn = proto; - hooks.min = min; - hooks.max = max; - hooks.now = now; - hooks.utc = createUTC; - hooks.unix = createUnix; - hooks.months = listMonths; - hooks.isDate = isDate; - hooks.locale = getSetGlobalLocale; - hooks.invalid = createInvalid; - hooks.duration = createDuration; - hooks.isMoment = isMoment; - hooks.weekdays = listWeekdays; - hooks.parseZone = createInZone; - hooks.localeData = getLocale; - hooks.isDuration = isDuration; - hooks.monthsShort = listMonthsShort; - hooks.weekdaysMin = listWeekdaysMin; - hooks.defineLocale = defineLocale; - hooks.updateLocale = updateLocale; - hooks.locales = listLocales; - hooks.weekdaysShort = listWeekdaysShort; - hooks.normalizeUnits = normalizeUnits; - hooks.relativeTimeRounding = getSetRelativeTimeRounding; - hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; - hooks.calendarFormat = getCalendarFormat; - hooks.prototype = proto; - - // currently HTML5 input type only supports 24-hour formats - hooks.HTML5_FMT = { - DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // - DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // - DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // - DATE: 'YYYY-MM-DD', // - TIME: 'HH:mm', // - TIME_SECONDS: 'HH:mm:ss', // - TIME_MS: 'HH:mm:ss.SSS', // - WEEK: 'GGGG-[W]WW', // - MONTH: 'YYYY-MM' // - }; - - return hooks; - -}))); - -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(5)(module))) - -/***/ }), -/* 41 */ -/***/ (function(module, exports, __webpack_require__) { - -var map = { - "./af": 42, - "./af.js": 42, - "./ar": 43, - "./ar-dz": 44, - "./ar-dz.js": 44, - "./ar-kw": 45, - "./ar-kw.js": 45, - "./ar-ly": 46, - "./ar-ly.js": 46, - "./ar-ma": 47, - "./ar-ma.js": 47, - "./ar-sa": 48, - "./ar-sa.js": 48, - "./ar-tn": 49, - "./ar-tn.js": 49, - "./ar.js": 43, - "./az": 50, - "./az.js": 50, - "./be": 51, - "./be.js": 51, - "./bg": 52, - "./bg.js": 52, - "./bm": 53, - "./bm.js": 53, - "./bn": 54, - "./bn.js": 54, - "./bo": 55, - "./bo.js": 55, - "./br": 56, - "./br.js": 56, - "./bs": 57, - "./bs.js": 57, - "./ca": 58, - "./ca.js": 58, - "./cs": 59, - "./cs.js": 59, - "./cv": 60, - "./cv.js": 60, - "./cy": 61, - "./cy.js": 61, - "./da": 62, - "./da.js": 62, - "./de": 63, - "./de-at": 64, - "./de-at.js": 64, - "./de-ch": 65, - "./de-ch.js": 65, - "./de.js": 63, - "./dv": 66, - "./dv.js": 66, - "./el": 67, - "./el.js": 67, - "./en-SG": 68, - "./en-SG.js": 68, - "./en-au": 69, - "./en-au.js": 69, - "./en-ca": 70, - "./en-ca.js": 70, - "./en-gb": 71, - "./en-gb.js": 71, - "./en-ie": 72, - "./en-ie.js": 72, - "./en-il": 73, - "./en-il.js": 73, - "./en-nz": 74, - "./en-nz.js": 74, - "./eo": 75, - "./eo.js": 75, - "./es": 76, - "./es-do": 77, - "./es-do.js": 77, - "./es-us": 78, - "./es-us.js": 78, - "./es.js": 76, - "./et": 79, - "./et.js": 79, - "./eu": 80, - "./eu.js": 80, - "./fa": 81, - "./fa.js": 81, - "./fi": 82, - "./fi.js": 82, - "./fo": 83, - "./fo.js": 83, - "./fr": 84, - "./fr-ca": 85, - "./fr-ca.js": 85, - "./fr-ch": 86, - "./fr-ch.js": 86, - "./fr.js": 84, - "./fy": 87, - "./fy.js": 87, - "./ga": 88, - "./ga.js": 88, - "./gd": 89, - "./gd.js": 89, - "./gl": 90, - "./gl.js": 90, - "./gom-latn": 91, - "./gom-latn.js": 91, - "./gu": 92, - "./gu.js": 92, - "./he": 93, - "./he.js": 93, - "./hi": 94, - "./hi.js": 94, - "./hr": 95, - "./hr.js": 95, - "./hu": 96, - "./hu.js": 96, - "./hy-am": 97, - "./hy-am.js": 97, - "./id": 98, - "./id.js": 98, - "./is": 99, - "./is.js": 99, - "./it": 100, - "./it-ch": 101, - "./it-ch.js": 101, - "./it.js": 100, - "./ja": 102, - "./ja.js": 102, - "./jv": 103, - "./jv.js": 103, - "./ka": 104, - "./ka.js": 104, - "./kk": 105, - "./kk.js": 105, - "./km": 106, - "./km.js": 106, - "./kn": 107, - "./kn.js": 107, - "./ko": 108, - "./ko.js": 108, - "./ku": 109, - "./ku.js": 109, - "./ky": 110, - "./ky.js": 110, - "./lb": 111, - "./lb.js": 111, - "./lo": 112, - "./lo.js": 112, - "./lt": 113, - "./lt.js": 113, - "./lv": 114, - "./lv.js": 114, - "./me": 115, - "./me.js": 115, - "./mi": 116, - "./mi.js": 116, - "./mk": 117, - "./mk.js": 117, - "./ml": 118, - "./ml.js": 118, - "./mn": 119, - "./mn.js": 119, - "./mr": 120, - "./mr.js": 120, - "./ms": 121, - "./ms-my": 122, - "./ms-my.js": 122, - "./ms.js": 121, - "./mt": 123, - "./mt.js": 123, - "./my": 124, - "./my.js": 124, - "./nb": 125, - "./nb.js": 125, - "./ne": 126, - "./ne.js": 126, - "./nl": 127, - "./nl-be": 128, - "./nl-be.js": 128, - "./nl.js": 127, - "./nn": 129, - "./nn.js": 129, - "./pa-in": 130, - "./pa-in.js": 130, - "./pl": 131, - "./pl.js": 131, - "./pt": 132, - "./pt-br": 133, - "./pt-br.js": 133, - "./pt.js": 132, - "./ro": 134, - "./ro.js": 134, - "./ru": 135, - "./ru.js": 135, - "./sd": 136, - "./sd.js": 136, - "./se": 137, - "./se.js": 137, - "./si": 138, - "./si.js": 138, - "./sk": 139, - "./sk.js": 139, - "./sl": 140, - "./sl.js": 140, - "./sq": 141, - "./sq.js": 141, - "./sr": 142, - "./sr-cyrl": 143, - "./sr-cyrl.js": 143, - "./sr.js": 142, - "./ss": 144, - "./ss.js": 144, - "./sv": 145, - "./sv.js": 145, - "./sw": 146, - "./sw.js": 146, - "./ta": 147, - "./ta.js": 147, - "./te": 148, - "./te.js": 148, - "./tet": 149, - "./tet.js": 149, - "./tg": 150, - "./tg.js": 150, - "./th": 151, - "./th.js": 151, - "./tl-ph": 152, - "./tl-ph.js": 152, - "./tlh": 153, - "./tlh.js": 153, - "./tr": 154, - "./tr.js": 154, - "./tzl": 155, - "./tzl.js": 155, - "./tzm": 156, - "./tzm-latn": 157, - "./tzm-latn.js": 157, - "./tzm.js": 156, - "./ug-cn": 158, - "./ug-cn.js": 158, - "./uk": 159, - "./uk.js": 159, - "./ur": 160, - "./ur.js": 160, - "./uz": 161, - "./uz-latn": 162, - "./uz-latn.js": 162, - "./uz.js": 161, - "./vi": 163, - "./vi.js": 163, - "./x-pseudo": 164, - "./x-pseudo.js": 164, - "./yo": 165, - "./yo.js": 165, - "./zh-cn": 166, - "./zh-cn.js": 166, - "./zh-hk": 167, - "./zh-hk.js": 167, - "./zh-tw": 168, - "./zh-tw.js": 168 -}; - - -function webpackContext(req) { - var id = webpackContextResolve(req); - return __webpack_require__(id); -} -function webpackContextResolve(req) { - if(!__webpack_require__.o(map, req)) { - var e = new Error("Cannot find module '" + req + "'"); - e.code = 'MODULE_NOT_FOUND'; - throw e; - } - return map[req]; -} -webpackContext.keys = function webpackContextKeys() { - return Object.keys(map); -}; -webpackContext.resolve = webpackContextResolve; -module.exports = webpackContext; -webpackContext.id = 41; - -/***/ }), -/* 42 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration - -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - - - var af = moment.defineLocale('af', { - months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'), - monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'), - weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'), - weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'), - weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'), - meridiemParse: /vm|nm/i, - isPM : function (input) { - return /^nm$/i.test(input); + var id = moment.defineLocale('id', { + months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Agt_Sep_Okt_Nov_Des'.split('_'), + weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'), + weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'), + weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /pagi|siang|sore|malam/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'siang') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'sore' || meridiem === 'malam') { + return hour + 12; + } }, meridiem : function (hours, minutes, isLower) { - if (hours < 12) { - return isLower ? 'vm' : 'VM'; + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'siang'; + } else if (hours < 19) { + return 'sore'; } else { - return isLower ? 'nm' : 'NM'; + return 'malam'; } }, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, calendar : { - sameDay : '[Vandag om] LT', - nextDay : '[Môre om] LT', - nextWeek : 'dddd [om] LT', - lastDay : '[Gister om] LT', - lastWeek : '[Laas] dddd [om] LT', + sameDay : '[Hari ini pukul] LT', + nextDay : '[Besok pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kemarin pukul] LT', + lastWeek : 'dddd [lalu pukul] LT', sameElse : 'L' }, relativeTime : { - future : 'oor %s', - past : '%s gelede', - s : '\'n paar sekondes', - ss : '%d sekondes', - m : '\'n minuut', - mm : '%d minute', - h : '\'n uur', - hh : '%d ure', - d : '\'n dag', - dd : '%d dae', - M : '\'n maand', - MM : '%d maande', - y : '\'n jaar', - yy : '%d jaar' - }, - dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, - ordinal : function (number) { - return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter + future : 'dalam %s', + past : '%s yang lalu', + s : 'beberapa detik', + ss : '%d detik', + m : 'semenit', + mm : '%d menit', + h : 'sejam', + hh : '%d jam', + d : 'sehari', + dd : '%d hari', + M : 'sebulan', + MM : '%d bulan', + y : 'setahun', + yy : '%d tahun' }, week : { - dow : 1, // Maandag is die eerste dag van die week. - doy : 4 // Die week wat die 4de Januarie bevat is die eerste week van die jaar. + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. } }); - return af; + return id; }))); /***/ }), -/* 43 */ +/* 70 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var symbolMap = { - '1': '١', - '2': '٢', - '3': '٣', - '4': '٤', - '5': '٥', - '6': '٦', - '7': '٧', - '8': '٨', - '9': '٩', - '0': '٠' - }, numberMap = { - '١': '1', - '٢': '2', - '٣': '3', - '٤': '4', - '٥': '5', - '٦': '6', - '٧': '7', - '٨': '8', - '٩': '9', - '٠': '0' - }, pluralForm = function (n) { - return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5; - }, plurals = { - s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'], - m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'], - h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'], - d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'], - M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'], - y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام'] - }, pluralize = function (u) { - return function (number, withoutSuffix, string, isFuture) { - var f = pluralForm(number), - str = plurals[u][pluralForm(number)]; - if (f === 2) { - str = str[withoutSuffix ? 0 : 1]; - } - return str.replace(/%d/i, number); - }; - }, months = [ - 'يناير', - 'فبراير', - 'مارس', - 'أبريل', - 'مايو', - 'يونيو', - 'يوليو', - 'أغسطس', - 'سبتمبر', - 'أكتوبر', - 'نوفمبر', - 'ديسمبر' - ]; + function plural(n) { + if (n % 100 === 11) { + return true; + } else if (n % 10 === 1) { + return false; + } + return true; + } + function translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': + return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum'; + case 'ss': + if (plural(number)) { + return result + (withoutSuffix || isFuture ? 'sekúndur' : 'sekúndum'); + } + return result + 'sekúnda'; + case 'm': + return withoutSuffix ? 'mínúta' : 'mínútu'; + case 'mm': + if (plural(number)) { + return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum'); + } else if (withoutSuffix) { + return result + 'mínúta'; + } + return result + 'mínútu'; + case 'hh': + if (plural(number)) { + return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum'); + } + return result + 'klukkustund'; + case 'd': + if (withoutSuffix) { + return 'dagur'; + } + return isFuture ? 'dag' : 'degi'; + case 'dd': + if (plural(number)) { + if (withoutSuffix) { + return result + 'dagar'; + } + return result + (isFuture ? 'daga' : 'dögum'); + } else if (withoutSuffix) { + return result + 'dagur'; + } + return result + (isFuture ? 'dag' : 'degi'); + case 'M': + if (withoutSuffix) { + return 'mánuður'; + } + return isFuture ? 'mánuð' : 'mánuði'; + case 'MM': + if (plural(number)) { + if (withoutSuffix) { + return result + 'mánuðir'; + } + return result + (isFuture ? 'mánuði' : 'mánuðum'); + } else if (withoutSuffix) { + return result + 'mánuður'; + } + return result + (isFuture ? 'mánuð' : 'mánuði'); + case 'y': + return withoutSuffix || isFuture ? 'ár' : 'ári'; + case 'yy': + if (plural(number)) { + return result + (withoutSuffix || isFuture ? 'ár' : 'árum'); + } + return result + (withoutSuffix || isFuture ? 'ár' : 'ári'); + } + } - var ar = moment.defineLocale('ar', { - months : months, - monthsShort : months, - weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), - weekdaysParseExact : true, + var is = moment.defineLocale('is', { + months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'), + monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'), + weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'), + weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'), + weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'), longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'D/\u200FM/\u200FYYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - meridiemParse: /ص|م/, - isPM : function (input) { - return 'م' === input; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'ص'; - } else { - return 'م'; - } + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY [kl.] H:mm', + LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm' }, calendar : { - sameDay: '[اليوم عند الساعة] LT', - nextDay: '[غدًا عند الساعة] LT', - nextWeek: 'dddd [عند الساعة] LT', - lastDay: '[أمس عند الساعة] LT', - lastWeek: 'dddd [عند الساعة] LT', - sameElse: 'L' + sameDay : '[í dag kl.] LT', + nextDay : '[á morgun kl.] LT', + nextWeek : 'dddd [kl.] LT', + lastDay : '[í gær kl.] LT', + lastWeek : '[síðasta] dddd [kl.] LT', + sameElse : 'L' }, relativeTime : { - future : 'بعد %s', - past : 'منذ %s', - s : pluralize('s'), - ss : pluralize('s'), - m : pluralize('m'), - mm : pluralize('m'), - h : pluralize('h'), - hh : pluralize('h'), - d : pluralize('d'), - dd : pluralize('d'), - M : pluralize('M'), - MM : pluralize('M'), - y : pluralize('y'), - yy : pluralize('y') - }, - preparse: function (string) { - return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { - return numberMap[match]; - }).replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }).replace(/,/g, '،'); + future : 'eftir %s', + past : 'fyrir %s síðan', + s : translate, + ss : translate, + m : translate, + mm : translate, + h : 'klukkustund', + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return ar; + return is; }))); /***/ }), -/* 44 */ +/* 71 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var arDz = moment.defineLocale('ar-dz', { - months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), - monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), - weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'), - weekdaysParseExact : true, + var it = moment.defineLocale('it', { + months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'), + monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'), + weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'), + weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'), + weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'), longDateFormat : { LT : 'HH:mm', LTS : 'HH:mm:ss', @@ -10130,446 +11445,586 @@ webpackContext.id = 41; LLLL : 'dddd D MMMM YYYY HH:mm' }, calendar : { - sameDay: '[اليوم على الساعة] LT', - nextDay: '[غدا على الساعة] LT', - nextWeek: 'dddd [على الساعة] LT', - lastDay: '[أمس على الساعة] LT', - lastWeek: 'dddd [على الساعة] LT', + sameDay: '[Oggi alle] LT', + nextDay: '[Domani alle] LT', + nextWeek: 'dddd [alle] LT', + lastDay: '[Ieri alle] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[la scorsa] dddd [alle] LT'; + default: + return '[lo scorso] dddd [alle] LT'; + } + }, sameElse: 'L' }, relativeTime : { - future : 'في %s', - past : 'منذ %s', - s : 'ثوان', - ss : '%d ثانية', - m : 'دقيقة', - mm : '%d دقائق', - h : 'ساعة', - hh : '%d ساعات', - d : 'يوم', - dd : '%d أيام', - M : 'شهر', - MM : '%d أشهر', - y : 'سنة', - yy : '%d سنوات' + future : function (s) { + return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s; + }, + past : '%s fa', + s : 'alcuni secondi', + ss : '%d secondi', + m : 'un minuto', + mm : '%d minuti', + h : 'un\'ora', + hh : '%d ore', + d : 'un giorno', + dd : '%d giorni', + M : 'un mese', + MM : '%d mesi', + y : 'un anno', + yy : '%d anni' }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal: '%dº', week : { - dow : 0, // Sunday is the first day of the week. + dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return arDz; + return it; }))); /***/ }), -/* 45 */ +/* 72 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var arKw = moment.defineLocale('ar-kw', { - months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), - monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), - weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', + var itCh = moment.defineLocale('it-ch', { + months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'), + monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'), + weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'), + weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'), + weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', + L : 'DD.MM.YYYY', LL : 'D MMMM YYYY', LLL : 'D MMMM YYYY HH:mm', LLLL : 'dddd D MMMM YYYY HH:mm' }, calendar : { - sameDay: '[اليوم على الساعة] LT', - nextDay: '[غدا على الساعة] LT', - nextWeek: 'dddd [على الساعة] LT', - lastDay: '[أمس على الساعة] LT', - lastWeek: 'dddd [على الساعة] LT', + sameDay: '[Oggi alle] LT', + nextDay: '[Domani alle] LT', + nextWeek: 'dddd [alle] LT', + lastDay: '[Ieri alle] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[la scorsa] dddd [alle] LT'; + default: + return '[lo scorso] dddd [alle] LT'; + } + }, sameElse: 'L' }, relativeTime : { - future : 'في %s', - past : 'منذ %s', - s : 'ثوان', - ss : '%d ثانية', - m : 'دقيقة', - mm : '%d دقائق', - h : 'ساعة', - hh : '%d ساعات', - d : 'يوم', - dd : '%d أيام', - M : 'شهر', - MM : '%d أشهر', - y : 'سنة', - yy : '%d سنوات' + future : function (s) { + return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s; + }, + past : '%s fa', + s : 'alcuni secondi', + ss : '%d secondi', + m : 'un minuto', + mm : '%d minuti', + h : 'un\'ora', + hh : '%d ore', + d : 'un giorno', + dd : '%d giorni', + M : 'un mese', + MM : '%d mesi', + y : 'un anno', + yy : '%d anni' }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal: '%dº', week : { - dow : 0, // Sunday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return arKw; + return itCh; }))); /***/ }), -/* 46 */ +/* 73 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var symbolMap = { - '1': '1', - '2': '2', - '3': '3', - '4': '4', - '5': '5', - '6': '6', - '7': '7', - '8': '8', - '9': '9', - '0': '0' - }, pluralForm = function (n) { - return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5; - }, plurals = { - s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'], - m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'], - h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'], - d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'], - M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'], - y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام'] - }, pluralize = function (u) { - return function (number, withoutSuffix, string, isFuture) { - var f = pluralForm(number), - str = plurals[u][pluralForm(number)]; - if (f === 2) { - str = str[withoutSuffix ? 0 : 1]; - } - return str.replace(/%d/i, number); - }; - }, months = [ - 'يناير', - 'فبراير', - 'مارس', - 'أبريل', - 'مايو', - 'يونيو', - 'يوليو', - 'أغسطس', - 'سبتمبر', - 'أكتوبر', - 'نوفمبر', - 'ديسمبر' - ]; - - var arLy = moment.defineLocale('ar-ly', { - months : months, - monthsShort : months, - weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), - weekdaysParseExact : true, + var ja = moment.defineLocale('ja', { + months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'), + weekdaysShort : '日_月_火_水_木_金_土'.split('_'), + weekdaysMin : '日_月_火_水_木_金_土'.split('_'), longDateFormat : { LT : 'HH:mm', LTS : 'HH:mm:ss', - L : 'D/\u200FM/\u200FYYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' + L : 'YYYY/MM/DD', + LL : 'YYYY年M月D日', + LLL : 'YYYY年M月D日 HH:mm', + LLLL : 'YYYY年M月D日 dddd HH:mm', + l : 'YYYY/MM/DD', + ll : 'YYYY年M月D日', + lll : 'YYYY年M月D日 HH:mm', + llll : 'YYYY年M月D日(ddd) HH:mm' }, - meridiemParse: /ص|م/, + meridiemParse: /午前|午後/i, isPM : function (input) { - return 'م' === input; + return input === '午後'; }, meridiem : function (hour, minute, isLower) { if (hour < 12) { - return 'ص'; + return '午前'; } else { - return 'م'; + return '午後'; } }, calendar : { - sameDay: '[اليوم عند الساعة] LT', - nextDay: '[غدًا عند الساعة] LT', - nextWeek: 'dddd [عند الساعة] LT', - lastDay: '[أمس عند الساعة] LT', - lastWeek: 'dddd [عند الساعة] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'بعد %s', - past : 'منذ %s', - s : pluralize('s'), - ss : pluralize('s'), - m : pluralize('m'), - mm : pluralize('m'), - h : pluralize('h'), - hh : pluralize('h'), - d : pluralize('d'), - dd : pluralize('d'), - M : pluralize('M'), - MM : pluralize('M'), - y : pluralize('y'), - yy : pluralize('y') - }, - preparse: function (string) { - return string.replace(/،/g, ','); + sameDay : '[今日] LT', + nextDay : '[明日] LT', + nextWeek : function (now) { + if (now.week() < this.week()) { + return '[来週]dddd LT'; + } else { + return 'dddd LT'; + } + }, + lastDay : '[昨日] LT', + lastWeek : function (now) { + if (this.week() < now.week()) { + return '[先週]dddd LT'; + } else { + return 'dddd LT'; + } + }, + sameElse : 'L' }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }).replace(/,/g, '،'); + dayOfMonthOrdinalParse : /\d{1,2}日/, + ordinal : function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '日'; + default: + return number; + } }, - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. + relativeTime : { + future : '%s後', + past : '%s前', + s : '数秒', + ss : '%d秒', + m : '1分', + mm : '%d分', + h : '1時間', + hh : '%d時間', + d : '1日', + dd : '%d日', + M : '1ヶ月', + MM : '%dヶ月', + y : '1年', + yy : '%d年' } }); - return arLy; + return ja; }))); /***/ }), -/* 47 */ +/* 74 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var arMa = moment.defineLocale('ar-ma', { - months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), - monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), - weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), - weekdaysParseExact : true, + var jv = moment.defineLocale('jv', { + months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'), + weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'), + weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'), + weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'), longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', + LT : 'HH.mm', + LTS : 'HH.mm.ss', L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /enjing|siyang|sonten|ndalu/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'enjing') { + return hour; + } else if (meridiem === 'siyang') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'sonten' || meridiem === 'ndalu') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'enjing'; + } else if (hours < 15) { + return 'siyang'; + } else if (hours < 19) { + return 'sonten'; + } else { + return 'ndalu'; + } }, calendar : { - sameDay: '[اليوم على الساعة] LT', - nextDay: '[غدا على الساعة] LT', - nextWeek: 'dddd [على الساعة] LT', - lastDay: '[أمس على الساعة] LT', - lastWeek: 'dddd [على الساعة] LT', - sameElse: 'L' + sameDay : '[Dinten puniko pukul] LT', + nextDay : '[Mbenjang pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kala wingi pukul] LT', + lastWeek : 'dddd [kepengker pukul] LT', + sameElse : 'L' }, relativeTime : { - future : 'في %s', - past : 'منذ %s', - s : 'ثوان', - ss : '%d ثانية', - m : 'دقيقة', - mm : '%d دقائق', - h : 'ساعة', - hh : '%d ساعات', - d : 'يوم', - dd : '%d أيام', - M : 'شهر', - MM : '%d أشهر', - y : 'سنة', - yy : '%d سنوات' + future : 'wonten ing %s', + past : '%s ingkang kepengker', + s : 'sawetawis detik', + ss : '%d detik', + m : 'setunggal menit', + mm : '%d menit', + h : 'setunggal jam', + hh : '%d jam', + d : 'sedinten', + dd : '%d dinten', + M : 'sewulan', + MM : '%d wulan', + y : 'setaun', + yy : '%d taun' }, week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. } }); - return arMa; + return jv; }))); /***/ }), -/* 48 */ +/* 75 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var symbolMap = { - '1': '١', - '2': '٢', - '3': '٣', - '4': '٤', - '5': '٥', - '6': '٦', - '7': '٧', - '8': '٨', - '9': '٩', - '0': '٠' - }, numberMap = { - '١': '1', - '٢': '2', - '٣': '3', - '٤': '4', - '٥': '5', - '٦': '6', - '٧': '7', - '٨': '8', - '٩': '9', - '٠': '0' - }; - - var arSa = moment.defineLocale('ar-sa', { - months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), - monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), - weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), - weekdaysParseExact : true, + var ka = moment.defineLocale('ka', { + months : { + standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'), + format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_') + }, + monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'), + weekdays : { + standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'), + format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'), + isFormat: /(წინა|შემდეგ)/ + }, + weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'), + weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'), longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', + LT : 'h:mm A', + LTS : 'h:mm:ss A', L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - meridiemParse: /ص|م/, - isPM : function (input) { - return 'م' === input; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'ص'; - } else { - return 'م'; - } + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' }, calendar : { - sameDay: '[اليوم على الساعة] LT', - nextDay: '[غدا على الساعة] LT', - nextWeek: 'dddd [على الساعة] LT', - lastDay: '[أمس على الساعة] LT', - lastWeek: 'dddd [على الساعة] LT', - sameElse: 'L' + sameDay : '[დღეს] LT[-ზე]', + nextDay : '[ხვალ] LT[-ზე]', + lastDay : '[გუშინ] LT[-ზე]', + nextWeek : '[შემდეგ] dddd LT[-ზე]', + lastWeek : '[წინა] dddd LT-ზე', + sameElse : 'L' }, relativeTime : { - future : 'في %s', - past : 'منذ %s', - s : 'ثوان', - ss : '%d ثانية', - m : 'دقيقة', - mm : '%d دقائق', - h : 'ساعة', - hh : '%d ساعات', - d : 'يوم', - dd : '%d أيام', - M : 'شهر', - MM : '%d أشهر', - y : 'سنة', - yy : '%d سنوات' - }, - preparse: function (string) { - return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { - return numberMap[match]; - }).replace(/،/g, ','); + future : function (s) { + return (/(წამი|წუთი|საათი|წელი)/).test(s) ? + s.replace(/ი$/, 'ში') : + s + 'ში'; + }, + past : function (s) { + if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) { + return s.replace(/(ი|ე)$/, 'ის წინ'); + } + if ((/წელი/).test(s)) { + return s.replace(/წელი$/, 'წლის წინ'); + } + }, + s : 'რამდენიმე წამი', + ss : '%d წამი', + m : 'წუთი', + mm : '%d წუთი', + h : 'საათი', + hh : '%d საათი', + d : 'დღე', + dd : '%d დღე', + M : 'თვე', + MM : '%d თვე', + y : 'წელი', + yy : '%d წელი' }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }).replace(/,/g, '،'); + dayOfMonthOrdinalParse: /0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/, + ordinal : function (number) { + if (number === 0) { + return number; + } + if (number === 1) { + return number + '-ლი'; + } + if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) { + return 'მე-' + number; + } + return number + '-ე'; }, week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. + dow : 1, + doy : 7 } }); - return arSa; + return ka; }))); /***/ }), -/* 49 */ +/* 76 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var arTn = moment.defineLocale('ar-tn', { - months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), - monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), - weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'), - weekdaysParseExact : true, - longDateFormat: { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY HH:mm', - LLLL: 'dddd D MMMM YYYY HH:mm' + var suffixes = { + 0: '-ші', + 1: '-ші', + 2: '-ші', + 3: '-ші', + 4: '-ші', + 5: '-ші', + 6: '-шы', + 7: '-ші', + 8: '-ші', + 9: '-шы', + 10: '-шы', + 20: '-шы', + 30: '-шы', + 40: '-шы', + 50: '-ші', + 60: '-шы', + 70: '-ші', + 80: '-ші', + 90: '-шы', + 100: '-ші' + }; + + var kk = moment.defineLocale('kk', { + months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'), + monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'), + weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'), + weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'), + weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' }, - calendar: { - sameDay: '[اليوم على الساعة] LT', - nextDay: '[غدا على الساعة] LT', - nextWeek: 'dddd [على الساعة] LT', - lastDay: '[أمس على الساعة] LT', - lastWeek: 'dddd [على الساعة] LT', + calendar : { + sameDay : '[Бүгін сағат] LT', + nextDay : '[Ертең сағат] LT', + nextWeek : 'dddd [сағат] LT', + lastDay : '[Кеше сағат] LT', + lastWeek : '[Өткен аптаның] dddd [сағат] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ішінде', + past : '%s бұрын', + s : 'бірнеше секунд', + ss : '%d секунд', + m : 'бір минут', + mm : '%d минут', + h : 'бір сағат', + hh : '%d сағат', + d : 'бір күн', + dd : '%d күн', + M : 'бір ай', + MM : '%d ай', + y : 'бір жыл', + yy : '%d жыл' + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ші|шы)/, + ordinal : function (number) { + var a = number % 10, + b = number >= 100 ? 100 : null; + return number + (suffixes[number] || suffixes[a] || suffixes[b]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. + } + }); + + return kk; + +}))); + + +/***/ }), +/* 77 */ +/***/ (function(module, exports, __webpack_require__) { + +//! moment.js locale configuration + +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; + + + var symbolMap = { + '1': '១', + '2': '២', + '3': '៣', + '4': '៤', + '5': '៥', + '6': '៦', + '7': '៧', + '8': '៨', + '9': '៩', + '0': '០' + }, numberMap = { + '១': '1', + '២': '2', + '៣': '3', + '៤': '4', + '៥': '5', + '៦': '6', + '៧': '7', + '៨': '8', + '៩': '9', + '០': '0' + }; + + var km = moment.defineLocale('km', { + months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split( + '_' + ), + monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split( + '_' + ), + weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'), + weekdaysShort: 'អា_ច_អ_ព_ព្រ_សុ_ស'.split('_'), + weekdaysMin: 'អា_ច_អ_ព_ព្រ_សុ_ស'.split('_'), + weekdaysParseExact: true, + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm' + }, + meridiemParse: /ព្រឹក|ល្ងាច/, + isPM: function (input) { + return input === 'ល្ងាច'; + }, + meridiem: function (hour, minute, isLower) { + if (hour < 12) { + return 'ព្រឹក'; + } else { + return 'ល្ងាច'; + } + }, + calendar: { + sameDay: '[ថ្ងៃនេះ ម៉ោង] LT', + nextDay: '[ស្អែក ម៉ោង] LT', + nextWeek: 'dddd [ម៉ោង] LT', + lastDay: '[ម្សិលមិញ ម៉ោង] LT', + lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT', sameElse: 'L' }, relativeTime: { - future: 'في %s', - past: 'منذ %s', - s: 'ثوان', - ss : '%d ثانية', - m: 'دقيقة', - mm: '%d دقائق', - h: 'ساعة', - hh: '%d ساعات', - d: 'يوم', - dd: '%d أيام', - M: 'شهر', - MM: '%d أشهر', - y: 'سنة', - yy: '%d سنوات' + future: '%sទៀត', + past: '%sមុន', + s: 'ប៉ុន្មានវិនាទី', + ss: '%d វិនាទី', + m: 'មួយនាទី', + mm: '%d នាទី', + h: 'មួយម៉ោង', + hh: '%d ម៉ោង', + d: 'មួយថ្ងៃ', + dd: '%d ថ្ងៃ', + M: 'មួយខែ', + MM: '%d ខែ', + y: 'មួយឆ្នាំ', + yy: '%d ឆ្នាំ' + }, + dayOfMonthOrdinalParse : /ទី\d{1,2}/, + ordinal : 'ទី%d', + preparse: function (string) { + return string.replace(/[១២៣៤៥៦៧៨៩០]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); }, week: { dow: 1, // Monday is the first day of the week. @@ -10577,857 +12032,926 @@ webpackContext.id = 41; } }); - return arTn; + return km; }))); /***/ }), -/* 50 */ +/* 78 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var suffixes = { - 1: '-inci', - 5: '-inci', - 8: '-inci', - 70: '-inci', - 80: '-inci', - 2: '-nci', - 7: '-nci', - 20: '-nci', - 50: '-nci', - 3: '-üncü', - 4: '-üncü', - 100: '-üncü', - 6: '-ncı', - 9: '-uncu', - 10: '-uncu', - 30: '-uncu', - 60: '-ıncı', - 90: '-ıncı' + var symbolMap = { + '1': '೧', + '2': '೨', + '3': '೩', + '4': '೪', + '5': '೫', + '6': '೬', + '7': '೭', + '8': '೮', + '9': '೯', + '0': '೦' + }, + numberMap = { + '೧': '1', + '೨': '2', + '೩': '3', + '೪': '4', + '೫': '5', + '೬': '6', + '೭': '7', + '೮': '8', + '೯': '9', + '೦': '0' }; - var az = moment.defineLocale('az', { - months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'), - monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'), - weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'), - weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'), - weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'), - weekdaysParseExact : true, + var kn = moment.defineLocale('kn', { + months : 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split('_'), + monthsShort : 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂ_ಅಕ್ಟೋ_ನವೆಂ_ಡಿಸೆಂ'.split('_'), + monthsParseExact: true, + weekdays : 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split('_'), + weekdaysShort : 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'), + weekdaysMin : 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'), longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', + LT : 'A h:mm', + LTS : 'A h:mm:ss', + L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' + LLL : 'D MMMM YYYY, A h:mm', + LLLL : 'dddd, D MMMM YYYY, A h:mm' }, calendar : { - sameDay : '[bugün saat] LT', - nextDay : '[sabah saat] LT', - nextWeek : '[gələn həftə] dddd [saat] LT', - lastDay : '[dünən] LT', - lastWeek : '[keçən həftə] dddd [saat] LT', + sameDay : '[ಇಂದು] LT', + nextDay : '[ನಾಳೆ] LT', + nextWeek : 'dddd, LT', + lastDay : '[ನಿನ್ನೆ] LT', + lastWeek : '[ಕೊನೆಯ] dddd, LT', sameElse : 'L' }, relativeTime : { - future : '%s sonra', - past : '%s əvvəl', - s : 'birneçə saniyə', - ss : '%d saniyə', - m : 'bir dəqiqə', - mm : '%d dəqiqə', - h : 'bir saat', - hh : '%d saat', - d : 'bir gün', - dd : '%d gün', - M : 'bir ay', - MM : '%d ay', - y : 'bir il', - yy : '%d il' + future : '%s ನಂತರ', + past : '%s ಹಿಂದೆ', + s : 'ಕೆಲವು ಕ್ಷಣಗಳು', + ss : '%d ಸೆಕೆಂಡುಗಳು', + m : 'ಒಂದು ನಿಮಿಷ', + mm : '%d ನಿಮಿಷ', + h : 'ಒಂದು ಗಂಟೆ', + hh : '%d ಗಂಟೆ', + d : 'ಒಂದು ದಿನ', + dd : '%d ದಿನ', + M : 'ಒಂದು ತಿಂಗಳು', + MM : '%d ತಿಂಗಳು', + y : 'ಒಂದು ವರ್ಷ', + yy : '%d ವರ್ಷ' }, - meridiemParse: /gecə|səhər|gündüz|axşam/, - isPM : function (input) { - return /^(gündüz|axşam)$/.test(input); + preparse: function (string) { + return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'ರಾತ್ರಿ') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') { + return hour; + } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'ಸಂಜೆ') { + return hour + 12; + } }, meridiem : function (hour, minute, isLower) { if (hour < 4) { - return 'gecə'; - } else if (hour < 12) { - return 'səhər'; + return 'ರಾತ್ರಿ'; + } else if (hour < 10) { + return 'ಬೆಳಿಗ್ಗೆ'; } else if (hour < 17) { - return 'gündüz'; + return 'ಮಧ್ಯಾಹ್ನ'; + } else if (hour < 20) { + return 'ಸಂಜೆ'; } else { - return 'axşam'; + return 'ರಾತ್ರಿ'; } }, - dayOfMonthOrdinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/, + dayOfMonthOrdinalParse: /\d{1,2}(ನೇ)/, ordinal : function (number) { - if (number === 0) { // special case for zero - return number + '-ıncı'; - } - var a = number % 10, - b = number % 100 - a, - c = number >= 100 ? 100 : null; - return number + (suffixes[a] || suffixes[b] || suffixes[c]); + return number + 'ನೇ'; }, week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 6th is the first week of the year. } }); - return az; + return kn; }))); /***/ }), -/* 51 */ +/* 79 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - function plural(word, num) { - var forms = word.split('_'); - return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); - } - function relativeTimeWithPlural(number, withoutSuffix, key) { - var format = { - 'ss': withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд', - 'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін', - 'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін', - 'dd': 'дзень_дні_дзён', - 'MM': 'месяц_месяцы_месяцаў', - 'yy': 'год_гады_гадоў' - }; - if (key === 'm') { - return withoutSuffix ? 'хвіліна' : 'хвіліну'; - } - else if (key === 'h') { - return withoutSuffix ? 'гадзіна' : 'гадзіну'; - } - else { - return number + ' ' + plural(format[key], +number); - } - } - - var be = moment.defineLocale('be', { - months : { - format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'), - standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_') - }, - monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'), - weekdays : { - format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'), - standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'), - isFormat: /\[ ?[Ууў] ?(?:мінулую|наступную)? ?\] ?dddd/ - }, - weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), - weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), + var ko = moment.defineLocale('ko', { + months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), + monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), + weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'), + weekdaysShort : '일_월_화_수_목_금_토'.split('_'), + weekdaysMin : '일_월_화_수_목_금_토'.split('_'), longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY г.', - LLL : 'D MMMM YYYY г., HH:mm', - LLLL : 'dddd, D MMMM YYYY г., HH:mm' + LT : 'A h:mm', + LTS : 'A h:mm:ss', + L : 'YYYY.MM.DD.', + LL : 'YYYY년 MMMM D일', + LLL : 'YYYY년 MMMM D일 A h:mm', + LLLL : 'YYYY년 MMMM D일 dddd A h:mm', + l : 'YYYY.MM.DD.', + ll : 'YYYY년 MMMM D일', + lll : 'YYYY년 MMMM D일 A h:mm', + llll : 'YYYY년 MMMM D일 dddd A h:mm' }, calendar : { - sameDay: '[Сёння ў] LT', - nextDay: '[Заўтра ў] LT', - lastDay: '[Учора ў] LT', - nextWeek: function () { - return '[У] dddd [ў] LT'; - }, - lastWeek: function () { - switch (this.day()) { - case 0: - case 3: - case 5: - case 6: - return '[У мінулую] dddd [ў] LT'; - case 1: - case 2: - case 4: - return '[У мінулы] dddd [ў] LT'; - } - }, - sameElse: 'L' + sameDay : '오늘 LT', + nextDay : '내일 LT', + nextWeek : 'dddd LT', + lastDay : '어제 LT', + lastWeek : '지난주 dddd LT', + sameElse : 'L' }, relativeTime : { - future : 'праз %s', - past : '%s таму', - s : 'некалькі секунд', - m : relativeTimeWithPlural, - mm : relativeTimeWithPlural, - h : relativeTimeWithPlural, - hh : relativeTimeWithPlural, - d : 'дзень', - dd : relativeTimeWithPlural, - M : 'месяц', - MM : relativeTimeWithPlural, - y : 'год', - yy : relativeTimeWithPlural - }, - meridiemParse: /ночы|раніцы|дня|вечара/, - isPM : function (input) { - return /^(дня|вечара)$/.test(input); - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'ночы'; - } else if (hour < 12) { - return 'раніцы'; - } else if (hour < 17) { - return 'дня'; - } else { - return 'вечара'; - } + future : '%s 후', + past : '%s 전', + s : '몇 초', + ss : '%d초', + m : '1분', + mm : '%d분', + h : '한 시간', + hh : '%d시간', + d : '하루', + dd : '%d일', + M : '한 달', + MM : '%d달', + y : '일 년', + yy : '%d년' }, - dayOfMonthOrdinalParse: /\d{1,2}-(і|ы|га)/, - ordinal: function (number, period) { + dayOfMonthOrdinalParse : /\d{1,2}(일|월|주)/, + ordinal : function (number, period) { switch (period) { - case 'M': case 'd': + case 'D': case 'DDD': + return number + '일'; + case 'M': + return number + '월'; case 'w': case 'W': - return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы'; - case 'D': - return number + '-га'; + return number + '주'; default: return number; } }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. + meridiemParse : /오전|오후/, + isPM : function (token) { + return token === '오후'; + }, + meridiem : function (hour, minute, isUpper) { + return hour < 12 ? '오전' : '오후'; } }); - return be; + return ko; }))); /***/ }), -/* 52 */ +/* 80 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var bg = moment.defineLocale('bg', { - months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'), - monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'), - weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'), - weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'), - weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'D.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY H:mm', - LLLL : 'dddd, D MMMM YYYY H:mm' - }, - calendar : { - sameDay : '[Днес в] LT', - nextDay : '[Утре в] LT', - nextWeek : 'dddd [в] LT', - lastDay : '[Вчера в] LT', - lastWeek : function () { - switch (this.day()) { - case 0: - case 3: - case 6: - return '[В изминалата] dddd [в] LT'; - case 1: - case 2: - case 4: - case 5: - return '[В изминалия] dddd [в] LT'; - } - }, - sameElse : 'L' - }, - relativeTime : { - future : 'след %s', - past : 'преди %s', - s : 'няколко секунди', - ss : '%d секунди', - m : 'минута', - mm : '%d минути', - h : 'час', - hh : '%d часа', - d : 'ден', - dd : '%d дни', - M : 'месец', - MM : '%d месеца', - y : 'година', - yy : '%d години' + var symbolMap = { + '1': '١', + '2': '٢', + '3': '٣', + '4': '٤', + '5': '٥', + '6': '٦', + '7': '٧', + '8': '٨', + '9': '٩', + '0': '٠' + }, numberMap = { + '١': '1', + '٢': '2', + '٣': '3', + '٤': '4', + '٥': '5', + '٦': '6', + '٧': '7', + '٨': '8', + '٩': '9', + '٠': '0' + }, + months = [ + 'کانونی دووەم', + 'شوبات', + 'ئازار', + 'نیسان', + 'ئایار', + 'حوزەیران', + 'تەمموز', + 'ئاب', + 'ئەیلوول', + 'تشرینی یەكەم', + 'تشرینی دووەم', + 'كانونی یەکەم' + ]; + + + var ku = moment.defineLocale('ku', { + months : months, + monthsShort : months, + weekdays : 'یه‌كشه‌ممه‌_دووشه‌ممه‌_سێشه‌ممه‌_چوارشه‌ممه‌_پێنجشه‌ممه‌_هه‌ینی_شه‌ممه‌'.split('_'), + weekdaysShort : 'یه‌كشه‌م_دووشه‌م_سێشه‌م_چوارشه‌م_پێنجشه‌م_هه‌ینی_شه‌ممه‌'.split('_'), + weekdaysMin : 'ی_د_س_چ_پ_ه_ش'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' }, - dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, - ordinal : function (number) { - var lastDigit = number % 10, - last2Digits = number % 100; - if (number === 0) { - return number + '-ев'; - } else if (last2Digits === 0) { - return number + '-ен'; - } else if (last2Digits > 10 && last2Digits < 20) { - return number + '-ти'; - } else if (lastDigit === 1) { - return number + '-ви'; - } else if (lastDigit === 2) { - return number + '-ри'; - } else if (lastDigit === 7 || lastDigit === 8) { - return number + '-ми'; + meridiemParse: /ئێواره‌|به‌یانی/, + isPM: function (input) { + return /ئێواره‌/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'به‌یانی'; } else { - return number + '-ти'; + return 'ئێواره‌'; } }, + calendar : { + sameDay : '[ئه‌مرۆ كاتژمێر] LT', + nextDay : '[به‌یانی كاتژمێر] LT', + nextWeek : 'dddd [كاتژمێر] LT', + lastDay : '[دوێنێ كاتژمێر] LT', + lastWeek : 'dddd [كاتژمێر] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'له‌ %s', + past : '%s', + s : 'چه‌ند چركه‌یه‌ك', + ss : 'چركه‌ %d', + m : 'یه‌ك خوله‌ك', + mm : '%d خوله‌ك', + h : 'یه‌ك كاتژمێر', + hh : '%d كاتژمێر', + d : 'یه‌ك ڕۆژ', + dd : '%d ڕۆژ', + M : 'یه‌ك مانگ', + MM : '%d مانگ', + y : 'یه‌ك ساڵ', + yy : '%d ساڵ' + }, + preparse: function (string) { + return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { + return numberMap[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }).replace(/,/g, '،'); + }, week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 12th is the first week of the year. } }); - return bg; + return ku; }))); /***/ }), -/* 53 */ +/* 81 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var bm = moment.defineLocale('bm', { - months : 'Zanwuyekalo_Fewuruyekalo_Marisikalo_Awirilikalo_Mɛkalo_Zuwɛnkalo_Zuluyekalo_Utikalo_Sɛtanburukalo_ɔkutɔburukalo_Nowanburukalo_Desanburukalo'.split('_'), - monthsShort : 'Zan_Few_Mar_Awi_Mɛ_Zuw_Zul_Uti_Sɛt_ɔku_Now_Des'.split('_'), - weekdays : 'Kari_Ntɛnɛn_Tarata_Araba_Alamisa_Juma_Sibiri'.split('_'), - weekdaysShort : 'Kar_Ntɛ_Tar_Ara_Ala_Jum_Sib'.split('_'), - weekdaysMin : 'Ka_Nt_Ta_Ar_Al_Ju_Si'.split('_'), + var suffixes = { + 0: '-чү', + 1: '-чи', + 2: '-чи', + 3: '-чү', + 4: '-чү', + 5: '-чи', + 6: '-чы', + 7: '-чи', + 8: '-чи', + 9: '-чу', + 10: '-чу', + 20: '-чы', + 30: '-чу', + 40: '-чы', + 50: '-чү', + 60: '-чы', + 70: '-чи', + 80: '-чи', + 90: '-чу', + 100: '-чү' + }; + + var ky = moment.defineLocale('ky', { + months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'), + monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'), + weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'), + weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'), + weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'), longDateFormat : { LT : 'HH:mm', LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'MMMM [tile] D [san] YYYY', - LLL : 'MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm', - LLLL : 'dddd MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm' + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' }, calendar : { - sameDay : '[Bi lɛrɛ] LT', - nextDay : '[Sini lɛrɛ] LT', - nextWeek : 'dddd [don lɛrɛ] LT', - lastDay : '[Kunu lɛrɛ] LT', - lastWeek : 'dddd [tɛmɛnen lɛrɛ] LT', + sameDay : '[Бүгүн саат] LT', + nextDay : '[Эртең саат] LT', + nextWeek : 'dddd [саат] LT', + lastDay : '[Кечээ саат] LT', + lastWeek : '[Өткөн аптанын] dddd [күнү] [саат] LT', sameElse : 'L' }, relativeTime : { - future : '%s kɔnɔ', - past : 'a bɛ %s bɔ', - s : 'sanga dama dama', - ss : 'sekondi %d', - m : 'miniti kelen', - mm : 'miniti %d', - h : 'lɛrɛ kelen', - hh : 'lɛrɛ %d', - d : 'tile kelen', - dd : 'tile %d', - M : 'kalo kelen', - MM : 'kalo %d', - y : 'san kelen', - yy : 'san %d' + future : '%s ичинде', + past : '%s мурун', + s : 'бирнече секунд', + ss : '%d секунд', + m : 'бир мүнөт', + mm : '%d мүнөт', + h : 'бир саат', + hh : '%d саат', + d : 'бир күн', + dd : '%d күн', + M : 'бир ай', + MM : '%d ай', + y : 'бир жыл', + yy : '%d жыл' + }, + dayOfMonthOrdinalParse: /\d{1,2}-(чи|чы|чү|чу)/, + ordinal : function (number) { + var a = number % 10, + b = number >= 100 ? 100 : null; + return number + (suffixes[number] || suffixes[a] || suffixes[b]); }, week : { dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + doy : 7 // The week that contains Jan 7th is the first week of the year. } }); - return bm; + return ky; }))); /***/ }), -/* 54 */ +/* 82 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var symbolMap = { - '1': '১', - '2': '২', - '3': '৩', - '4': '৪', - '5': '৫', - '6': '৬', - '7': '৭', - '8': '৮', - '9': '৯', - '0': '০' - }, - numberMap = { - '১': '1', - '২': '2', - '৩': '3', - '৪': '4', - '৫': '5', - '৬': '6', - '৭': '7', - '৮': '8', - '৯': '9', - '০': '0' - }; - - var bn = moment.defineLocale('bn', { - months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'), - monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'), - weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'), - weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'), - weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'), - longDateFormat : { - LT : 'A h:mm সময়', - LTS : 'A h:mm:ss সময়', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm সময়', - LLLL : 'dddd, D MMMM YYYY, A h:mm সময়' - }, - calendar : { - sameDay : '[আজ] LT', - nextDay : '[আগামীকাল] LT', - nextWeek : 'dddd, LT', - lastDay : '[গতকাল] LT', - lastWeek : '[গত] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s পরে', - past : '%s আগে', - s : 'কয়েক সেকেন্ড', - ss : '%d সেকেন্ড', - m : 'এক মিনিট', - mm : '%d মিনিট', - h : 'এক ঘন্টা', - hh : '%d ঘন্টা', - d : 'এক দিন', - dd : '%d দিন', - M : 'এক মাস', - MM : '%d মাস', - y : 'এক বছর', - yy : '%d বছর' - }, - preparse: function (string) { - return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); - }, - meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eng Minutt', 'enger Minutt'], + 'h': ['eng Stonn', 'enger Stonn'], + 'd': ['een Dag', 'engem Dag'], + 'M': ['ee Mount', 'engem Mount'], + 'y': ['ee Joer', 'engem Joer'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + function processFutureTime(string) { + var number = string.substr(0, string.indexOf(' ')); + if (eifelerRegelAppliesToNumber(number)) { + return 'a ' + string; + } + return 'an ' + string; + } + function processPastTime(string) { + var number = string.substr(0, string.indexOf(' ')); + if (eifelerRegelAppliesToNumber(number)) { + return 'viru ' + string; + } + return 'virun ' + string; + } + /** + * Returns true if the word before the given number loses the '-n' ending. + * e.g. 'an 10 Deeg' but 'a 5 Deeg' + * + * @param number {integer} + * @returns {boolean} + */ + function eifelerRegelAppliesToNumber(number) { + number = parseInt(number, 10); + if (isNaN(number)) { + return false; + } + if (number < 0) { + // Negative Number --> always true + return true; + } else if (number < 10) { + // Only 1 digit + if (4 <= number && number <= 7) { + return true; } - if ((meridiem === 'রাত' && hour >= 4) || - (meridiem === 'দুপুর' && hour < 5) || - meridiem === 'বিকাল') { - return hour + 12; - } else { - return hour; + return false; + } else if (number < 100) { + // 2 digits + var lastDigit = number % 10, firstDigit = number / 10; + if (lastDigit === 0) { + return eifelerRegelAppliesToNumber(firstDigit); + } + return eifelerRegelAppliesToNumber(lastDigit); + } else if (number < 10000) { + // 3 or 4 digits --> recursively check first digit + while (number >= 10) { + number = number / 10; } + return eifelerRegelAppliesToNumber(number); + } else { + // Anything larger than 4 digits: recursively check first n-3 digits + number = number / 1000; + return eifelerRegelAppliesToNumber(number); + } + } + + var lb = moment.defineLocale('lb', { + months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'), + monthsParseExact : true, + weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'), + weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'), + weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'), + weekdaysParseExact : true, + longDateFormat: { + LT: 'H:mm [Auer]', + LTS: 'H:mm:ss [Auer]', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm [Auer]', + LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]' }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'রাত'; - } else if (hour < 10) { - return 'সকাল'; - } else if (hour < 17) { - return 'দুপুর'; - } else if (hour < 20) { - return 'বিকাল'; - } else { - return 'রাত'; + calendar: { + sameDay: '[Haut um] LT', + sameElse: 'L', + nextDay: '[Muer um] LT', + nextWeek: 'dddd [um] LT', + lastDay: '[Gëschter um] LT', + lastWeek: function () { + // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule + switch (this.day()) { + case 2: + case 4: + return '[Leschten] dddd [um] LT'; + default: + return '[Leschte] dddd [um] LT'; + } } }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. + relativeTime : { + future : processFutureTime, + past : processPastTime, + s : 'e puer Sekonnen', + ss : '%d Sekonnen', + m : processRelativeTime, + mm : '%d Minutten', + h : processRelativeTime, + hh : '%d Stonnen', + d : processRelativeTime, + dd : '%d Deeg', + M : processRelativeTime, + MM : '%d Méint', + y : processRelativeTime, + yy : '%d Joer' + }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. } }); - return bn; + return lb; }))); /***/ }), -/* 55 */ +/* 83 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var symbolMap = { - '1': '༡', - '2': '༢', - '3': '༣', - '4': '༤', - '5': '༥', - '6': '༦', - '7': '༧', - '8': '༨', - '9': '༩', - '0': '༠' - }, - numberMap = { - '༡': '1', - '༢': '2', - '༣': '3', - '༤': '4', - '༥': '5', - '༦': '6', - '༧': '7', - '༨': '8', - '༩': '9', - '༠': '0' - }; - - var bo = moment.defineLocale('bo', { - months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), - monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), - weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'), - weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), - weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), + var lo = moment.defineLocale('lo', { + months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'), + monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'), + weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), + weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), + weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'), + weekdaysParseExact : true, longDateFormat : { - LT : 'A h:mm', - LTS : 'A h:mm:ss', + LT : 'HH:mm', + LTS : 'HH:mm:ss', L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm', - LLLL : 'dddd, D MMMM YYYY, A h:mm' + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'ວັນdddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/, + isPM: function (input) { + return input === 'ຕອນແລງ'; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ຕອນເຊົ້າ'; + } else { + return 'ຕອນແລງ'; + } }, calendar : { - sameDay : '[དི་རིང] LT', - nextDay : '[སང་ཉིན] LT', - nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT', - lastDay : '[ཁ་སང] LT', - lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT', + sameDay : '[ມື້ນີ້ເວລາ] LT', + nextDay : '[ມື້ອື່ນເວລາ] LT', + nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT', + lastDay : '[ມື້ວານນີ້ເວລາ] LT', + lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT', sameElse : 'L' }, relativeTime : { - future : '%s ལ་', - past : '%s སྔན་ལ', - s : 'ལམ་སང', - ss : '%d སྐར་ཆ།', - m : 'སྐར་མ་གཅིག', - mm : '%d སྐར་མ', - h : 'ཆུ་ཚོད་གཅིག', - hh : '%d ཆུ་ཚོད', - d : 'ཉིན་གཅིག', - dd : '%d ཉིན་', - M : 'ཟླ་བ་གཅིག', - MM : '%d ཟླ་བ', - y : 'ལོ་གཅིག', - yy : '%d ལོ' - }, - preparse: function (string) { - return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); + future : 'ອີກ %s', + past : '%sຜ່ານມາ', + s : 'ບໍ່ເທົ່າໃດວິນາທີ', + ss : '%d ວິນາທີ' , + m : '1 ນາທີ', + mm : '%d ນາທີ', + h : '1 ຊົ່ວໂມງ', + hh : '%d ຊົ່ວໂມງ', + d : '1 ມື້', + dd : '%d ມື້', + M : '1 ເດືອນ', + MM : '%d ເດືອນ', + y : '1 ປີ', + yy : '%d ປີ' }, - meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if ((meridiem === 'མཚན་མོ' && hour >= 4) || - (meridiem === 'ཉིན་གུང' && hour < 5) || - meridiem === 'དགོང་དག') { - return hour + 12; + dayOfMonthOrdinalParse: /(ທີ່)\d{1,2}/, + ordinal : function (number) { + return 'ທີ່' + number; + } + }); + + return lo; + +}))); + + +/***/ }), +/* 84 */ +/***/ (function(module, exports, __webpack_require__) { + +//! moment.js locale configuration + +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; + + + var units = { + 'ss' : 'sekundė_sekundžių_sekundes', + 'm' : 'minutė_minutės_minutę', + 'mm': 'minutės_minučių_minutes', + 'h' : 'valanda_valandos_valandą', + 'hh': 'valandos_valandų_valandas', + 'd' : 'diena_dienos_dieną', + 'dd': 'dienos_dienų_dienas', + 'M' : 'mėnuo_mėnesio_mėnesį', + 'MM': 'mėnesiai_mėnesių_mėnesius', + 'y' : 'metai_metų_metus', + 'yy': 'metai_metų_metus' + }; + function translateSeconds(number, withoutSuffix, key, isFuture) { + if (withoutSuffix) { + return 'kelios sekundės'; + } else { + return isFuture ? 'kelių sekundžių' : 'kelias sekundes'; + } + } + function translateSingular(number, withoutSuffix, key, isFuture) { + return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]); + } + function special(number) { + return number % 10 === 0 || (number > 10 && number < 20); + } + function forms(key) { + return units[key].split('_'); + } + function translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + if (number === 1) { + return result + translateSingular(number, withoutSuffix, key[0], isFuture); + } else if (withoutSuffix) { + return result + (special(number) ? forms(key)[1] : forms(key)[0]); + } else { + if (isFuture) { + return result + forms(key)[1]; } else { - return hour; + return result + (special(number) ? forms(key)[1] : forms(key)[2]); } + } + } + var lt = moment.defineLocale('lt', { + months : { + format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'), + standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'), + isFormat: /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/ }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'མཚན་མོ'; - } else if (hour < 10) { - return 'ཞོགས་ཀས'; - } else if (hour < 17) { - return 'ཉིན་གུང'; - } else if (hour < 20) { - return 'དགོང་དག'; - } else { - return 'མཚན་མོ'; - } + monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'), + weekdays : { + format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'), + standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'), + isFormat: /dddd HH:mm/ + }, + weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'), + weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'YYYY [m.] MMMM D [d.]', + LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]', + LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]', + l : 'YYYY-MM-DD', + ll : 'YYYY [m.] MMMM D [d.]', + lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]', + llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]' + }, + calendar : { + sameDay : '[Šiandien] LT', + nextDay : '[Rytoj] LT', + nextWeek : 'dddd LT', + lastDay : '[Vakar] LT', + lastWeek : '[Praėjusį] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : 'po %s', + past : 'prieš %s', + s : translateSeconds, + ss : translate, + m : translateSingular, + mm : translate, + h : translateSingular, + hh : translate, + d : translateSingular, + dd : translate, + M : translateSingular, + MM : translate, + y : translateSingular, + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2}-oji/, + ordinal : function (number) { + return number + '-oji'; }, week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return bo; + return lt; }))); /***/ }), -/* 56 */ +/* 85 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - function relativeTimeWithMutation(number, withoutSuffix, key) { - var format = { - 'mm': 'munutenn', - 'MM': 'miz', - 'dd': 'devezh' - }; - return number + ' ' + mutation(format[key], number); - } - function specialMutationForYears(number) { - switch (lastNumber(number)) { - case 1: - case 3: - case 4: - case 5: - case 9: - return number + ' bloaz'; - default: - return number + ' vloaz'; + var units = { + 'ss': 'sekundes_sekundēm_sekunde_sekundes'.split('_'), + 'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'), + 'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'), + 'h': 'stundas_stundām_stunda_stundas'.split('_'), + 'hh': 'stundas_stundām_stunda_stundas'.split('_'), + 'd': 'dienas_dienām_diena_dienas'.split('_'), + 'dd': 'dienas_dienām_diena_dienas'.split('_'), + 'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), + 'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), + 'y': 'gada_gadiem_gads_gadi'.split('_'), + 'yy': 'gada_gadiem_gads_gadi'.split('_') + }; + /** + * @param withoutSuffix boolean true = a length of time; false = before/after a period of time. + */ + function format(forms, number, withoutSuffix) { + if (withoutSuffix) { + // E.g. "21 minūte", "3 minūtes". + return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3]; + } else { + // E.g. "21 minūtes" as in "pēc 21 minūtes". + // E.g. "3 minūtēm" as in "pēc 3 minūtēm". + return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1]; } } - function lastNumber(number) { - if (number > 9) { - return lastNumber(number % 10); - } - return number; + function relativeTimeWithPlural(number, withoutSuffix, key) { + return number + ' ' + format(units[key], number, withoutSuffix); } - function mutation(text, number) { - if (number === 2) { - return softMutation(text); - } - return text; + function relativeTimeWithSingular(number, withoutSuffix, key) { + return format(units[key], number, withoutSuffix); } - function softMutation(text) { - var mutationTable = { - 'm': 'v', - 'b': 'v', - 'd': 'z' - }; - if (mutationTable[text.charAt(0)] === undefined) { - return text; - } - return mutationTable[text.charAt(0)] + text.substring(1); + function relativeSeconds(number, withoutSuffix) { + return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm'; } - var br = moment.defineLocale('br', { - months : 'Genver_C\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'), - monthsShort : 'Gen_C\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'), - weekdays : 'Sul_Lun_Meurzh_Merc\'her_Yaou_Gwener_Sadorn'.split('_'), - weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'), - weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'), + var lv = moment.defineLocale('lv', { + months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'), + monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'), + weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'), + weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'), + weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'), weekdaysParseExact : true, longDateFormat : { - LT : 'h[e]mm A', - LTS : 'h[e]mm:ss A', - L : 'DD/MM/YYYY', - LL : 'D [a viz] MMMM YYYY', - LLL : 'D [a viz] MMMM YYYY h[e]mm A', - LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A' + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY.', + LL : 'YYYY. [gada] D. MMMM', + LLL : 'YYYY. [gada] D. MMMM, HH:mm', + LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm' }, calendar : { - sameDay : '[Hiziv da] LT', - nextDay : '[Warc\'hoazh da] LT', - nextWeek : 'dddd [da] LT', - lastDay : '[Dec\'h da] LT', - lastWeek : 'dddd [paset da] LT', + sameDay : '[Šodien pulksten] LT', + nextDay : '[Rīt pulksten] LT', + nextWeek : 'dddd [pulksten] LT', + lastDay : '[Vakar pulksten] LT', + lastWeek : '[Pagājušā] dddd [pulksten] LT', sameElse : 'L' }, relativeTime : { - future : 'a-benn %s', - past : '%s \'zo', - s : 'un nebeud segondennoù', - ss : '%d eilenn', - m : 'ur vunutenn', - mm : relativeTimeWithMutation, - h : 'un eur', - hh : '%d eur', - d : 'un devezh', - dd : relativeTimeWithMutation, - M : 'ur miz', - MM : relativeTimeWithMutation, - y : 'ur bloaz', - yy : specialMutationForYears - }, - dayOfMonthOrdinalParse: /\d{1,2}(añ|vet)/, - ordinal : function (number) { - var output = (number === 1) ? 'añ' : 'vet'; - return number + output; + future : 'pēc %s', + past : 'pirms %s', + s : relativeSeconds, + ss : relativeTimeWithPlural, + m : relativeTimeWithSingular, + mm : relativeTimeWithPlural, + h : relativeTimeWithSingular, + hh : relativeTimeWithPlural, + d : relativeTimeWithSingular, + dd : relativeTimeWithPlural, + M : relativeTimeWithSingular, + MM : relativeTimeWithPlural, + y : relativeTimeWithSingular, + yy : relativeTimeWithPlural }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return br; + return lv; }))); /***/ }), -/* 57 */ +/* 86 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - function translate(number, withoutSuffix, key) { - var result = number + ' '; - switch (key) { - case 'ss': - if (number === 1) { - result += 'sekunda'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'sekunde'; - } else { - result += 'sekundi'; - } - return result; - case 'm': - return withoutSuffix ? 'jedna minuta' : 'jedne minute'; - case 'mm': - if (number === 1) { - result += 'minuta'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'minute'; - } else { - result += 'minuta'; - } - return result; - case 'h': - return withoutSuffix ? 'jedan sat' : 'jednog sata'; - case 'hh': - if (number === 1) { - result += 'sat'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'sata'; - } else { - result += 'sati'; - } - return result; - case 'dd': - if (number === 1) { - result += 'dan'; - } else { - result += 'dana'; - } - return result; - case 'MM': - if (number === 1) { - result += 'mjesec'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'mjeseca'; - } else { - result += 'mjeseci'; - } - return result; - case 'yy': - if (number === 1) { - result += 'godina'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'godine'; - } else { - result += 'godina'; - } - return result; + var translator = { + words: { //Different grammatical cases + ss: ['sekund', 'sekunda', 'sekundi'], + m: ['jedan minut', 'jednog minuta'], + mm: ['minut', 'minuta', 'minuta'], + h: ['jedan sat', 'jednog sata'], + hh: ['sat', 'sata', 'sati'], + dd: ['dan', 'dana', 'dana'], + MM: ['mjesec', 'mjeseca', 'mjeseci'], + yy: ['godina', 'godine', 'godina'] + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); + }, + translate: function (number, withoutSuffix, key) { + var wordKey = translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return number + ' ' + translator.correctGrammaticalCase(number, wordKey); + } } - } + }; - var bs = moment.defineLocale('bs', { - months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'), - monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'), - monthsParseExact: true, - weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), - weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), - weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), + var me = moment.defineLocale('me', { + months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'), + monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'), + monthsParseExact : true, + weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), + weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'), weekdaysParseExact : true, - longDateFormat : { - LT : 'H:mm', + longDateFormat: { + LT: 'H:mm', LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY H:mm', - LLLL : 'dddd, D. MMMM YYYY H:mm' + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm' }, - calendar : { - sameDay : '[danas u] LT', - nextDay : '[sutra u] LT', - nextWeek : function () { + calendar: { + sameDay: '[danas u] LT', + nextDay: '[sjutra u] LT', + + nextWeek: function () { switch (this.day()) { case 0: return '[u] [nedjelju] [u] LT'; @@ -11442,38 +12966,36 @@ webpackContext.id = 41; return '[u] dddd [u] LT'; } }, - lastDay : '[jučer u] LT', + lastDay : '[juče u] LT', lastWeek : function () { - switch (this.day()) { - case 0: - case 3: - return '[prošlu] dddd [u] LT'; - case 6: - return '[prošle] [subote] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[prošli] dddd [u] LT'; - } + var lastWeekDays = [ + '[prošle] [nedjelje] [u] LT', + '[prošlog] [ponedjeljka] [u] LT', + '[prošlog] [utorka] [u] LT', + '[prošle] [srijede] [u] LT', + '[prošlog] [četvrtka] [u] LT', + '[prošlog] [petka] [u] LT', + '[prošle] [subote] [u] LT' + ]; + return lastWeekDays[this.day()]; }, sameElse : 'L' }, relativeTime : { future : 'za %s', past : 'prije %s', - s : 'par sekundi', - ss : translate, - m : translate, - mm : translate, - h : translate, - hh : translate, + s : 'nekoliko sekundi', + ss : translator.translate, + m : translator.translate, + mm : translator.translate, + h : translator.translate, + hh : translator.translate, d : 'dan', - dd : translate, + dd : translator.translate, M : 'mjesec', - MM : translate, + MM : translator.translate, y : 'godinu', - yy : translate + yy : translator.translate }, dayOfMonthOrdinalParse: /\d{1,2}\./, ordinal : '%d.', @@ -11483,1059 +13005,1123 @@ webpackContext.id = 41; } }); - return bs; + return me; }))); /***/ }), -/* 58 */ +/* 87 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var ca = moment.defineLocale('ca', { - months : { - standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'), - format: 'de gener_de febrer_de març_d\'abril_de maig_de juny_de juliol_d\'agost_de setembre_d\'octubre_de novembre_de desembre'.split('_'), - isFormat: /D[oD]?(\s)+MMMM/ + var mi = moment.defineLocale('mi', { + months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'), + monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'), + monthsRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, + monthsStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, + monthsShortRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, + monthsShortStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i, + weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'), + weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'), + weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY [i] HH:mm', + LLLL: 'dddd, D MMMM YYYY [i] HH:mm' }, - monthsShort : 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split('_'), - monthsParseExact : true, - weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'), - weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'), - weekdaysMin : 'dg_dl_dt_dc_dj_dv_ds'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM [de] YYYY', - ll : 'D MMM YYYY', - LLL : 'D MMMM [de] YYYY [a les] H:mm', - lll : 'D MMM YYYY, H:mm', - LLLL : 'dddd D MMMM [de] YYYY [a les] H:mm', - llll : 'ddd D MMM YYYY, H:mm' - }, - calendar : { - sameDay : function () { - return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - nextDay : function () { - return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - nextWeek : function () { - return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - lastDay : function () { - return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - lastWeek : function () { - return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - sameElse : 'L' - }, - relativeTime : { - future : 'd\'aquí %s', - past : 'fa %s', - s : 'uns segons', - ss : '%d segons', - m : 'un minut', - mm : '%d minuts', - h : 'una hora', - hh : '%d hores', - d : 'un dia', - dd : '%d dies', - M : 'un mes', - MM : '%d mesos', - y : 'un any', - yy : '%d anys' + calendar: { + sameDay: '[i teie mahana, i] LT', + nextDay: '[apopo i] LT', + nextWeek: 'dddd [i] LT', + lastDay: '[inanahi i] LT', + lastWeek: 'dddd [whakamutunga i] LT', + sameElse: 'L' }, - dayOfMonthOrdinalParse: /\d{1,2}(r|n|t|è|a)/, - ordinal : function (number, period) { - var output = (number === 1) ? 'r' : - (number === 2) ? 'n' : - (number === 3) ? 'r' : - (number === 4) ? 't' : 'è'; - if (period === 'w' || period === 'W') { - output = 'a'; - } - return number + output; + relativeTime: { + future: 'i roto i %s', + past: '%s i mua', + s: 'te hēkona ruarua', + ss: '%d hēkona', + m: 'he meneti', + mm: '%d meneti', + h: 'te haora', + hh: '%d haora', + d: 'he ra', + dd: '%d ra', + M: 'he marama', + MM: '%d marama', + y: 'he tau', + yy: '%d tau' }, + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal: '%dº', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return ca; + return mi; }))); /***/ }), -/* 59 */ +/* 88 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'), - monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_'); - - var monthsParse = [/^led/i, /^úno/i, /^bře/i, /^dub/i, /^kvě/i, /^(čvn|červen$|června)/i, /^(čvc|červenec|července)/i, /^srp/i, /^zář/i, /^říj/i, /^lis/i, /^pro/i]; - // NOTE: 'červen' is substring of 'červenec'; therefore 'červenec' must precede 'červen' in the regex to be fully matched. - // Otherwise parser matches '1. červenec' as '1. červen' + 'ec'. - var monthsRegex = /^(leden|únor|březen|duben|květen|červenec|července|červen|června|srpen|září|říjen|listopad|prosinec|led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i; - - function plural(n) { - return (n > 1) && (n < 5) && (~~(n / 10) !== 1); - } - function translate(number, withoutSuffix, key, isFuture) { - var result = number + ' '; - switch (key) { - case 's': // a few seconds / in a few seconds / a few seconds ago - return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami'; - case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'sekundy' : 'sekund'); - } else { - return result + 'sekundami'; - } - break; - case 'm': // a minute / in a minute / a minute ago - return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou'); - case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'minuty' : 'minut'); - } else { - return result + 'minutami'; - } - break; - case 'h': // an hour / in an hour / an hour ago - return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); - case 'hh': // 9 hours / in 9 hours / 9 hours ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'hodiny' : 'hodin'); - } else { - return result + 'hodinami'; - } - break; - case 'd': // a day / in a day / a day ago - return (withoutSuffix || isFuture) ? 'den' : 'dnem'; - case 'dd': // 9 days / in 9 days / 9 days ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'dny' : 'dní'); - } else { - return result + 'dny'; - } - break; - case 'M': // a month / in a month / a month ago - return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem'; - case 'MM': // 9 months / in 9 months / 9 months ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'měsíce' : 'měsíců'); - } else { - return result + 'měsíci'; - } - break; - case 'y': // a year / in a year / a year ago - return (withoutSuffix || isFuture) ? 'rok' : 'rokem'; - case 'yy': // 9 years / in 9 years / 9 years ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'roky' : 'let'); - } else { - return result + 'lety'; - } - break; - } - } - - var cs = moment.defineLocale('cs', { - months : months, - monthsShort : monthsShort, - monthsRegex : monthsRegex, - monthsShortRegex : monthsRegex, - // NOTE: 'červen' is substring of 'červenec'; therefore 'červenec' must precede 'červen' in the regex to be fully matched. - // Otherwise parser matches '1. červenec' as '1. červen' + 'ec'. - monthsStrictRegex : /^(leden|ledna|února|únor|březen|března|duben|dubna|květen|května|červenec|července|červen|června|srpen|srpna|září|říjen|října|listopadu|listopad|prosinec|prosince)/i, - monthsShortStrictRegex : /^(led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i, - monthsParse : monthsParse, - longMonthsParse : monthsParse, - shortMonthsParse : monthsParse, - weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'), - weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'), - weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'), + var mk = moment.defineLocale('mk', { + months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'), + monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'), + weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'), + weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'), + weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'), longDateFormat : { - LT: 'H:mm', + LT : 'H:mm', LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY H:mm', - LLLL : 'dddd D. MMMM YYYY H:mm', - l : 'D. M. YYYY' + L : 'D.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd, D MMMM YYYY H:mm' }, calendar : { - sameDay: '[dnes v] LT', - nextDay: '[zítra v] LT', - nextWeek: function () { + sameDay : '[Денес во] LT', + nextDay : '[Утре во] LT', + nextWeek : '[Во] dddd [во] LT', + lastDay : '[Вчера во] LT', + lastWeek : function () { switch (this.day()) { case 0: - return '[v neděli v] LT'; - case 1: - case 2: - return '[v] dddd [v] LT'; case 3: - return '[ve středu v] LT'; - case 4: - return '[ve čtvrtek v] LT'; - case 5: - return '[v pátek v] LT'; case 6: - return '[v sobotu v] LT'; - } - }, - lastDay: '[včera v] LT', - lastWeek: function () { - switch (this.day()) { - case 0: - return '[minulou neděli v] LT'; + return '[Изминатата] dddd [во] LT'; case 1: case 2: - return '[minulé] dddd [v] LT'; - case 3: - return '[minulou středu v] LT'; case 4: case 5: - return '[minulý] dddd [v] LT'; - case 6: - return '[minulou sobotu v] LT'; + return '[Изминатиот] dddd [во] LT'; } }, - sameElse: 'L' + sameElse : 'L' }, relativeTime : { - future : 'za %s', - past : 'před %s', - s : translate, - ss : translate, - m : translate, - mm : translate, - h : translate, - hh : translate, - d : translate, - dd : translate, - M : translate, - MM : translate, - y : translate, - yy : translate + future : 'после %s', + past : 'пред %s', + s : 'неколку секунди', + ss : '%d секунди', + m : 'минута', + mm : '%d минути', + h : 'час', + hh : '%d часа', + d : 'ден', + dd : '%d дена', + M : 'месец', + MM : '%d месеци', + y : 'година', + yy : '%d години' + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, + ordinal : function (number) { + var lastDigit = number % 10, + last2Digits = number % 100; + if (number === 0) { + return number + '-ев'; + } else if (last2Digits === 0) { + return number + '-ен'; + } else if (last2Digits > 10 && last2Digits < 20) { + return number + '-ти'; + } else if (lastDigit === 1) { + return number + '-ви'; + } else if (lastDigit === 2) { + return number + '-ри'; + } else if (lastDigit === 7 || lastDigit === 8) { + return number + '-ми'; + } else { + return number + '-ти'; + } }, - dayOfMonthOrdinalParse : /\d{1,2}\./, - ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + doy : 7 // The week that contains Jan 7th is the first week of the year. } }); - return cs; + return mk; }))); /***/ }), -/* 60 */ +/* 89 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var cv = moment.defineLocale('cv', { - months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'), - monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'), - weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'), - weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'), - weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'), + var ml = moment.defineLocale('ml', { + months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'), + monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'), + monthsParseExact : true, + weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'), + weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'), + weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'), longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD-MM-YYYY', - LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]', - LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm', - LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm' + LT : 'A h:mm -നു', + LTS : 'A h:mm:ss -നു', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm -നു', + LLLL : 'dddd, D MMMM YYYY, A h:mm -നു' }, calendar : { - sameDay: '[Паян] LT [сехетре]', - nextDay: '[Ыран] LT [сехетре]', - lastDay: '[Ӗнер] LT [сехетре]', - nextWeek: '[Ҫитес] dddd LT [сехетре]', - lastWeek: '[Иртнӗ] dddd LT [сехетре]', - sameElse: 'L' + sameDay : '[ഇന്ന്] LT', + nextDay : '[നാളെ] LT', + nextWeek : 'dddd, LT', + lastDay : '[ഇന്നലെ] LT', + lastWeek : '[കഴിഞ്ഞ] dddd, LT', + sameElse : 'L' }, relativeTime : { - future : function (output) { - var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран'; - return output + affix; - }, - past : '%s каялла', - s : 'пӗр-ик ҫеккунт', - ss : '%d ҫеккунт', - m : 'пӗр минут', - mm : '%d минут', - h : 'пӗр сехет', - hh : '%d сехет', - d : 'пӗр кун', - dd : '%d кун', - M : 'пӗр уйӑх', - MM : '%d уйӑх', - y : 'пӗр ҫул', - yy : '%d ҫул' - }, - dayOfMonthOrdinalParse: /\d{1,2}-мӗш/, - ordinal : '%d-мӗш', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - return cv; - -}))); - - -/***/ }), -/* 61 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration - -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - - - var cy = moment.defineLocale('cy', { - months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'), - monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'), - weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'), - weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'), - weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'), - weekdaysParseExact : true, - // time formats are the same as en-gb - longDateFormat: { - LT: 'HH:mm', - LTS : 'HH:mm:ss', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY HH:mm', - LLLL: 'dddd, D MMMM YYYY HH:mm' - }, - calendar: { - sameDay: '[Heddiw am] LT', - nextDay: '[Yfory am] LT', - nextWeek: 'dddd [am] LT', - lastDay: '[Ddoe am] LT', - lastWeek: 'dddd [diwethaf am] LT', - sameElse: 'L' - }, - relativeTime: { - future: 'mewn %s', - past: '%s yn ôl', - s: 'ychydig eiliadau', - ss: '%d eiliad', - m: 'munud', - mm: '%d munud', - h: 'awr', - hh: '%d awr', - d: 'diwrnod', - dd: '%d diwrnod', - M: 'mis', - MM: '%d mis', - y: 'blwyddyn', - yy: '%d flynedd' + future : '%s കഴിഞ്ഞ്', + past : '%s മുൻപ്', + s : 'അൽപ നിമിഷങ്ങൾ', + ss : '%d സെക്കൻഡ്', + m : 'ഒരു മിനിറ്റ്', + mm : '%d മിനിറ്റ്', + h : 'ഒരു മണിക്കൂർ', + hh : '%d മണിക്കൂർ', + d : 'ഒരു ദിവസം', + dd : '%d ദിവസം', + M : 'ഒരു മാസം', + MM : '%d മാസം', + y : 'ഒരു വർഷം', + yy : '%d വർഷം' }, - dayOfMonthOrdinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/, - // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh - ordinal: function (number) { - var b = number, - output = '', - lookup = [ - '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed - 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed - ]; - if (b > 20) { - if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) { - output = 'fed'; // not 30ain, 70ain or 90ain - } else { - output = 'ain'; - } - } else if (b > 0) { - output = lookup[b]; + meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ((meridiem === 'രാത്രി' && hour >= 4) || + meridiem === 'ഉച്ച കഴിഞ്ഞ്' || + meridiem === 'വൈകുന്നേരം') { + return hour + 12; + } else { + return hour; } - return number + output; }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'രാത്രി'; + } else if (hour < 12) { + return 'രാവിലെ'; + } else if (hour < 17) { + return 'ഉച്ച കഴിഞ്ഞ്'; + } else if (hour < 20) { + return 'വൈകുന്നേരം'; + } else { + return 'രാത്രി'; + } } }); - return cy; + return ml; }))); /***/ }), -/* 62 */ +/* 90 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var da = moment.defineLocale('da', { - months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'), - monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), - weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), - weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'), - weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), + function translate(number, withoutSuffix, key, isFuture) { + switch (key) { + case 's': + return withoutSuffix ? 'хэдхэн секунд' : 'хэдхэн секундын'; + case 'ss': + return number + (withoutSuffix ? ' секунд' : ' секундын'); + case 'm': + case 'mm': + return number + (withoutSuffix ? ' минут' : ' минутын'); + case 'h': + case 'hh': + return number + (withoutSuffix ? ' цаг' : ' цагийн'); + case 'd': + case 'dd': + return number + (withoutSuffix ? ' өдөр' : ' өдрийн'); + case 'M': + case 'MM': + return number + (withoutSuffix ? ' сар' : ' сарын'); + case 'y': + case 'yy': + return number + (withoutSuffix ? ' жил' : ' жилийн'); + default: + return number; + } + } + + var mn = moment.defineLocale('mn', { + months : 'Нэгдүгээр сар_Хоёрдугаар сар_Гуравдугаар сар_Дөрөвдүгээр сар_Тавдугаар сар_Зургадугаар сар_Долдугаар сар_Наймдугаар сар_Есдүгээр сар_Аравдугаар сар_Арван нэгдүгээр сар_Арван хоёрдугаар сар'.split('_'), + monthsShort : '1 сар_2 сар_3 сар_4 сар_5 сар_6 сар_7 сар_8 сар_9 сар_10 сар_11 сар_12 сар'.split('_'), + monthsParseExact : true, + weekdays : 'Ням_Даваа_Мягмар_Лхагва_Пүрэв_Баасан_Бямба'.split('_'), + weekdaysShort : 'Ням_Дав_Мяг_Лха_Пүр_Баа_Бям'.split('_'), + weekdaysMin : 'Ня_Да_Мя_Лх_Пү_Ба_Бя'.split('_'), + weekdaysParseExact : true, longDateFormat : { LT : 'HH:mm', LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY HH:mm', - LLLL : 'dddd [d.] D. MMMM YYYY [kl.] HH:mm' + L : 'YYYY-MM-DD', + LL : 'YYYY оны MMMMын D', + LLL : 'YYYY оны MMMMын D HH:mm', + LLLL : 'dddd, YYYY оны MMMMын D HH:mm' }, - calendar : { - sameDay : '[i dag kl.] LT', - nextDay : '[i morgen kl.] LT', - nextWeek : 'på dddd [kl.] LT', - lastDay : '[i går kl.] LT', - lastWeek : '[i] dddd[s kl.] LT', - sameElse : 'L' + meridiemParse: /ҮӨ|ҮХ/i, + isPM : function (input) { + return input === 'ҮХ'; }, - relativeTime : { - future : 'om %s', - past : '%s siden', - s : 'få sekunder', - ss : '%d sekunder', - m : 'et minut', - mm : '%d minutter', - h : 'en time', - hh : '%d timer', - d : 'en dag', - dd : '%d dage', - M : 'en måned', - MM : '%d måneder', - y : 'et år', - yy : '%d år' + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ҮӨ'; + } else { + return 'ҮХ'; + } }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + calendar : { + sameDay : '[Өнөөдөр] LT', + nextDay : '[Маргааш] LT', + nextWeek : '[Ирэх] dddd LT', + lastDay : '[Өчигдөр] LT', + lastWeek : '[Өнгөрсөн] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s дараа', + past : '%s өмнө', + s : translate, + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate + }, + dayOfMonthOrdinalParse: /\d{1,2} өдөр/, + ordinal : function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + ' өдөр'; + default: + return number; + } } }); - return da; + return mn; }))); /***/ }), -/* 63 */ +/* 91 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - function processRelativeTime(number, withoutSuffix, key, isFuture) { - var format = { - 'm': ['eine Minute', 'einer Minute'], - 'h': ['eine Stunde', 'einer Stunde'], - 'd': ['ein Tag', 'einem Tag'], - 'dd': [number + ' Tage', number + ' Tagen'], - 'M': ['ein Monat', 'einem Monat'], - 'MM': [number + ' Monate', number + ' Monaten'], - 'y': ['ein Jahr', 'einem Jahr'], - 'yy': [number + ' Jahre', number + ' Jahren'] - }; - return withoutSuffix ? format[key][0] : format[key][1]; + var symbolMap = { + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + '0': '०' + }, + numberMap = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0' + }; + + function relativeTimeMr(number, withoutSuffix, string, isFuture) + { + var output = ''; + if (withoutSuffix) { + switch (string) { + case 's': output = 'काही सेकंद'; break; + case 'ss': output = '%d सेकंद'; break; + case 'm': output = 'एक मिनिट'; break; + case 'mm': output = '%d मिनिटे'; break; + case 'h': output = 'एक तास'; break; + case 'hh': output = '%d तास'; break; + case 'd': output = 'एक दिवस'; break; + case 'dd': output = '%d दिवस'; break; + case 'M': output = 'एक महिना'; break; + case 'MM': output = '%d महिने'; break; + case 'y': output = 'एक वर्ष'; break; + case 'yy': output = '%d वर्षे'; break; + } + } + else { + switch (string) { + case 's': output = 'काही सेकंदां'; break; + case 'ss': output = '%d सेकंदां'; break; + case 'm': output = 'एका मिनिटा'; break; + case 'mm': output = '%d मिनिटां'; break; + case 'h': output = 'एका तासा'; break; + case 'hh': output = '%d तासां'; break; + case 'd': output = 'एका दिवसा'; break; + case 'dd': output = '%d दिवसां'; break; + case 'M': output = 'एका महिन्या'; break; + case 'MM': output = '%d महिन्यां'; break; + case 'y': output = 'एका वर्षा'; break; + case 'yy': output = '%d वर्षां'; break; + } + } + return output.replace(/%d/i, number); } - var de = moment.defineLocale('de', { - months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), - monthsShort : 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'), + var mr = moment.defineLocale('mr', { + months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'), + monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'), monthsParseExact : true, - weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), - weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), - weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), - weekdaysParseExact : true, + weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), + weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'), + weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), longDateFormat : { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY HH:mm', - LLLL : 'dddd, D. MMMM YYYY HH:mm' + LT : 'A h:mm वाजता', + LTS : 'A h:mm:ss वाजता', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm वाजता', + LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता' }, calendar : { - sameDay: '[heute um] LT [Uhr]', - sameElse: 'L', - nextDay: '[morgen um] LT [Uhr]', - nextWeek: 'dddd [um] LT [Uhr]', - lastDay: '[gestern um] LT [Uhr]', - lastWeek: '[letzten] dddd [um] LT [Uhr]' + sameDay : '[आज] LT', + nextDay : '[उद्या] LT', + nextWeek : 'dddd, LT', + lastDay : '[काल] LT', + lastWeek: '[मागील] dddd, LT', + sameElse : 'L' }, relativeTime : { - future : 'in %s', - past : 'vor %s', - s : 'ein paar Sekunden', - ss : '%d Sekunden', - m : processRelativeTime, - mm : '%d Minuten', - h : processRelativeTime, - hh : '%d Stunden', - d : processRelativeTime, - dd : processRelativeTime, - M : processRelativeTime, - MM : processRelativeTime, - y : processRelativeTime, - yy : processRelativeTime + future: '%sमध्ये', + past: '%sपूर्वी', + s: relativeTimeMr, + ss: relativeTimeMr, + m: relativeTimeMr, + mm: relativeTimeMr, + h: relativeTimeMr, + hh: relativeTimeMr, + d: relativeTimeMr, + dd: relativeTimeMr, + M: relativeTimeMr, + MM: relativeTimeMr, + y: relativeTimeMr, + yy: relativeTimeMr + }, + preparse: function (string) { + return string.replace(/[१२३४५६७८९०]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'रात्री') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'सकाळी') { + return hour; + } else if (meridiem === 'दुपारी') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'सायंकाळी') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'रात्री'; + } else if (hour < 10) { + return 'सकाळी'; + } else if (hour < 17) { + return 'दुपारी'; + } else if (hour < 20) { + return 'सायंकाळी'; + } else { + return 'रात्री'; + } }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 6th is the first week of the year. } }); - return de; + return mr; }))); /***/ }), -/* 64 */ +/* 92 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - function processRelativeTime(number, withoutSuffix, key, isFuture) { - var format = { - 'm': ['eine Minute', 'einer Minute'], - 'h': ['eine Stunde', 'einer Stunde'], - 'd': ['ein Tag', 'einem Tag'], - 'dd': [number + ' Tage', number + ' Tagen'], - 'M': ['ein Monat', 'einem Monat'], - 'MM': [number + ' Monate', number + ' Monaten'], - 'y': ['ein Jahr', 'einem Jahr'], - 'yy': [number + ' Jahre', number + ' Jahren'] - }; - return withoutSuffix ? format[key][0] : format[key][1]; - } - - var deAt = moment.defineLocale('de-at', { - months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), - monthsShort : 'Jän._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'), - monthsParseExact : true, - weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), - weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), - weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), - weekdaysParseExact : true, + var ms = moment.defineLocale('ms', { + months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'), + monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), + weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), + weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), + weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), longDateFormat : { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY HH:mm', - LLLL : 'dddd, D. MMMM YYYY HH:mm' + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /pagi|tengahari|petang|malam/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'tengahari') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'petang' || meridiem === 'malam') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'tengahari'; + } else if (hours < 19) { + return 'petang'; + } else { + return 'malam'; + } }, calendar : { - sameDay: '[heute um] LT [Uhr]', - sameElse: 'L', - nextDay: '[morgen um] LT [Uhr]', - nextWeek: 'dddd [um] LT [Uhr]', - lastDay: '[gestern um] LT [Uhr]', - lastWeek: '[letzten] dddd [um] LT [Uhr]' + sameDay : '[Hari ini pukul] LT', + nextDay : '[Esok pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kelmarin pukul] LT', + lastWeek : 'dddd [lepas pukul] LT', + sameElse : 'L' }, relativeTime : { - future : 'in %s', - past : 'vor %s', - s : 'ein paar Sekunden', - ss : '%d Sekunden', - m : processRelativeTime, - mm : '%d Minuten', - h : processRelativeTime, - hh : '%d Stunden', - d : processRelativeTime, - dd : processRelativeTime, - M : processRelativeTime, - MM : processRelativeTime, - y : processRelativeTime, - yy : processRelativeTime + future : 'dalam %s', + past : '%s yang lepas', + s : 'beberapa saat', + ss : '%d saat', + m : 'seminit', + mm : '%d minit', + h : 'sejam', + hh : '%d jam', + d : 'sehari', + dd : '%d hari', + M : 'sebulan', + MM : '%d bulan', + y : 'setahun', + yy : '%d tahun' }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + doy : 7 // The week that contains Jan 7th is the first week of the year. } }); - return deAt; + return ms; }))); /***/ }), -/* 65 */ +/* 93 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - function processRelativeTime(number, withoutSuffix, key, isFuture) { - var format = { - 'm': ['eine Minute', 'einer Minute'], - 'h': ['eine Stunde', 'einer Stunde'], - 'd': ['ein Tag', 'einem Tag'], - 'dd': [number + ' Tage', number + ' Tagen'], - 'M': ['ein Monat', 'einem Monat'], - 'MM': [number + ' Monate', number + ' Monaten'], - 'y': ['ein Jahr', 'einem Jahr'], - 'yy': [number + ' Jahre', number + ' Jahren'] - }; - return withoutSuffix ? format[key][0] : format[key][1]; - } - - var deCh = moment.defineLocale('de-ch', { - months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), - monthsShort : 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'), - monthsParseExact : true, - weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), - weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), - weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), - weekdaysParseExact : true, + var msMy = moment.defineLocale('ms-my', { + months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'), + monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), + weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), + weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), + weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), longDateFormat : { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY HH:mm', - LLLL : 'dddd, D. MMMM YYYY HH:mm' + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /pagi|tengahari|petang|malam/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'tengahari') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'petang' || meridiem === 'malam') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'tengahari'; + } else if (hours < 19) { + return 'petang'; + } else { + return 'malam'; + } }, calendar : { - sameDay: '[heute um] LT [Uhr]', - sameElse: 'L', - nextDay: '[morgen um] LT [Uhr]', - nextWeek: 'dddd [um] LT [Uhr]', - lastDay: '[gestern um] LT [Uhr]', - lastWeek: '[letzten] dddd [um] LT [Uhr]' + sameDay : '[Hari ini pukul] LT', + nextDay : '[Esok pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kelmarin pukul] LT', + lastWeek : 'dddd [lepas pukul] LT', + sameElse : 'L' }, relativeTime : { - future : 'in %s', - past : 'vor %s', - s : 'ein paar Sekunden', - ss : '%d Sekunden', - m : processRelativeTime, - mm : '%d Minuten', - h : processRelativeTime, - hh : '%d Stunden', - d : processRelativeTime, - dd : processRelativeTime, - M : processRelativeTime, - MM : processRelativeTime, - y : processRelativeTime, - yy : processRelativeTime + future : 'dalam %s', + past : '%s yang lepas', + s : 'beberapa saat', + ss : '%d saat', + m : 'seminit', + mm : '%d minit', + h : 'sejam', + hh : '%d jam', + d : 'sehari', + dd : '%d hari', + M : 'sebulan', + MM : '%d bulan', + y : 'setahun', + yy : '%d tahun' }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + doy : 7 // The week that contains Jan 7th is the first week of the year. } }); - return deCh; + return msMy; }))); /***/ }), -/* 66 */ +/* 94 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var months = [ - 'ޖެނުއަރީ', - 'ފެބްރުއަރީ', - 'މާރިޗު', - 'އޭޕްރީލު', - 'މޭ', - 'ޖޫން', - 'ޖުލައި', - 'އޯގަސްޓު', - 'ސެޕްޓެމްބަރު', - 'އޮކްޓޯބަރު', - 'ނޮވެމްބަރު', - 'ޑިސެމްބަރު' - ], weekdays = [ - 'އާދިއްތަ', - 'ހޯމަ', - 'އަންގާރަ', - 'ބުދަ', - 'ބުރާސްފަތި', - 'ހުކުރު', - 'ހޮނިހިރު' - ]; - - var dv = moment.defineLocale('dv', { - months : months, - monthsShort : months, - weekdays : weekdays, - weekdaysShort : weekdays, - weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'), + var mt = moment.defineLocale('mt', { + months : 'Jannar_Frar_Marzu_April_Mejju_Ġunju_Lulju_Awwissu_Settembru_Ottubru_Novembru_Diċembru'.split('_'), + monthsShort : 'Jan_Fra_Mar_Apr_Mej_Ġun_Lul_Aww_Set_Ott_Nov_Diċ'.split('_'), + weekdays : 'Il-Ħadd_It-Tnejn_It-Tlieta_L-Erbgħa_Il-Ħamis_Il-Ġimgħa_Is-Sibt'.split('_'), + weekdaysShort : 'Ħad_Tne_Tli_Erb_Ħam_Ġim_Sib'.split('_'), + weekdaysMin : 'Ħa_Tn_Tl_Er_Ħa_Ġi_Si'.split('_'), longDateFormat : { - LT : 'HH:mm', LTS : 'HH:mm:ss', - L : 'D/M/YYYY', + L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - meridiemParse: /މކ|މފ/, - isPM : function (input) { - return 'މފ' === input; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'މކ'; - } else { - return 'މފ'; - } + LLLL : 'dddd, D MMMM YYYY HH:mm' }, calendar : { - sameDay : '[މިއަދު] LT', - nextDay : '[މާދަމާ] LT', - nextWeek : 'dddd LT', - lastDay : '[އިއްޔެ] LT', - lastWeek : '[ފާއިތުވި] dddd LT', + sameDay : '[Illum fil-]LT', + nextDay : '[Għada fil-]LT', + nextWeek : 'dddd [fil-]LT', + lastDay : '[Il-bieraħ fil-]LT', + lastWeek : 'dddd [li għadda] [fil-]LT', sameElse : 'L' }, relativeTime : { - future : 'ތެރޭގައި %s', - past : 'ކުރިން %s', - s : 'ސިކުންތުކޮޅެއް', - ss : 'd% ސިކުންތު', - m : 'މިނިޓެއް', - mm : 'މިނިޓު %d', - h : 'ގަޑިއިރެއް', - hh : 'ގަޑިއިރު %d', - d : 'ދުވަހެއް', - dd : 'ދުވަސް %d', - M : 'މަހެއް', - MM : 'މަސް %d', - y : 'އަހަރެއް', - yy : 'އަހަރު %d' - }, - preparse: function (string) { - return string.replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/,/g, '،'); + future : 'f’ %s', + past : '%s ilu', + s : 'ftit sekondi', + ss : '%d sekondi', + m : 'minuta', + mm : '%d minuti', + h : 'siegħa', + hh : '%d siegħat', + d : 'ġurnata', + dd : '%d ġranet', + M : 'xahar', + MM : '%d xhur', + y : 'sena', + yy : '%d sni' }, + dayOfMonthOrdinalParse : /\d{1,2}º/, + ordinal: '%dº', week : { - dow : 7, // Sunday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return dv; + return mt; }))); /***/ }), -/* 67 */ +/* 95 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - function isFunction(input) { - return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; - } + var symbolMap = { + '1': '၁', + '2': '၂', + '3': '၃', + '4': '၄', + '5': '၅', + '6': '၆', + '7': '၇', + '8': '၈', + '9': '၉', + '0': '၀' + }, numberMap = { + '၁': '1', + '၂': '2', + '၃': '3', + '၄': '4', + '၅': '5', + '၆': '6', + '၇': '7', + '၈': '8', + '၉': '9', + '၀': '0' + }; - var el = moment.defineLocale('el', { - monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'), - monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'), - months : function (momentToFormat, format) { - if (!momentToFormat) { - return this._monthsNominativeEl; - } else if (typeof format === 'string' && /D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM' - return this._monthsGenitiveEl[momentToFormat.month()]; - } else { - return this._monthsNominativeEl[momentToFormat.month()]; - } + var my = moment.defineLocale('my', { + months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'), + monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'), + weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'), + weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), + weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), + + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm' }, - monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'), - weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'), - weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'), - weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'), - meridiem : function (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'μμ' : 'ΜΜ'; - } else { - return isLower ? 'πμ' : 'ΠΜ'; - } + calendar: { + sameDay: '[ယနေ.] LT [မှာ]', + nextDay: '[မနက်ဖြန်] LT [မှာ]', + nextWeek: 'dddd LT [မှာ]', + lastDay: '[မနေ.က] LT [မှာ]', + lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]', + sameElse: 'L' }, - isPM : function (input) { - return ((input + '').toLowerCase()[0] === 'μ'); + relativeTime: { + future: 'လာမည့် %s မှာ', + past: 'လွန်ခဲ့သော %s က', + s: 'စက္ကန်.အနည်းငယ်', + ss : '%d စက္ကန့်', + m: 'တစ်မိနစ်', + mm: '%d မိနစ်', + h: 'တစ်နာရီ', + hh: '%d နာရီ', + d: 'တစ်ရက်', + dd: '%d ရက်', + M: 'တစ်လ', + MM: '%d လ', + y: 'တစ်နှစ်', + yy: '%d နှစ်' }, - meridiemParse : /[ΠΜ]\.?Μ?\.?/i, - longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY h:mm A', - LLLL : 'dddd, D MMMM YYYY h:mm A' + preparse: function (string) { + return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) { + return numberMap[match]; + }); }, - calendarEl : { - sameDay : '[Σήμερα {}] LT', - nextDay : '[Αύριο {}] LT', - nextWeek : 'dddd [{}] LT', - lastDay : '[Χθες {}] LT', - lastWeek : function () { - switch (this.day()) { - case 6: - return '[το προηγούμενο] dddd [{}] LT'; - default: - return '[την προηγούμενη] dddd [{}] LT'; - } - }, - sameElse : 'L' + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); }, - calendar : function (key, mom) { - var output = this._calendarEl[key], - hours = mom && mom.hours(); - if (isFunction(output)) { - output = output.apply(mom); - } - return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις')); + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + return my; + +}))); + + +/***/ }), +/* 96 */ +/***/ (function(module, exports, __webpack_require__) { + +//! moment.js locale configuration + +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; + + + var nb = moment.defineLocale('nb', { + months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), + monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'), + monthsParseExact : true, + weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), + weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'), + weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY [kl.] HH:mm', + LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm' + }, + calendar : { + sameDay: '[i dag kl.] LT', + nextDay: '[i morgen kl.] LT', + nextWeek: 'dddd [kl.] LT', + lastDay: '[i går kl.] LT', + lastWeek: '[forrige] dddd [kl.] LT', + sameElse: 'L' }, relativeTime : { - future : 'σε %s', - past : '%s πριν', - s : 'λίγα δευτερόλεπτα', - ss : '%d δευτερόλεπτα', - m : 'ένα λεπτό', - mm : '%d λεπτά', - h : 'μία ώρα', - hh : '%d ώρες', - d : 'μία μέρα', - dd : '%d μέρες', - M : 'ένας μήνας', - MM : '%d μήνες', - y : 'ένας χρόνος', - yy : '%d χρόνια' + future : 'om %s', + past : '%s siden', + s : 'noen sekunder', + ss : '%d sekunder', + m : 'ett minutt', + mm : '%d minutter', + h : 'en time', + hh : '%d timer', + d : 'en dag', + dd : '%d dager', + M : 'en måned', + MM : '%d måneder', + y : 'ett år', + yy : '%d år' }, - dayOfMonthOrdinalParse: /\d{1,2}η/, - ordinal: '%dη', + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4st is the first week of the year. + doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return el; + return nb; }))); /***/ }), -/* 68 */ +/* 97 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var enSG = moment.defineLocale('en-SG', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + var symbolMap = { + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + '0': '०' + }, + numberMap = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0' + }; + + var ne = moment.defineLocale('ne', { + months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'), + monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'), + monthsParseExact : true, + weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'), + weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'), + weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'), + weekdaysParseExact : true, longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', + LT : 'Aको h:mm बजे', + LTS : 'Aको h:mm:ss बजे', L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' + LLL : 'D MMMM YYYY, Aको h:mm बजे', + LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे' + }, + preparse: function (string) { + return string.replace(/[१२३४५६७८९०]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + meridiemParse: /राति|बिहान|दिउँसो|साँझ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'राति') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'बिहान') { + return hour; + } else if (meridiem === 'दिउँसो') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'साँझ') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 3) { + return 'राति'; + } else if (hour < 12) { + return 'बिहान'; + } else if (hour < 16) { + return 'दिउँसो'; + } else if (hour < 20) { + return 'साँझ'; + } else { + return 'राति'; + } }, calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', + sameDay : '[आज] LT', + nextDay : '[भोलि] LT', + nextWeek : '[आउँदो] dddd[,] LT', + lastDay : '[हिजो] LT', + lastWeek : '[गएको] dddd[,] LT', sameElse : 'L' }, relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - ss : '%d seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }, - dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; + future : '%sमा', + past : '%s अगाडि', + s : 'केही क्षण', + ss : '%d सेकेण्ड', + m : 'एक मिनेट', + mm : '%d मिनेट', + h : 'एक घण्टा', + hh : '%d घण्टा', + d : 'एक दिन', + dd : '%d दिन', + M : 'एक महिना', + MM : '%d महिना', + y : 'एक बर्ष', + yy : '%d बर्ष' }, week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 6th is the first week of the year. } }); - return enSG; + return ne; }))); /***/ }), -/* 69 */ +/* 98 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var enAu = moment.defineLocale('en-au', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'), + monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_'); + + var monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i]; + var monthsRegex = /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i; + + var nl = moment.defineLocale('nl', { + months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortWithDots; + } else if (/-MMM-/.test(format)) { + return monthsShortWithoutDots[m.month()]; + } else { + return monthsShortWithDots[m.month()]; + } + }, + + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + monthsStrictRegex: /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i, + monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i, + + monthsParse : monthsParse, + longMonthsParse : monthsParse, + shortMonthsParse : monthsParse, + + weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'), + weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'), + weekdaysMin : 'zo_ma_di_wo_do_vr_za'.split('_'), + weekdaysParseExact : true, longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'DD/MM/YYYY', + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY h:mm A', - LLLL : 'dddd, D MMMM YYYY h:mm A' + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' }, calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' + sameDay: '[vandaag om] LT', + nextDay: '[morgen om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[gisteren om] LT', + lastWeek: '[afgelopen] dddd [om] LT', + sameElse: 'L' }, relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - ss : '%d seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' + future : 'over %s', + past : '%s geleden', + s : 'een paar seconden', + ss : '%d seconden', + m : 'één minuut', + mm : '%d minuten', + h : 'één uur', + hh : '%d uur', + d : 'één dag', + dd : '%d dagen', + M : 'één maand', + MM : '%d maanden', + y : 'één jaar', + yy : '%d jaar' }, - dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); }, week : { dow : 1, // Monday is the first day of the week. @@ -12543,135 +14129,89 @@ webpackContext.id = 41; } }); - return enAu; + return nl; }))); /***/ }), -/* 70 */ +/* 99 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var enCa = moment.defineLocale('en-ca', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), - longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'YYYY-MM-DD', - LL : 'MMMM D, YYYY', - LLL : 'MMMM D, YYYY h:mm A', - LLLL : 'dddd, MMMM D, YYYY h:mm A' - }, - calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - ss : '%d seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }, - dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - } - }); - - return enCa; - -}))); - + var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'), + monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_'); -/***/ }), -/* 71 */ -/***/ (function(module, exports, __webpack_require__) { + var monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i]; + var monthsRegex = /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i; -//! moment.js locale configuration + var nlBe = moment.defineLocale('nl-be', { + months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'), + monthsShort : function (m, format) { + if (!m) { + return monthsShortWithDots; + } else if (/-MMM-/.test(format)) { + return monthsShortWithoutDots[m.month()]; + } else { + return monthsShortWithDots[m.month()]; + } + }, -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; + monthsRegex: monthsRegex, + monthsShortRegex: monthsRegex, + monthsStrictRegex: /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i, + monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i, + monthsParse : monthsParse, + longMonthsParse : monthsParse, + shortMonthsParse : monthsParse, - var enGb = moment.defineLocale('en-gb', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'), + weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'), + weekdaysMin : 'zo_ma_di_wo_do_vr_za'.split('_'), + weekdaysParseExact : true, longDateFormat : { LT : 'HH:mm', LTS : 'HH:mm:ss', L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' + LLLL : 'dddd D MMMM YYYY HH:mm' }, calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' + sameDay: '[vandaag om] LT', + nextDay: '[morgen om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[gisteren om] LT', + lastWeek: '[afgelopen] dddd [om] LT', + sameElse: 'L' }, relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - ss : '%d seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' + future : 'over %s', + past : '%s geleden', + s : 'een paar seconden', + ss : '%d seconden', + m : 'één minuut', + mm : '%d minuten', + h : 'één uur', + hh : '%d uur', + d : 'één dag', + dd : '%d dagen', + M : 'één maand', + MM : '%d maanden', + y : 'één jaar', + yy : '%d jaar' }, - dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); }, week : { dow : 1, // Monday is the first day of the week. @@ -12679,373 +14219,386 @@ webpackContext.id = 41; } }); - return enGb; + return nlBe; }))); /***/ }), -/* 72 */ +/* 100 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var enIe = moment.defineLocale('en-ie', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + var nn = moment.defineLocale('nn', { + months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), + monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), + weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'), + weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'), + weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'), longDateFormat : { LT : 'HH:mm', LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY [kl.] H:mm', + LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm' }, calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' + sameDay: '[I dag klokka] LT', + nextDay: '[I morgon klokka] LT', + nextWeek: 'dddd [klokka] LT', + lastDay: '[I går klokka] LT', + lastWeek: '[Føregåande] dddd [klokka] LT', + sameElse: 'L' }, relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - ss : '%d seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }, - dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; + future : 'om %s', + past : '%s sidan', + s : 'nokre sekund', + ss : '%d sekund', + m : 'eit minutt', + mm : '%d minutt', + h : 'ein time', + hh : '%d timar', + d : 'ein dag', + dd : '%d dagar', + M : 'ein månad', + MM : '%d månader', + y : 'eit år', + yy : '%d år' }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return enIe; + return nn; }))); /***/ }), -/* 73 */ +/* 101 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var enIl = moment.defineLocale('en-il', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + var symbolMap = { + '1': '੧', + '2': '੨', + '3': '੩', + '4': '੪', + '5': '੫', + '6': '੬', + '7': '੭', + '8': '੮', + '9': '੯', + '0': '੦' + }, + numberMap = { + '੧': '1', + '੨': '2', + '੩': '3', + '੪': '4', + '੫': '5', + '੬': '6', + '੭': '7', + '੮': '8', + '੯': '9', + '੦': '0' + }; + + var paIn = moment.defineLocale('pa-in', { + // There are months name as per Nanakshahi Calendar but they are not used as rigidly in modern Punjabi. + months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'), + monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'), + weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'), + weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'), + weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'), longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', + LT : 'A h:mm ਵਜੇ', + LTS : 'A h:mm:ss ਵਜੇ', L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' + LLL : 'D MMMM YYYY, A h:mm ਵਜੇ', + LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ' }, calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', + sameDay : '[ਅਜ] LT', + nextDay : '[ਕਲ] LT', + nextWeek : '[ਅਗਲਾ] dddd, LT', + lastDay : '[ਕਲ] LT', + lastWeek : '[ਪਿਛਲੇ] dddd, LT', sameElse : 'L' }, relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' + future : '%s ਵਿੱਚ', + past : '%s ਪਿਛਲੇ', + s : 'ਕੁਝ ਸਕਿੰਟ', + ss : '%d ਸਕਿੰਟ', + m : 'ਇਕ ਮਿੰਟ', + mm : '%d ਮਿੰਟ', + h : 'ਇੱਕ ਘੰਟਾ', + hh : '%d ਘੰਟੇ', + d : 'ਇੱਕ ਦਿਨ', + dd : '%d ਦਿਨ', + M : 'ਇੱਕ ਮਹੀਨਾ', + MM : '%d ਮਹੀਨੇ', + y : 'ਇੱਕ ਸਾਲ', + yy : '%d ਸਾਲ' }, - dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; + preparse: function (string) { + return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + // Punjabi notation for meridiems are quite fuzzy in practice. While there exists + // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi. + meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'ਰਾਤ') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'ਸਵੇਰ') { + return hour; + } else if (meridiem === 'ਦੁਪਹਿਰ') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'ਸ਼ਾਮ') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ਰਾਤ'; + } else if (hour < 10) { + return 'ਸਵੇਰ'; + } else if (hour < 17) { + return 'ਦੁਪਹਿਰ'; + } else if (hour < 20) { + return 'ਸ਼ਾਮ'; + } else { + return 'ਰਾਤ'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 6th is the first week of the year. } }); - return enIl; + return paIn; }))); /***/ }), -/* 74 */ +/* 102 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var enNz = moment.defineLocale('en-nz', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'), + monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_'); + function plural(n) { + return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1); + } + function translate(number, withoutSuffix, key) { + var result = number + ' '; + switch (key) { + case 'ss': + return result + (plural(number) ? 'sekundy' : 'sekund'); + case 'm': + return withoutSuffix ? 'minuta' : 'minutę'; + case 'mm': + return result + (plural(number) ? 'minuty' : 'minut'); + case 'h': + return withoutSuffix ? 'godzina' : 'godzinę'; + case 'hh': + return result + (plural(number) ? 'godziny' : 'godzin'); + case 'MM': + return result + (plural(number) ? 'miesiące' : 'miesięcy'); + case 'yy': + return result + (plural(number) ? 'lata' : 'lat'); + } + } + + var pl = moment.defineLocale('pl', { + months : function (momentToFormat, format) { + if (!momentToFormat) { + return monthsNominative; + } else if (format === '') { + // Hack: if format empty we know this is used to generate + // RegExp by moment. Give then back both valid forms of months + // in RegExp ready format. + return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')'; + } else if (/D MMMM/.test(format)) { + return monthsSubjective[momentToFormat.month()]; + } else { + return monthsNominative[momentToFormat.month()]; + } + }, + monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'), + weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'), + weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'), + weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'), longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'DD/MM/YYYY', + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY h:mm A', - LLLL : 'dddd, D MMMM YYYY h:mm A' + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' }, calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' + sameDay: '[Dziś o] LT', + nextDay: '[Jutro o] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[W niedzielę o] LT'; + + case 2: + return '[We wtorek o] LT'; + + case 3: + return '[W środę o] LT'; + + case 6: + return '[W sobotę o] LT'; + + default: + return '[W] dddd [o] LT'; + } + }, + lastDay: '[Wczoraj o] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[W zeszłą niedzielę o] LT'; + case 3: + return '[W zeszłą środę o] LT'; + case 6: + return '[W zeszłą sobotę o] LT'; + default: + return '[W zeszły] dddd [o] LT'; + } + }, + sameElse: 'L' }, relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - ss : '%d seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }, - dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; + future : 'za %s', + past : '%s temu', + s : 'kilka sekund', + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : '1 dzień', + dd : '%d dni', + M : 'miesiąc', + MM : translate, + y : 'rok', + yy : translate }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return enNz; + return pl; }))); /***/ }), -/* 75 */ +/* 103 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var eo = moment.defineLocale('eo', { - months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'), - monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'), - weekdays : 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'), - weekdaysShort : 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'), - weekdaysMin : 'di_lu_ma_me_ĵa_ve_sa'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY-MM-DD', - LL : 'D[-a de] MMMM, YYYY', - LLL : 'D[-a de] MMMM, YYYY HH:mm', - LLLL : 'dddd, [la] D[-a de] MMMM, YYYY HH:mm' - }, - meridiemParse: /[ap]\.t\.m/i, - isPM: function (input) { - return input.charAt(0).toLowerCase() === 'p'; - }, - meridiem : function (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'p.t.m.' : 'P.T.M.'; - } else { - return isLower ? 'a.t.m.' : 'A.T.M.'; - } - }, - calendar : { - sameDay : '[Hodiaŭ je] LT', - nextDay : '[Morgaŭ je] LT', - nextWeek : 'dddd [je] LT', - lastDay : '[Hieraŭ je] LT', - lastWeek : '[pasinta] dddd [je] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'post %s', - past : 'antaŭ %s', - s : 'sekundoj', - ss : '%d sekundoj', - m : 'minuto', - mm : '%d minutoj', - h : 'horo', - hh : '%d horoj', - d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo - dd : '%d tagoj', - M : 'monato', - MM : '%d monatoj', - y : 'jaro', - yy : '%d jaroj' - }, - dayOfMonthOrdinalParse: /\d{1,2}a/, - ordinal : '%da', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - return eo; - -}))); - - -/***/ }), -/* 76 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration - -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - - - var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), - monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); - - var monthsParse = [/^ene/i, /^feb/i, /^mar/i, /^abr/i, /^may/i, /^jun/i, /^jul/i, /^ago/i, /^sep/i, /^oct/i, /^nov/i, /^dic/i]; - var monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; - - var es = moment.defineLocale('es', { - months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), - monthsShort : function (m, format) { - if (!m) { - return monthsShortDot; - } else if (/-MMM-/.test(format)) { - return monthsShort[m.month()]; - } else { - return monthsShortDot[m.month()]; - } - }, - monthsRegex : monthsRegex, - monthsShortRegex : monthsRegex, - monthsStrictRegex : /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, - monthsShortStrictRegex : /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, - monthsParse : monthsParse, - longMonthsParse : monthsParse, - shortMonthsParse : monthsParse, - weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), - weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), - weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), + var pt = moment.defineLocale('pt', { + months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'), + monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'), + weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'), + weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), + weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'), weekdaysParseExact : true, longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', + LT : 'HH:mm', + LTS : 'HH:mm:ss', L : 'DD/MM/YYYY', LL : 'D [de] MMMM [de] YYYY', - LLL : 'D [de] MMMM [de] YYYY H:mm', - LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm' + LLL : 'D [de] MMMM [de] YYYY HH:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm' }, calendar : { - sameDay : function () { - return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextDay : function () { - return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextWeek : function () { - return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastDay : function () { - return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastWeek : function () { - return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + sameDay: '[Hoje às] LT', + nextDay: '[Amanhã às] LT', + nextWeek: 'dddd [às] LT', + lastDay: '[Ontem às] LT', + lastWeek: function () { + return (this.day() === 0 || this.day() === 6) ? + '[Último] dddd [às] LT' : // Saturday + Sunday + '[Última] dddd [às] LT'; // Monday - Friday }, - sameElse : 'L' + sameElse: 'L' }, relativeTime : { - future : 'en %s', - past : 'hace %s', - s : 'unos segundos', + future : 'em %s', + past : 'há %s', + s : 'segundos', ss : '%d segundos', - m : 'un minuto', + m : 'um minuto', mm : '%d minutos', - h : 'una hora', + h : 'uma hora', hh : '%d horas', - d : 'un día', - dd : '%d días', - M : 'un mes', + d : 'um dia', + dd : '%d dias', + M : 'um mês', MM : '%d meses', - y : 'un año', - yy : '%d años' + y : 'um ano', + yy : '%d anos' }, - dayOfMonthOrdinalParse : /\d{1,2}º/, + dayOfMonthOrdinalParse: /\d{1,2}º/, ordinal : '%dº', week : { dow : 1, // Monday is the first day of the week. @@ -13053,560 +14606,488 @@ webpackContext.id = 41; } }); - return es; + return pt; }))); /***/ }), -/* 77 */ +/* 104 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), - monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); - - var monthsParse = [/^ene/i, /^feb/i, /^mar/i, /^abr/i, /^may/i, /^jun/i, /^jul/i, /^ago/i, /^sep/i, /^oct/i, /^nov/i, /^dic/i]; - var monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; - - var esDo = moment.defineLocale('es-do', { - months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), - monthsShort : function (m, format) { - if (!m) { - return monthsShortDot; - } else if (/-MMM-/.test(format)) { - return monthsShort[m.month()]; - } else { - return monthsShortDot[m.month()]; - } - }, - monthsRegex: monthsRegex, - monthsShortRegex: monthsRegex, - monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, - monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, - monthsParse: monthsParse, - longMonthsParse: monthsParse, - shortMonthsParse: monthsParse, - weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), - weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), - weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), + var ptBr = moment.defineLocale('pt-br', { + months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'), + monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'), + weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'), + weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), + weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'), weekdaysParseExact : true, longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', + LT : 'HH:mm', + LTS : 'HH:mm:ss', L : 'DD/MM/YYYY', LL : 'D [de] MMMM [de] YYYY', - LLL : 'D [de] MMMM [de] YYYY h:mm A', - LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A' + LLL : 'D [de] MMMM [de] YYYY [às] HH:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm' }, calendar : { - sameDay : function () { - return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextDay : function () { - return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextWeek : function () { - return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastDay : function () { - return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastWeek : function () { - return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + sameDay: '[Hoje às] LT', + nextDay: '[Amanhã às] LT', + nextWeek: 'dddd [às] LT', + lastDay: '[Ontem às] LT', + lastWeek: function () { + return (this.day() === 0 || this.day() === 6) ? + '[Último] dddd [às] LT' : // Saturday + Sunday + '[Última] dddd [às] LT'; // Monday - Friday }, - sameElse : 'L' + sameElse: 'L' }, relativeTime : { - future : 'en %s', - past : 'hace %s', - s : 'unos segundos', + future : 'em %s', + past : 'há %s', + s : 'poucos segundos', ss : '%d segundos', - m : 'un minuto', + m : 'um minuto', mm : '%d minutos', - h : 'una hora', + h : 'uma hora', hh : '%d horas', - d : 'un día', - dd : '%d días', - M : 'un mes', + d : 'um dia', + dd : '%d dias', + M : 'um mês', MM : '%d meses', - y : 'un año', - yy : '%d años' + y : 'um ano', + yy : '%d anos' }, - dayOfMonthOrdinalParse : /\d{1,2}º/, - ordinal : '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } + dayOfMonthOrdinalParse: /\d{1,2}º/, + ordinal : '%dº' }); - return esDo; + return ptBr; }))); /***/ }), -/* 78 */ +/* 105 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), - monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); - - var monthsParse = [/^ene/i, /^feb/i, /^mar/i, /^abr/i, /^may/i, /^jun/i, /^jul/i, /^ago/i, /^sep/i, /^oct/i, /^nov/i, /^dic/i]; - var monthsRegex = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; + function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'ss': 'secunde', + 'mm': 'minute', + 'hh': 'ore', + 'dd': 'zile', + 'MM': 'luni', + 'yy': 'ani' + }, + separator = ' '; + if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) { + separator = ' de '; + } + return number + separator + format[key]; + } - var esUs = moment.defineLocale('es-us', { - months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), - monthsShort : function (m, format) { - if (!m) { - return monthsShortDot; - } else if (/-MMM-/.test(format)) { - return monthsShort[m.month()]; - } else { - return monthsShortDot[m.month()]; - } - }, - monthsRegex: monthsRegex, - monthsShortRegex: monthsRegex, - monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, - monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, - monthsParse: monthsParse, - longMonthsParse: monthsParse, - shortMonthsParse: monthsParse, - weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), - weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), - weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), - weekdaysParseExact : true, + var ro = moment.defineLocale('ro', { + months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'), + monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'), + monthsParseExact: true, + weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'), + weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'), + weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'), longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'MM/DD/YYYY', - LL : 'D [de] MMMM [de] YYYY', - LLL : 'D [de] MMMM [de] YYYY h:mm A', - LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A' + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd, D MMMM YYYY H:mm' }, calendar : { - sameDay : function () { - return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextDay : function () { - return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextWeek : function () { - return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastDay : function () { - return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastWeek : function () { - return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - sameElse : 'L' + sameDay: '[azi la] LT', + nextDay: '[mâine la] LT', + nextWeek: 'dddd [la] LT', + lastDay: '[ieri la] LT', + lastWeek: '[fosta] dddd [la] LT', + sameElse: 'L' }, relativeTime : { - future : 'en %s', - past : 'hace %s', - s : 'unos segundos', - ss : '%d segundos', - m : 'un minuto', - mm : '%d minutos', - h : 'una hora', - hh : '%d horas', - d : 'un día', - dd : '%d días', - M : 'un mes', - MM : '%d meses', - y : 'un año', - yy : '%d años' + future : 'peste %s', + past : '%s în urmă', + s : 'câteva secunde', + ss : relativeTimeWithPlural, + m : 'un minut', + mm : relativeTimeWithPlural, + h : 'o oră', + hh : relativeTimeWithPlural, + d : 'o zi', + dd : relativeTimeWithPlural, + M : 'o lună', + MM : relativeTimeWithPlural, + y : 'un an', + yy : relativeTimeWithPlural }, - dayOfMonthOrdinalParse : /\d{1,2}º/, - ordinal : '%dº', week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. } }); - return esUs; + return ro; }))); /***/ }), -/* 79 */ +/* 106 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - function processRelativeTime(number, withoutSuffix, key, isFuture) { + function plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); + } + function relativeTimeWithPlural(number, withoutSuffix, key) { var format = { - 's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'], - 'ss': [number + 'sekundi', number + 'sekundit'], - 'm' : ['ühe minuti', 'üks minut'], - 'mm': [number + ' minuti', number + ' minutit'], - 'h' : ['ühe tunni', 'tund aega', 'üks tund'], - 'hh': [number + ' tunni', number + ' tundi'], - 'd' : ['ühe päeva', 'üks päev'], - 'M' : ['kuu aja', 'kuu aega', 'üks kuu'], - 'MM': [number + ' kuu', number + ' kuud'], - 'y' : ['ühe aasta', 'aasta', 'üks aasta'], - 'yy': [number + ' aasta', number + ' aastat'] + 'ss': withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд', + 'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут', + 'hh': 'час_часа_часов', + 'dd': 'день_дня_дней', + 'MM': 'месяц_месяца_месяцев', + 'yy': 'год_года_лет' }; - if (withoutSuffix) { - return format[key][2] ? format[key][2] : format[key][1]; + if (key === 'm') { + return withoutSuffix ? 'минута' : 'минуту'; + } + else { + return number + ' ' + plural(format[key], +number); } - return isFuture ? format[key][0] : format[key][1]; } + var monthsParse = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i]; - var et = moment.defineLocale('et', { - months : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'), - monthsShort : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'), - weekdays : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'), - weekdaysShort : 'P_E_T_K_N_R_L'.split('_'), - weekdaysMin : 'P_E_T_K_N_R_L'.split('_'), - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY H:mm', - LLLL : 'dddd, D. MMMM YYYY H:mm' + // http://new.gramota.ru/spravka/rules/139-prop : § 103 + // Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637 + // CLDR data: http://www.unicode.org/cldr/charts/28/summary/ru.html#1753 + var ru = moment.defineLocale('ru', { + months : { + format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'), + standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_') }, - calendar : { - sameDay : '[Täna,] LT', - nextDay : '[Homme,] LT', - nextWeek : '[Järgmine] dddd LT', - lastDay : '[Eile,] LT', - lastWeek : '[Eelmine] dddd LT', - sameElse : 'L' + monthsShort : { + // по CLDR именно "июл." и "июн.", но какой смысл менять букву на точку ? + format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'), + standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_') }, - relativeTime : { - future : '%s pärast', - past : '%s tagasi', - s : processRelativeTime, - ss : processRelativeTime, - m : processRelativeTime, - mm : processRelativeTime, - h : processRelativeTime, - hh : processRelativeTime, - d : processRelativeTime, - dd : '%d päeva', - M : processRelativeTime, - MM : processRelativeTime, - y : processRelativeTime, - yy : processRelativeTime + weekdays : { + standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'), + format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'), + isFormat: /\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/ }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - return et; - -}))); - - -/***/ }), -/* 80 */ -/***/ (function(module, exports, __webpack_require__) { + weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'), + weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'), + monthsParse : monthsParse, + longMonthsParse : monthsParse, + shortMonthsParse : monthsParse, -//! moment.js locale configuration + // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки + monthsRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i, -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; + // копия предыдущего + monthsShortRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i, + // полные названия с падежами + monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i, - var eu = moment.defineLocale('eu', { - months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'), - monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'), - monthsParseExact : true, - weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'), - weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'), - weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'), - weekdaysParseExact : true, + // Выражение, которое соотвествует только сокращённым формам + monthsShortStrictRegex: /^(янв\.|февр?\.|мар[т.]|апр\.|ма[яй]|июн[ья.]|июл[ья.]|авг\.|сент?\.|окт\.|нояб?\.|дек\.)/i, longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY-MM-DD', - LL : 'YYYY[ko] MMMM[ren] D[a]', - LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm', - LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm', - l : 'YYYY-M-D', - ll : 'YYYY[ko] MMM D[a]', - lll : 'YYYY[ko] MMM D[a] HH:mm', - llll : 'ddd, YYYY[ko] MMM D[a] HH:mm' + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY г.', + LLL : 'D MMMM YYYY г., H:mm', + LLLL : 'dddd, D MMMM YYYY г., H:mm' }, calendar : { - sameDay : '[gaur] LT[etan]', - nextDay : '[bihar] LT[etan]', - nextWeek : 'dddd LT[etan]', - lastDay : '[atzo] LT[etan]', - lastWeek : '[aurreko] dddd LT[etan]', - sameElse : 'L' + sameDay: '[Сегодня, в] LT', + nextDay: '[Завтра, в] LT', + lastDay: '[Вчера, в] LT', + nextWeek: function (now) { + if (now.week() !== this.week()) { + switch (this.day()) { + case 0: + return '[В следующее] dddd, [в] LT'; + case 1: + case 2: + case 4: + return '[В следующий] dddd, [в] LT'; + case 3: + case 5: + case 6: + return '[В следующую] dddd, [в] LT'; + } + } else { + if (this.day() === 2) { + return '[Во] dddd, [в] LT'; + } else { + return '[В] dddd, [в] LT'; + } + } + }, + lastWeek: function (now) { + if (now.week() !== this.week()) { + switch (this.day()) { + case 0: + return '[В прошлое] dddd, [в] LT'; + case 1: + case 2: + case 4: + return '[В прошлый] dddd, [в] LT'; + case 3: + case 5: + case 6: + return '[В прошлую] dddd, [в] LT'; + } + } else { + if (this.day() === 2) { + return '[Во] dddd, [в] LT'; + } else { + return '[В] dddd, [в] LT'; + } + } + }, + sameElse: 'L' }, relativeTime : { - future : '%s barru', - past : 'duela %s', - s : 'segundo batzuk', - ss : '%d segundo', - m : 'minutu bat', - mm : '%d minutu', - h : 'ordu bat', - hh : '%d ordu', - d : 'egun bat', - dd : '%d egun', - M : 'hilabete bat', - MM : '%d hilabete', - y : 'urte bat', - yy : '%d urte' + future : 'через %s', + past : '%s назад', + s : 'несколько секунд', + ss : relativeTimeWithPlural, + m : relativeTimeWithPlural, + mm : relativeTimeWithPlural, + h : 'час', + hh : relativeTimeWithPlural, + d : 'день', + dd : relativeTimeWithPlural, + M : 'месяц', + MM : relativeTimeWithPlural, + y : 'год', + yy : relativeTimeWithPlural + }, + meridiemParse: /ночи|утра|дня|вечера/i, + isPM : function (input) { + return /^(дня|вечера)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ночи'; + } else if (hour < 12) { + return 'утра'; + } else if (hour < 17) { + return 'дня'; + } else { + return 'вечера'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(й|го|я)/, + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + return number + '-й'; + case 'D': + return number + '-го'; + case 'w': + case 'W': + return number + '-я'; + default: + return number; + } }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. + doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return eu; + return ru; }))); /***/ }), -/* 81 */ +/* 107 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var symbolMap = { - '1': '۱', - '2': '۲', - '3': '۳', - '4': '۴', - '5': '۵', - '6': '۶', - '7': '۷', - '8': '۸', - '9': '۹', - '0': '۰' - }, numberMap = { - '۱': '1', - '۲': '2', - '۳': '3', - '۴': '4', - '۵': '5', - '۶': '6', - '۷': '7', - '۸': '8', - '۹': '9', - '۰': '0' - }; + var months = [ + 'جنوري', + 'فيبروري', + 'مارچ', + 'اپريل', + 'مئي', + 'جون', + 'جولاءِ', + 'آگسٽ', + 'سيپٽمبر', + 'آڪٽوبر', + 'نومبر', + 'ڊسمبر' + ]; + var days = [ + 'آچر', + 'سومر', + 'اڱارو', + 'اربع', + 'خميس', + 'جمع', + 'ڇنڇر' + ]; - var fa = moment.defineLocale('fa', { - months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), - monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), - weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), - weekdaysShort : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), - weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'), - weekdaysParseExact : true, + var sd = moment.defineLocale('sd', { + months : months, + monthsShort : months, + weekdays : days, + weekdaysShort : days, + weekdaysMin : days, longDateFormat : { LT : 'HH:mm', LTS : 'HH:mm:ss', L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' + LLLL : 'dddd، D MMMM YYYY HH:mm' }, - meridiemParse: /قبل از ظهر|بعد از ظهر/, - isPM: function (input) { - return /بعد از ظهر/.test(input); + meridiemParse: /صبح|شام/, + isPM : function (input) { + return 'شام' === input; }, meridiem : function (hour, minute, isLower) { if (hour < 12) { - return 'قبل از ظهر'; - } else { - return 'بعد از ظهر'; + return 'صبح'; } + return 'شام'; }, calendar : { - sameDay : '[امروز ساعت] LT', - nextDay : '[فردا ساعت] LT', - nextWeek : 'dddd [ساعت] LT', - lastDay : '[دیروز ساعت] LT', - lastWeek : 'dddd [پیش] [ساعت] LT', + sameDay : '[اڄ] LT', + nextDay : '[سڀاڻي] LT', + nextWeek : 'dddd [اڳين هفتي تي] LT', + lastDay : '[ڪالهه] LT', + lastWeek : '[گزريل هفتي] dddd [تي] LT', sameElse : 'L' }, relativeTime : { - future : 'در %s', - past : '%s پیش', - s : 'چند ثانیه', - ss : 'ثانیه d%', - m : 'یک دقیقه', - mm : '%d دقیقه', - h : 'یک ساعت', - hh : '%d ساعت', - d : 'یک روز', - dd : '%d روز', - M : 'یک ماه', - MM : '%d ماه', - y : 'یک سال', + future : '%s پوء', + past : '%s اڳ', + s : 'چند سيڪنڊ', + ss : '%d سيڪنڊ', + m : 'هڪ منٽ', + mm : '%d منٽ', + h : 'هڪ ڪلاڪ', + hh : '%d ڪلاڪ', + d : 'هڪ ڏينهن', + dd : '%d ڏينهن', + M : 'هڪ مهينو', + MM : '%d مهينا', + y : 'هڪ سال', yy : '%d سال' }, preparse: function (string) { - return string.replace(/[۰-۹]/g, function (match) { - return numberMap[match]; - }).replace(/،/g, ','); + return string.replace(/،/g, ','); }, postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }).replace(/,/g, '،'); + return string.replace(/,/g, '،'); }, - dayOfMonthOrdinalParse: /\d{1,2}م/, - ordinal : '%dم', week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return fa; + return sd; }))); /***/ }), -/* 82 */ +/* 108 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '), - numbersFuture = [ - 'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden', - numbersPast[7], numbersPast[8], numbersPast[9] - ]; - function translate(number, withoutSuffix, key, isFuture) { - var result = ''; - switch (key) { - case 's': - return isFuture ? 'muutaman sekunnin' : 'muutama sekunti'; - case 'ss': - return isFuture ? 'sekunnin' : 'sekuntia'; - case 'm': - return isFuture ? 'minuutin' : 'minuutti'; - case 'mm': - result = isFuture ? 'minuutin' : 'minuuttia'; - break; - case 'h': - return isFuture ? 'tunnin' : 'tunti'; - case 'hh': - result = isFuture ? 'tunnin' : 'tuntia'; - break; - case 'd': - return isFuture ? 'päivän' : 'päivä'; - case 'dd': - result = isFuture ? 'päivän' : 'päivää'; - break; - case 'M': - return isFuture ? 'kuukauden' : 'kuukausi'; - case 'MM': - result = isFuture ? 'kuukauden' : 'kuukautta'; - break; - case 'y': - return isFuture ? 'vuoden' : 'vuosi'; - case 'yy': - result = isFuture ? 'vuoden' : 'vuotta'; - break; - } - result = verbalNumber(number, isFuture) + ' ' + result; - return result; - } - function verbalNumber(number, isFuture) { - return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number; - } - - var fi = moment.defineLocale('fi', { - months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'), - monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'), - weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'), - weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'), - weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'), + var se = moment.defineLocale('se', { + months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'), + monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'), + weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'), + weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'), + weekdaysMin : 's_v_m_g_d_b_L'.split('_'), longDateFormat : { - LT : 'HH.mm', - LTS : 'HH.mm.ss', + LT : 'HH:mm', + LTS : 'HH:mm:ss', L : 'DD.MM.YYYY', - LL : 'Do MMMM[ta] YYYY', - LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm', - LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm', - l : 'D.M.YYYY', - ll : 'Do MMM YYYY', - lll : 'Do MMM YYYY, [klo] HH.mm', - llll : 'ddd, Do MMM YYYY, [klo] HH.mm' + LL : 'MMMM D. [b.] YYYY', + LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm', + LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm' }, calendar : { - sameDay : '[tänään] [klo] LT', - nextDay : '[huomenna] [klo] LT', - nextWeek : 'dddd [klo] LT', - lastDay : '[eilen] [klo] LT', - lastWeek : '[viime] dddd[na] [klo] LT', - sameElse : 'L' + sameDay: '[otne ti] LT', + nextDay: '[ihttin ti] LT', + nextWeek: 'dddd [ti] LT', + lastDay: '[ikte ti] LT', + lastWeek: '[ovddit] dddd [ti] LT', + sameElse: 'L' }, relativeTime : { - future : '%s päästä', - past : '%s sitten', - s : translate, - ss : translate, - m : translate, - mm : translate, - h : translate, - hh : translate, - d : translate, - dd : translate, - M : translate, - MM : translate, - y : translate, - yy : translate + future : '%s geažes', + past : 'maŋit %s', + s : 'moadde sekunddat', + ss: '%d sekunddat', + m : 'okta minuhta', + mm : '%d minuhtat', + h : 'okta diimmu', + hh : '%d diimmut', + d : 'okta beaivi', + dd : '%d beaivvit', + M : 'okta mánnu', + MM : '%d mánut', + y : 'okta jahki', + yy : '%d jagit' }, dayOfMonthOrdinalParse: /\d{1,2}\./, ordinal : '%d.', @@ -13616,1102 +15097,1155 @@ webpackContext.id = 41; } }); - return fi; + return se; }))); /***/ }), -/* 83 */ +/* 109 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var fo = moment.defineLocale('fo', { - months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'), - monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), - weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'), - weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'), - weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'), + /*jshint -W100*/ + var si = moment.defineLocale('si', { + months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'), + monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'), + weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'), + weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'), + weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'), + weekdaysParseExact : true, longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D. MMMM, YYYY HH:mm' + LT : 'a h:mm', + LTS : 'a h:mm:ss', + L : 'YYYY/MM/DD', + LL : 'YYYY MMMM D', + LLL : 'YYYY MMMM D, a h:mm', + LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss' }, calendar : { - sameDay : '[Í dag kl.] LT', - nextDay : '[Í morgin kl.] LT', - nextWeek : 'dddd [kl.] LT', - lastDay : '[Í gjár kl.] LT', - lastWeek : '[síðstu] dddd [kl] LT', + sameDay : '[අද] LT[ට]', + nextDay : '[හෙට] LT[ට]', + nextWeek : 'dddd LT[ට]', + lastDay : '[ඊයේ] LT[ට]', + lastWeek : '[පසුගිය] dddd LT[ට]', sameElse : 'L' }, relativeTime : { - future : 'um %s', - past : '%s síðani', - s : 'fá sekund', - ss : '%d sekundir', - m : 'ein minuttur', - mm : '%d minuttir', - h : 'ein tími', - hh : '%d tímar', - d : 'ein dagur', - dd : '%d dagar', - M : 'ein mánaður', - MM : '%d mánaðir', - y : 'eitt ár', - yy : '%d ár' + future : '%sකින්', + past : '%sකට පෙර', + s : 'තත්පර කිහිපය', + ss : 'තත්පර %d', + m : 'මිනිත්තුව', + mm : 'මිනිත්තු %d', + h : 'පැය', + hh : 'පැය %d', + d : 'දිනය', + dd : 'දින %d', + M : 'මාසය', + MM : 'මාස %d', + y : 'වසර', + yy : 'වසර %d' }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + dayOfMonthOrdinalParse: /\d{1,2} වැනි/, + ordinal : function (number) { + return number + ' වැනි'; + }, + meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./, + isPM : function (input) { + return input === 'ප.ව.' || input === 'පස් වරු'; + }, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'ප.ව.' : 'පස් වරු'; + } else { + return isLower ? 'පෙ.ව.' : 'පෙර වරු'; + } } }); - return fo; + return si; }))); /***/ }), -/* 84 */ +/* 110 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var fr = moment.defineLocale('fr', { - months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), - monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), - monthsParseExact : true, - weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), - weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), - weekdaysMin : 'di_lu_ma_me_je_ve_sa'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Aujourd’hui à] LT', - nextDay : '[Demain à] LT', - nextWeek : 'dddd [à] LT', - lastDay : '[Hier à] LT', - lastWeek : 'dddd [dernier à] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'dans %s', - past : 'il y a %s', - s : 'quelques secondes', - ss : '%d secondes', - m : 'une minute', - mm : '%d minutes', - h : 'une heure', - hh : '%d heures', - d : 'un jour', - dd : '%d jours', - M : 'un mois', - MM : '%d mois', - y : 'un an', - yy : '%d ans' - }, - dayOfMonthOrdinalParse: /\d{1,2}(er|)/, - ordinal : function (number, period) { - switch (period) { - // TODO: Return 'e' when day of month > 1. Move this case inside - // block for masculine words below. - // See https://github.com/moment/moment/issues/3375 - case 'D': - return number + (number === 1 ? 'er' : ''); - - // Words with masculine grammatical gender: mois, trimestre, jour - default: - case 'M': - case 'Q': - case 'DDD': - case 'd': - return number + (number === 1 ? 'er' : 'e'); - - // Words with feminine grammatical gender: semaine - case 'w': - case 'W': - return number + (number === 1 ? 're' : 'e'); - } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + var months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'), + monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_'); + function plural(n) { + return (n > 1) && (n < 5); + } + function translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': // a few seconds / in a few seconds / a few seconds ago + return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami'; + case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'sekundy' : 'sekúnd'); + } else { + return result + 'sekundami'; + } + break; + case 'm': // a minute / in a minute / a minute ago + return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou'); + case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'minúty' : 'minút'); + } else { + return result + 'minútami'; + } + break; + case 'h': // an hour / in an hour / an hour ago + return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); + case 'hh': // 9 hours / in 9 hours / 9 hours ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'hodiny' : 'hodín'); + } else { + return result + 'hodinami'; + } + break; + case 'd': // a day / in a day / a day ago + return (withoutSuffix || isFuture) ? 'deň' : 'dňom'; + case 'dd': // 9 days / in 9 days / 9 days ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'dni' : 'dní'); + } else { + return result + 'dňami'; + } + break; + case 'M': // a month / in a month / a month ago + return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom'; + case 'MM': // 9 months / in 9 months / 9 months ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'mesiace' : 'mesiacov'); + } else { + return result + 'mesiacmi'; + } + break; + case 'y': // a year / in a year / a year ago + return (withoutSuffix || isFuture) ? 'rok' : 'rokom'; + case 'yy': // 9 years / in 9 years / 9 years ago + if (withoutSuffix || isFuture) { + return result + (plural(number) ? 'roky' : 'rokov'); + } else { + return result + 'rokmi'; + } + break; } - }); - - return fr; - -}))); - - -/***/ }), -/* 85 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration - -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - + } - var frCa = moment.defineLocale('fr-ca', { - months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), - monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), - monthsParseExact : true, - weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), - weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), - weekdaysMin : 'di_lu_ma_me_je_ve_sa'.split('_'), - weekdaysParseExact : true, + var sk = moment.defineLocale('sk', { + months : months, + monthsShort : monthsShort, + weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'), + weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'), + weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'), longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY-MM-DD', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' + LT: 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd D. MMMM YYYY H:mm' }, calendar : { - sameDay : '[Aujourd’hui à] LT', - nextDay : '[Demain à] LT', - nextWeek : 'dddd [à] LT', - lastDay : '[Hier à] LT', - lastWeek : 'dddd [dernier à] LT', - sameElse : 'L' + sameDay: '[dnes o] LT', + nextDay: '[zajtra o] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[v nedeľu o] LT'; + case 1: + case 2: + return '[v] dddd [o] LT'; + case 3: + return '[v stredu o] LT'; + case 4: + return '[vo štvrtok o] LT'; + case 5: + return '[v piatok o] LT'; + case 6: + return '[v sobotu o] LT'; + } + }, + lastDay: '[včera o] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[minulú nedeľu o] LT'; + case 1: + case 2: + return '[minulý] dddd [o] LT'; + case 3: + return '[minulú stredu o] LT'; + case 4: + case 5: + return '[minulý] dddd [o] LT'; + case 6: + return '[minulú sobotu o] LT'; + } + }, + sameElse: 'L' }, relativeTime : { - future : 'dans %s', - past : 'il y a %s', - s : 'quelques secondes', - ss : '%d secondes', - m : 'une minute', - mm : '%d minutes', - h : 'une heure', - hh : '%d heures', - d : 'un jour', - dd : '%d jours', - M : 'un mois', - MM : '%d mois', - y : 'un an', - yy : '%d ans' + future : 'za %s', + past : 'pred %s', + s : translate, + ss : translate, + m : translate, + mm : translate, + h : translate, + hh : translate, + d : translate, + dd : translate, + M : translate, + MM : translate, + y : translate, + yy : translate }, - dayOfMonthOrdinalParse: /\d{1,2}(er|e)/, - ordinal : function (number, period) { - switch (period) { - // Words with masculine grammatical gender: mois, trimestre, jour - default: - case 'M': - case 'Q': - case 'D': - case 'DDD': - case 'd': - return number + (number === 1 ? 'er' : 'e'); - - // Words with feminine grammatical gender: semaine - case 'w': - case 'W': - return number + (number === 1 ? 're' : 'e'); - } + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return frCa; + return sk; }))); /***/ }), -/* 86 */ +/* 111 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var frCh = moment.defineLocale('fr-ch', { - months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), - monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), - monthsParseExact : true, - weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), - weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), - weekdaysMin : 'di_lu_ma_me_je_ve_sa'.split('_'), + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': + return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami'; + case 'ss': + if (number === 1) { + result += withoutSuffix ? 'sekundo' : 'sekundi'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'sekundi' : 'sekundah'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'sekunde' : 'sekundah'; + } else { + result += 'sekund'; + } + return result; + case 'm': + return withoutSuffix ? 'ena minuta' : 'eno minuto'; + case 'mm': + if (number === 1) { + result += withoutSuffix ? 'minuta' : 'minuto'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'minuti' : 'minutama'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'minute' : 'minutami'; + } else { + result += withoutSuffix || isFuture ? 'minut' : 'minutami'; + } + return result; + case 'h': + return withoutSuffix ? 'ena ura' : 'eno uro'; + case 'hh': + if (number === 1) { + result += withoutSuffix ? 'ura' : 'uro'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'uri' : 'urama'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'ure' : 'urami'; + } else { + result += withoutSuffix || isFuture ? 'ur' : 'urami'; + } + return result; + case 'd': + return withoutSuffix || isFuture ? 'en dan' : 'enim dnem'; + case 'dd': + if (number === 1) { + result += withoutSuffix || isFuture ? 'dan' : 'dnem'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'dni' : 'dnevoma'; + } else { + result += withoutSuffix || isFuture ? 'dni' : 'dnevi'; + } + return result; + case 'M': + return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem'; + case 'MM': + if (number === 1) { + result += withoutSuffix || isFuture ? 'mesec' : 'mesecem'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'meseca' : 'mesecema'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'mesece' : 'meseci'; + } else { + result += withoutSuffix || isFuture ? 'mesecev' : 'meseci'; + } + return result; + case 'y': + return withoutSuffix || isFuture ? 'eno leto' : 'enim letom'; + case 'yy': + if (number === 1) { + result += withoutSuffix || isFuture ? 'leto' : 'letom'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'leti' : 'letoma'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'leta' : 'leti'; + } else { + result += withoutSuffix || isFuture ? 'let' : 'leti'; + } + return result; + } + } + + var sl = moment.defineLocale('sl', { + months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'), + monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'), + monthsParseExact: true, + weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'), + weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'), + weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'), weekdaysParseExact : true, longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', + LT : 'H:mm', + LTS : 'H:mm:ss', L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' }, calendar : { - sameDay : '[Aujourd’hui à] LT', - nextDay : '[Demain à] LT', - nextWeek : 'dddd [à] LT', - lastDay : '[Hier à] LT', - lastWeek : 'dddd [dernier à] LT', + sameDay : '[danes ob] LT', + nextDay : '[jutri ob] LT', + + nextWeek : function () { + switch (this.day()) { + case 0: + return '[v] [nedeljo] [ob] LT'; + case 3: + return '[v] [sredo] [ob] LT'; + case 6: + return '[v] [soboto] [ob] LT'; + case 1: + case 2: + case 4: + case 5: + return '[v] dddd [ob] LT'; + } + }, + lastDay : '[včeraj ob] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + return '[prejšnjo] [nedeljo] [ob] LT'; + case 3: + return '[prejšnjo] [sredo] [ob] LT'; + case 6: + return '[prejšnjo] [soboto] [ob] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prejšnji] dddd [ob] LT'; + } + }, sameElse : 'L' }, relativeTime : { - future : 'dans %s', - past : 'il y a %s', - s : 'quelques secondes', - ss : '%d secondes', - m : 'une minute', - mm : '%d minutes', - h : 'une heure', - hh : '%d heures', - d : 'un jour', - dd : '%d jours', - M : 'un mois', - MM : '%d mois', - y : 'un an', - yy : '%d ans' - }, - dayOfMonthOrdinalParse: /\d{1,2}(er|e)/, - ordinal : function (number, period) { - switch (period) { - // Words with masculine grammatical gender: mois, trimestre, jour - default: - case 'M': - case 'Q': - case 'D': - case 'DDD': - case 'd': - return number + (number === 1 ? 'er' : 'e'); - - // Words with feminine grammatical gender: semaine - case 'w': - case 'W': - return number + (number === 1 ? 're' : 'e'); - } + future : 'čez %s', + past : 'pred %s', + s : processRelativeTime, + ss : processRelativeTime, + m : processRelativeTime, + mm : processRelativeTime, + h : processRelativeTime, + hh : processRelativeTime, + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + doy : 7 // The week that contains Jan 7th is the first week of the year. } }); - return frCh; + return sl; }))); /***/ }), -/* 87 */ +/* 112 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_'), - monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'); - - var fy = moment.defineLocale('fy', { - months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'), - monthsShort : function (m, format) { - if (!m) { - return monthsShortWithDots; - } else if (/-MMM-/.test(format)) { - return monthsShortWithoutDots[m.month()]; - } else { - return monthsShortWithDots[m.month()]; - } - }, - monthsParseExact : true, - weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'), - weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'), - weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'), + var sq = moment.defineLocale('sq', { + months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'), + monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'), + weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'), + weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'), + weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'), weekdaysParseExact : true, + meridiemParse: /PD|MD/, + isPM: function (input) { + return input.charAt(0) === 'M'; + }, + meridiem : function (hours, minutes, isLower) { + return hours < 12 ? 'PD' : 'MD'; + }, longDateFormat : { LT : 'HH:mm', LTS : 'HH:mm:ss', - L : 'DD-MM-YYYY', + L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' + LLLL : 'dddd, D MMMM YYYY HH:mm' }, calendar : { - sameDay: '[hjoed om] LT', - nextDay: '[moarn om] LT', - nextWeek: 'dddd [om] LT', - lastDay: '[juster om] LT', - lastWeek: '[ôfrûne] dddd [om] LT', - sameElse: 'L' + sameDay : '[Sot në] LT', + nextDay : '[Nesër në] LT', + nextWeek : 'dddd [në] LT', + lastDay : '[Dje në] LT', + lastWeek : 'dddd [e kaluar në] LT', + sameElse : 'L' }, relativeTime : { - future : 'oer %s', - past : '%s lyn', - s : 'in pear sekonden', - ss : '%d sekonden', - m : 'ien minút', - mm : '%d minuten', - h : 'ien oere', - hh : '%d oeren', - d : 'ien dei', - dd : '%d dagen', - M : 'ien moanne', - MM : '%d moannen', - y : 'ien jier', - yy : '%d jierren' - }, - dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, - ordinal : function (number) { - return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); + future : 'në %s', + past : '%s më parë', + s : 'disa sekonda', + ss : '%d sekonda', + m : 'një minutë', + mm : '%d minuta', + h : 'një orë', + hh : '%d orë', + d : 'një ditë', + dd : '%d ditë', + M : 'një muaj', + MM : '%d muaj', + y : 'një vit', + yy : '%d vite' }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return fy; + return sq; }))); /***/ }), -/* 88 */ +/* 113 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; + var translator = { + words: { //Different grammatical cases + ss: ['sekunda', 'sekunde', 'sekundi'], + m: ['jedan minut', 'jedne minute'], + mm: ['minut', 'minute', 'minuta'], + h: ['jedan sat', 'jednog sata'], + hh: ['sat', 'sata', 'sati'], + dd: ['dan', 'dana', 'dana'], + MM: ['mesec', 'meseca', 'meseci'], + yy: ['godina', 'godine', 'godina'] + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); + }, + translate: function (number, withoutSuffix, key) { + var wordKey = translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return number + ' ' + translator.correctGrammaticalCase(number, wordKey); + } + } + }; - var months = [ - 'Eanáir', 'Feabhra', 'Márta', 'Aibreán', 'Bealtaine', 'Méitheamh', 'Iúil', 'Lúnasa', 'Meán Fómhair', 'Deaireadh Fómhair', 'Samhain', 'Nollaig' - ]; - - var monthsShort = ['Eaná', 'Feab', 'Márt', 'Aibr', 'Beal', 'Méit', 'Iúil', 'Lúna', 'Meán', 'Deai', 'Samh', 'Noll']; - - var weekdays = ['Dé Domhnaigh', 'Dé Luain', 'Dé Máirt', 'Dé Céadaoin', 'Déardaoin', 'Dé hAoine', 'Dé Satharn']; - - var weekdaysShort = ['Dom', 'Lua', 'Mái', 'Céa', 'Déa', 'hAo', 'Sat']; - - var weekdaysMin = ['Do', 'Lu', 'Má', 'Ce', 'Dé', 'hA', 'Sa']; - - var ga = moment.defineLocale('ga', { - months: months, - monthsShort: monthsShort, + var sr = moment.defineLocale('sr', { + months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'), + monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'), monthsParseExact: true, - weekdays: weekdays, - weekdaysShort: weekdaysShort, - weekdaysMin: weekdaysMin, + weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'), + weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'), + weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'), + weekdaysParseExact : true, longDateFormat: { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY HH:mm', - LLLL: 'dddd, D MMMM YYYY HH:mm' + LT: 'H:mm', + LTS : 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm' }, calendar: { - sameDay: '[Inniu ag] LT', - nextDay: '[Amárach ag] LT', - nextWeek: 'dddd [ag] LT', - lastDay: '[Inné aig] LT', - lastWeek: 'dddd [seo caite] [ag] LT', - sameElse: 'L' - }, - relativeTime: { - future: 'i %s', - past: '%s ó shin', - s: 'cúpla soicind', - ss: '%d soicind', - m: 'nóiméad', - mm: '%d nóiméad', - h: 'uair an chloig', - hh: '%d uair an chloig', - d: 'lá', - dd: '%d lá', - M: 'mí', - MM: '%d mí', - y: 'bliain', - yy: '%d bliain' + sameDay: '[danas u] LT', + nextDay: '[sutra u] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[u] [nedelju] [u] LT'; + case 3: + return '[u] [sredu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[juče u] LT', + lastWeek : function () { + var lastWeekDays = [ + '[prošle] [nedelje] [u] LT', + '[prošlog] [ponedeljka] [u] LT', + '[prošlog] [utorka] [u] LT', + '[prošle] [srede] [u] LT', + '[prošlog] [četvrtka] [u] LT', + '[prošlog] [petka] [u] LT', + '[prošle] [subote] [u] LT' + ]; + return lastWeekDays[this.day()]; + }, + sameElse : 'L' }, - dayOfMonthOrdinalParse: /\d{1,2}(d|na|mh)/, - ordinal: function (number) { - var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh'; - return number + output; + relativeTime : { + future : 'za %s', + past : 'pre %s', + s : 'nekoliko sekundi', + ss : translator.translate, + m : translator.translate, + mm : translator.translate, + h : translator.translate, + hh : translator.translate, + d : 'dan', + dd : translator.translate, + M : 'mesec', + MM : translator.translate, + y : 'godinu', + yy : translator.translate }, - week: { - dow: 1, // Monday is the first day of the week. - doy: 4 // The week that contains Jan 4th is the first week of the year. + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. } }); - return ga; + return sr; }))); /***/ }), -/* 89 */ +/* 114 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var months = [ - 'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd' - ]; - - var monthsShort = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh']; - - var weekdays = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne']; - - var weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis']; - - var weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa']; + var translator = { + words: { //Different grammatical cases + ss: ['секунда', 'секунде', 'секунди'], + m: ['један минут', 'једне минуте'], + mm: ['минут', 'минуте', 'минута'], + h: ['један сат', 'једног сата'], + hh: ['сат', 'сата', 'сати'], + dd: ['дан', 'дана', 'дана'], + MM: ['месец', 'месеца', 'месеци'], + yy: ['година', 'године', 'година'] + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); + }, + translate: function (number, withoutSuffix, key) { + var wordKey = translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return number + ' ' + translator.correctGrammaticalCase(number, wordKey); + } + } + }; - var gd = moment.defineLocale('gd', { - months : months, - monthsShort : monthsShort, - monthsParseExact : true, - weekdays : weekdays, - weekdaysShort : weekdaysShort, - weekdaysMin : weekdaysMin, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' + var srCyrl = moment.defineLocale('sr-cyrl', { + months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'), + monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'), + monthsParseExact: true, + weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'), + weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'), + weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'), + weekdaysParseExact : true, + longDateFormat: { + LT: 'H:mm', + LTS : 'H:mm:ss', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm' }, - calendar : { - sameDay : '[An-diugh aig] LT', - nextDay : '[A-màireach aig] LT', - nextWeek : 'dddd [aig] LT', - lastDay : '[An-dè aig] LT', - lastWeek : 'dddd [seo chaidh] [aig] LT', + calendar: { + sameDay: '[данас у] LT', + nextDay: '[сутра у] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[у] [недељу] [у] LT'; + case 3: + return '[у] [среду] [у] LT'; + case 6: + return '[у] [суботу] [у] LT'; + case 1: + case 2: + case 4: + case 5: + return '[у] dddd [у] LT'; + } + }, + lastDay : '[јуче у] LT', + lastWeek : function () { + var lastWeekDays = [ + '[прошле] [недеље] [у] LT', + '[прошлог] [понедељка] [у] LT', + '[прошлог] [уторка] [у] LT', + '[прошле] [среде] [у] LT', + '[прошлог] [четвртка] [у] LT', + '[прошлог] [петка] [у] LT', + '[прошле] [суботе] [у] LT' + ]; + return lastWeekDays[this.day()]; + }, sameElse : 'L' }, relativeTime : { - future : 'ann an %s', - past : 'bho chionn %s', - s : 'beagan diogan', - ss : '%d diogan', - m : 'mionaid', - mm : '%d mionaidean', - h : 'uair', - hh : '%d uairean', - d : 'latha', - dd : '%d latha', - M : 'mìos', - MM : '%d mìosan', - y : 'bliadhna', - yy : '%d bliadhna' - }, - dayOfMonthOrdinalParse : /\d{1,2}(d|na|mh)/, - ordinal : function (number) { - var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh'; - return number + output; + future : 'за %s', + past : 'пре %s', + s : 'неколико секунди', + ss : translator.translate, + m : translator.translate, + mm : translator.translate, + h : translator.translate, + hh : translator.translate, + d : 'дан', + dd : translator.translate, + M : 'месец', + MM : translator.translate, + y : 'годину', + yy : translator.translate }, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + doy : 7 // The week that contains Jan 7th is the first week of the year. } }); - return gd; + return srCyrl; }))); /***/ }), -/* 90 */ +/* 115 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var gl = moment.defineLocale('gl', { - months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'), - monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'), - monthsParseExact: true, - weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'), - weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'), - weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'), + var ss = moment.defineLocale('ss', { + months : "Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split('_'), + monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'), + weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'), + weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'), + weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'), weekdaysParseExact : true, longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', + LT : 'h:mm A', + LTS : 'h:mm:ss A', L : 'DD/MM/YYYY', - LL : 'D [de] MMMM [de] YYYY', - LLL : 'D [de] MMMM [de] YYYY H:mm', - LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm' + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' }, calendar : { - sameDay : function () { - return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; - }, - nextDay : function () { - return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; - }, - nextWeek : function () { - return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; - }, - lastDay : function () { - return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT'; - }, - lastWeek : function () { - return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; - }, + sameDay : '[Namuhla nga] LT', + nextDay : '[Kusasa nga] LT', + nextWeek : 'dddd [nga] LT', + lastDay : '[Itolo nga] LT', + lastWeek : 'dddd [leliphelile] [nga] LT', sameElse : 'L' }, relativeTime : { - future : function (str) { - if (str.indexOf('un') === 0) { - return 'n' + str; + future : 'nga %s', + past : 'wenteka nga %s', + s : 'emizuzwana lomcane', + ss : '%d mzuzwana', + m : 'umzuzu', + mm : '%d emizuzu', + h : 'lihora', + hh : '%d emahora', + d : 'lilanga', + dd : '%d emalanga', + M : 'inyanga', + MM : '%d tinyanga', + y : 'umnyaka', + yy : '%d iminyaka' + }, + meridiemParse: /ekuseni|emini|entsambama|ebusuku/, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'ekuseni'; + } else if (hours < 15) { + return 'emini'; + } else if (hours < 19) { + return 'entsambama'; + } else { + return 'ebusuku'; + } + }, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'ekuseni') { + return hour; + } else if (meridiem === 'emini') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') { + if (hour === 0) { + return 0; } - return 'en ' + str; - }, - past : 'hai %s', - s : 'uns segundos', - ss : '%d segundos', - m : 'un minuto', - mm : '%d minutos', - h : 'unha hora', - hh : '%d horas', - d : 'un día', - dd : '%d días', - M : 'un mes', - MM : '%d meses', - y : 'un ano', - yy : '%d anos' + return hour + 12; + } }, - dayOfMonthOrdinalParse : /\d{1,2}º/, - ordinal : '%dº', + dayOfMonthOrdinalParse: /\d{1,2}/, + ordinal : '%d', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return gl; + return ss; }))); /***/ }), -/* 91 */ +/* 116 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - function processRelativeTime(number, withoutSuffix, key, isFuture) { - var format = { - 's': ['thodde secondanim', 'thodde second'], - 'ss': [number + ' secondanim', number + ' second'], - 'm': ['eka mintan', 'ek minute'], - 'mm': [number + ' mintanim', number + ' mintam'], - 'h': ['eka voran', 'ek vor'], - 'hh': [number + ' voranim', number + ' voram'], - 'd': ['eka disan', 'ek dis'], - 'dd': [number + ' disanim', number + ' dis'], - 'M': ['eka mhoinean', 'ek mhoino'], - 'MM': [number + ' mhoineanim', number + ' mhoine'], - 'y': ['eka vorsan', 'ek voros'], - 'yy': [number + ' vorsanim', number + ' vorsam'] - }; - return withoutSuffix ? format[key][0] : format[key][1]; - } - - var gomLatn = moment.defineLocale('gom-latn', { - months : 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split('_'), - monthsShort : 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split('_'), - monthsParseExact : true, - weekdays : 'Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son\'var'.split('_'), - weekdaysShort : 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'), - weekdaysMin : 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'), - weekdaysParseExact : true, + var sv = moment.defineLocale('sv', { + months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'), + monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), + weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'), + weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'), + weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'), longDateFormat : { - LT : 'A h:mm [vazta]', - LTS : 'A h:mm:ss [vazta]', - L : 'DD-MM-YYYY', + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY A h:mm [vazta]', - LLLL : 'dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]', - llll: 'ddd, D MMM YYYY, A h:mm [vazta]' + LLL : 'D MMMM YYYY [kl.] HH:mm', + LLLL : 'dddd D MMMM YYYY [kl.] HH:mm', + lll : 'D MMM YYYY HH:mm', + llll : 'ddd D MMM YYYY HH:mm' }, calendar : { - sameDay: '[Aiz] LT', - nextDay: '[Faleam] LT', - nextWeek: '[Ieta to] dddd[,] LT', - lastDay: '[Kal] LT', - lastWeek: '[Fatlo] dddd[,] LT', + sameDay: '[Idag] LT', + nextDay: '[Imorgon] LT', + lastDay: '[Igår] LT', + nextWeek: '[På] dddd LT', + lastWeek: '[I] dddd[s] LT', sameElse: 'L' }, relativeTime : { - future : '%s', - past : '%s adim', - s : processRelativeTime, - ss : processRelativeTime, - m : processRelativeTime, - mm : processRelativeTime, - h : processRelativeTime, - hh : processRelativeTime, - d : processRelativeTime, - dd : processRelativeTime, - M : processRelativeTime, - MM : processRelativeTime, - y : processRelativeTime, - yy : processRelativeTime + future : 'om %s', + past : 'för %s sedan', + s : 'några sekunder', + ss : '%d sekunder', + m : 'en minut', + mm : '%d minuter', + h : 'en timme', + hh : '%d timmar', + d : 'en dag', + dd : '%d dagar', + M : 'en månad', + MM : '%d månader', + y : 'ett år', + yy : '%d år' }, - dayOfMonthOrdinalParse : /\d{1,2}(er)/, - ordinal : function (number, period) { - switch (period) { - // the ordinal 'er' only applies to day of the month - case 'D': - return number + 'er'; - default: - case 'M': - case 'Q': - case 'DDD': - case 'd': - case 'w': - case 'W': - return number; - } + dayOfMonthOrdinalParse: /\d{1,2}(e|a)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'e' : + (b === 1) ? 'a' : + (b === 2) ? 'a' : + (b === 3) ? 'e' : 'e'; + return number + output; }, week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. - }, - meridiemParse: /rati|sokalli|donparam|sanje/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'rati') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'sokalli') { - return hour; - } else if (meridiem === 'donparam') { - return hour > 12 ? hour : hour + 12; - } else if (meridiem === 'sanje') { - return hour + 12; - } - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'rati'; - } else if (hour < 12) { - return 'sokalli'; - } else if (hour < 16) { - return 'donparam'; - } else if (hour < 20) { - return 'sanje'; - } else { - return 'rati'; - } } }); - return gomLatn; + return sv; }))); /***/ }), -/* 92 */ +/* 117 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var symbolMap = { - '1': '૧', - '2': '૨', - '3': '૩', - '4': '૪', - '5': '૫', - '6': '૬', - '7': '૭', - '8': '૮', - '9': '૯', - '0': '૦' - }, - numberMap = { - '૧': '1', - '૨': '2', - '૩': '3', - '૪': '4', - '૫': '5', - '૬': '6', - '૭': '7', - '૮': '8', - '૯': '9', - '૦': '0' - }; - - var gu = moment.defineLocale('gu', { - months: 'જાન્યુઆરી_ફેબ્રુઆરી_માર્ચ_એપ્રિલ_મે_જૂન_જુલાઈ_ઑગસ્ટ_સપ્ટેમ્બર_ઑક્ટ્બર_નવેમ્બર_ડિસેમ્બર'.split('_'), - monthsShort: 'જાન્યુ._ફેબ્રુ._માર્ચ_એપ્રિ._મે_જૂન_જુલા._ઑગ._સપ્ટે._ઑક્ટ્._નવે._ડિસે.'.split('_'), - monthsParseExact: true, - weekdays: 'રવિવાર_સોમવાર_મંગળવાર_બુધ્વાર_ગુરુવાર_શુક્રવાર_શનિવાર'.split('_'), - weekdaysShort: 'રવિ_સોમ_મંગળ_બુધ્_ગુરુ_શુક્ર_શનિ'.split('_'), - weekdaysMin: 'ર_સો_મં_બુ_ગુ_શુ_શ'.split('_'), - longDateFormat: { - LT: 'A h:mm વાગ્યે', - LTS: 'A h:mm:ss વાગ્યે', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY, A h:mm વાગ્યે', - LLLL: 'dddd, D MMMM YYYY, A h:mm વાગ્યે' - }, - calendar: { - sameDay: '[આજ] LT', - nextDay: '[કાલે] LT', - nextWeek: 'dddd, LT', - lastDay: '[ગઇકાલે] LT', - lastWeek: '[પાછલા] dddd, LT', - sameElse: 'L' - }, - relativeTime: { - future: '%s મા', - past: '%s પેહલા', - s: 'અમુક પળો', - ss: '%d સેકંડ', - m: 'એક મિનિટ', - mm: '%d મિનિટ', - h: 'એક કલાક', - hh: '%d કલાક', - d: 'એક દિવસ', - dd: '%d દિવસ', - M: 'એક મહિનો', - MM: '%d મહિનો', - y: 'એક વર્ષ', - yy: '%d વર્ષ' - }, - preparse: function (string) { - return string.replace(/[૧૨૩૪૫૬૭૮૯૦]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); + var sw = moment.defineLocale('sw', { + months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'), + monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'), + weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'), + weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'), + weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'), + weekdaysParseExact : true, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' }, - // Gujarati notation for meridiems are quite fuzzy in practice. While there exists - // a rigid notion of a 'Pahar' it is not used as rigidly in modern Gujarati. - meridiemParse: /રાત|બપોર|સવાર|સાંજ/, - meridiemHour: function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'રાત') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'સવાર') { - return hour; - } else if (meridiem === 'બપોર') { - return hour >= 10 ? hour : hour + 12; - } else if (meridiem === 'સાંજ') { - return hour + 12; - } + calendar : { + sameDay : '[leo saa] LT', + nextDay : '[kesho saa] LT', + nextWeek : '[wiki ijayo] dddd [saat] LT', + lastDay : '[jana] LT', + lastWeek : '[wiki iliyopita] dddd [saat] LT', + sameElse : 'L' }, - meridiem: function (hour, minute, isLower) { - if (hour < 4) { - return 'રાત'; - } else if (hour < 10) { - return 'સવાર'; - } else if (hour < 17) { - return 'બપોર'; - } else if (hour < 20) { - return 'સાંજ'; - } else { - return 'રાત'; - } + relativeTime : { + future : '%s baadaye', + past : 'tokea %s', + s : 'hivi punde', + ss : 'sekunde %d', + m : 'dakika moja', + mm : 'dakika %d', + h : 'saa limoja', + hh : 'masaa %d', + d : 'siku moja', + dd : 'masiku %d', + M : 'mwezi mmoja', + MM : 'miezi %d', + y : 'mwaka mmoja', + yy : 'miaka %d' }, - week: { - dow: 0, // Sunday is the first day of the week. - doy: 6 // The week that contains Jan 6th is the first week of the year. + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. } }); - return gu; + return sw; }))); /***/ }), -/* 93 */ +/* 118 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var he = moment.defineLocale('he', { - months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'), - monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'), - weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'), - weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'), - weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'), + var symbolMap = { + '1': '௧', + '2': '௨', + '3': '௩', + '4': '௪', + '5': '௫', + '6': '௬', + '7': '௭', + '8': '௮', + '9': '௯', + '0': '௦' + }, numberMap = { + '௧': '1', + '௨': '2', + '௩': '3', + '௪': '4', + '௫': '5', + '௬': '6', + '௭': '7', + '௮': '8', + '௯': '9', + '௦': '0' + }; + + var ta = moment.defineLocale('ta', { + months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), + monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), + weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'), + weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'), + weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'), longDateFormat : { LT : 'HH:mm', LTS : 'HH:mm:ss', L : 'DD/MM/YYYY', - LL : 'D [ב]MMMM YYYY', - LLL : 'D [ב]MMMM YYYY HH:mm', - LLLL : 'dddd, D [ב]MMMM YYYY HH:mm', - l : 'D/M/YYYY', - ll : 'D MMM YYYY', - lll : 'D MMM YYYY HH:mm', - llll : 'ddd, D MMM YYYY HH:mm' + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, HH:mm', + LLLL : 'dddd, D MMMM YYYY, HH:mm' }, calendar : { - sameDay : '[היום ב־]LT', - nextDay : '[מחר ב־]LT', - nextWeek : 'dddd [בשעה] LT', - lastDay : '[אתמול ב־]LT', - lastWeek : '[ביום] dddd [האחרון בשעה] LT', + sameDay : '[இன்று] LT', + nextDay : '[நாளை] LT', + nextWeek : 'dddd, LT', + lastDay : '[நேற்று] LT', + lastWeek : '[கடந்த வாரம்] dddd, LT', sameElse : 'L' }, relativeTime : { - future : 'בעוד %s', - past : 'לפני %s', - s : 'מספר שניות', - ss : '%d שניות', - m : 'דקה', - mm : '%d דקות', - h : 'שעה', - hh : function (number) { - if (number === 2) { - return 'שעתיים'; - } - return number + ' שעות'; - }, - d : 'יום', - dd : function (number) { - if (number === 2) { - return 'יומיים'; - } - return number + ' ימים'; - }, - M : 'חודש', - MM : function (number) { - if (number === 2) { - return 'חודשיים'; - } - return number + ' חודשים'; - }, - y : 'שנה', - yy : function (number) { - if (number === 2) { - return 'שנתיים'; - } else if (number % 10 === 0 && number !== 10) { - return number + ' שנה'; - } - return number + ' שנים'; - } + future : '%s இல்', + past : '%s முன்', + s : 'ஒரு சில விநாடிகள்', + ss : '%d விநாடிகள்', + m : 'ஒரு நிமிடம்', + mm : '%d நிமிடங்கள்', + h : 'ஒரு மணி நேரம்', + hh : '%d மணி நேரம்', + d : 'ஒரு நாள்', + dd : '%d நாட்கள்', + M : 'ஒரு மாதம்', + MM : '%d மாதங்கள்', + y : 'ஒரு வருடம்', + yy : '%d ஆண்டுகள்' }, - meridiemParse: /אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i, - isPM : function (input) { - return /^(אחה"צ|אחרי הצהריים|בערב)$/.test(input); + dayOfMonthOrdinalParse: /\d{1,2}வது/, + ordinal : function (number) { + return number + 'வது'; }, + preparse: function (string) { + return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) { + return numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return symbolMap[match]; + }); + }, + // refer http://ta.wikipedia.org/s/1er1 + meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/, meridiem : function (hour, minute, isLower) { - if (hour < 5) { - return 'לפנות בוקר'; + if (hour < 2) { + return ' யாமம்'; + } else if (hour < 6) { + return ' வைகறை'; // வைகறை } else if (hour < 10) { - return 'בבוקר'; - } else if (hour < 12) { - return isLower ? 'לפנה"צ' : 'לפני הצהריים'; + return ' காலை'; // காலை + } else if (hour < 14) { + return ' நண்பகல்'; // நண்பகல் } else if (hour < 18) { - return isLower ? 'אחה"צ' : 'אחרי הצהריים'; + return ' எற்பாடு'; // எற்பாடு + } else if (hour < 22) { + return ' மாலை'; // மாலை } else { - return 'בערב'; + return ' யாமம்'; + } + }, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'யாமம்') { + return hour < 2 ? hour : hour + 12; + } else if (meridiem === 'வைகறை' || meridiem === 'காலை') { + return hour; + } else if (meridiem === 'நண்பகல்') { + return hour >= 10 ? hour : hour + 12; + } else { + return hour + 12; } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 6th is the first week of the year. } }); - return he; + return ta; }))); /***/ }), -/* 94 */ +/* 119 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var symbolMap = { - '1': '१', - '2': '२', - '3': '३', - '4': '४', - '5': '५', - '6': '६', - '7': '७', - '8': '८', - '9': '९', - '0': '०' - }, - numberMap = { - '१': '1', - '२': '2', - '३': '3', - '४': '4', - '५': '5', - '६': '6', - '७': '7', - '८': '8', - '९': '9', - '०': '0' - }; - - var hi = moment.defineLocale('hi', { - months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'), - monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'), - monthsParseExact: true, - weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), - weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'), - weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), + var te = moment.defineLocale('te', { + months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జులై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'), + monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జులై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'), + monthsParseExact : true, + weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'), + weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'), + weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'), longDateFormat : { - LT : 'A h:mm बजे', - LTS : 'A h:mm:ss बजे', + LT : 'A h:mm', + LTS : 'A h:mm:ss', L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm बजे', - LLLL : 'dddd, D MMMM YYYY, A h:mm बजे' + LLL : 'D MMMM YYYY, A h:mm', + LLLL : 'dddd, D MMMM YYYY, A h:mm' }, calendar : { - sameDay : '[आज] LT', - nextDay : '[कल] LT', + sameDay : '[నేడు] LT', + nextDay : '[రేపు] LT', nextWeek : 'dddd, LT', - lastDay : '[कल] LT', - lastWeek : '[पिछले] dddd, LT', + lastDay : '[నిన్న] LT', + lastWeek : '[గత] dddd, LT', sameElse : 'L' }, relativeTime : { - future : '%s में', - past : '%s पहले', - s : 'कुछ ही क्षण', - ss : '%d सेकंड', - m : 'एक मिनट', - mm : '%d मिनट', - h : 'एक घंटा', - hh : '%d घंटे', - d : 'एक दिन', - dd : '%d दिन', - M : 'एक महीने', - MM : '%d महीने', - y : 'एक वर्ष', - yy : '%d वर्ष' - }, - preparse: function (string) { - return string.replace(/[१२३४५६७८९०]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); + future : '%s లో', + past : '%s క్రితం', + s : 'కొన్ని క్షణాలు', + ss : '%d సెకన్లు', + m : 'ఒక నిమిషం', + mm : '%d నిమిషాలు', + h : 'ఒక గంట', + hh : '%d గంటలు', + d : 'ఒక రోజు', + dd : '%d రోజులు', + M : 'ఒక నెల', + MM : '%d నెలలు', + y : 'ఒక సంవత్సరం', + yy : '%d సంవత్సరాలు' }, - // Hindi notation for meridiems are quite fuzzy in practice. While there exists - // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi. - meridiemParse: /रात|सुबह|दोपहर|शाम/, + dayOfMonthOrdinalParse : /\d{1,2}వ/, + ordinal : '%dవ', + meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/, meridiemHour : function (hour, meridiem) { if (hour === 12) { hour = 0; } - if (meridiem === 'रात') { + if (meridiem === 'రాత్రి') { return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'सुबह') { + } else if (meridiem === 'ఉదయం') { return hour; - } else if (meridiem === 'दोपहर') { + } else if (meridiem === 'మధ్యాహ్నం') { return hour >= 10 ? hour : hour + 12; - } else if (meridiem === 'शाम') { + } else if (meridiem === 'సాయంత్రం') { return hour + 12; } }, meridiem : function (hour, minute, isLower) { if (hour < 4) { - return 'रात'; + return 'రాత్రి'; } else if (hour < 10) { - return 'सुबह'; + return 'ఉదయం'; } else if (hour < 17) { - return 'दोपहर'; + return 'మధ్యాహ్నం'; } else if (hour < 20) { - return 'शाम'; + return 'సాయంత్రం'; } else { - return 'रात'; + return 'రాత్రి'; } }, week : { @@ -14720,584 +16254,445 @@ webpackContext.id = 41; } }); - return hi; + return te; }))); /***/ }), -/* 95 */ +/* 120 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - function translate(number, withoutSuffix, key) { - var result = number + ' '; - switch (key) { - case 'ss': - if (number === 1) { - result += 'sekunda'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'sekunde'; - } else { - result += 'sekundi'; - } - return result; - case 'm': - return withoutSuffix ? 'jedna minuta' : 'jedne minute'; - case 'mm': - if (number === 1) { - result += 'minuta'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'minute'; - } else { - result += 'minuta'; - } - return result; - case 'h': - return withoutSuffix ? 'jedan sat' : 'jednog sata'; - case 'hh': - if (number === 1) { - result += 'sat'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'sata'; - } else { - result += 'sati'; - } - return result; - case 'dd': - if (number === 1) { - result += 'dan'; - } else { - result += 'dana'; - } - return result; - case 'MM': - if (number === 1) { - result += 'mjesec'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'mjeseca'; - } else { - result += 'mjeseci'; - } - return result; - case 'yy': - if (number === 1) { - result += 'godina'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'godine'; - } else { - result += 'godina'; - } - return result; - } - } - - var hr = moment.defineLocale('hr', { - months : { - format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'), - standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_') - }, - monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'), - monthsParseExact: true, - weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), - weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), - weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), - weekdaysParseExact : true, + var tet = moment.defineLocale('tet', { + months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juñu_Jullu_Agustu_Setembru_Outubru_Novembru_Dezembru'.split('_'), + monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'), + weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sesta_Sabadu'.split('_'), + weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sest_Sab'.split('_'), + weekdaysMin : 'Do_Seg_Te_Ku_Ki_Ses_Sa'.split('_'), longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY H:mm', - LLLL : 'dddd, D. MMMM YYYY H:mm' + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' }, calendar : { - sameDay : '[danas u] LT', - nextDay : '[sutra u] LT', - nextWeek : function () { - switch (this.day()) { - case 0: - return '[u] [nedjelju] [u] LT'; - case 3: - return '[u] [srijedu] [u] LT'; - case 6: - return '[u] [subotu] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[u] dddd [u] LT'; - } - }, - lastDay : '[jučer u] LT', - lastWeek : function () { - switch (this.day()) { - case 0: - case 3: - return '[prošlu] dddd [u] LT'; - case 6: - return '[prošle] [subote] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[prošli] dddd [u] LT'; - } - }, - sameElse : 'L' + sameDay: '[Ohin iha] LT', + nextDay: '[Aban iha] LT', + nextWeek: 'dddd [iha] LT', + lastDay: '[Horiseik iha] LT', + lastWeek: 'dddd [semana kotuk] [iha] LT', + sameElse: 'L' }, relativeTime : { - future : 'za %s', - past : 'prije %s', - s : 'par sekundi', - ss : translate, - m : translate, - mm : translate, - h : translate, - hh : translate, - d : 'dan', - dd : translate, - M : 'mjesec', - MM : translate, - y : 'godinu', - yy : translate + future : 'iha %s', + past : '%s liuba', + s : 'minutu balun', + ss : 'minutu %d', + m : 'minutu ida', + mm : 'minutu %d', + h : 'oras ida', + hh : 'oras %d', + d : 'loron ida', + dd : 'loron %d', + M : 'fulan ida', + MM : 'fulan %d', + y : 'tinan ida', + yy : 'tinan %d' + }, + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. + doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return hr; + return tet; }))); /***/ }), -/* 96 */ +/* 121 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' '); - function translate(number, withoutSuffix, key, isFuture) { - var num = number; - switch (key) { - case 's': - return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce'; - case 'ss': - return num + (isFuture || withoutSuffix) ? ' másodperc' : ' másodperce'; - case 'm': - return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce'); - case 'mm': - return num + (isFuture || withoutSuffix ? ' perc' : ' perce'); - case 'h': - return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája'); - case 'hh': - return num + (isFuture || withoutSuffix ? ' óra' : ' órája'); - case 'd': - return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja'); - case 'dd': - return num + (isFuture || withoutSuffix ? ' nap' : ' napja'); - case 'M': - return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); - case 'MM': - return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); - case 'y': - return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve'); - case 'yy': - return num + (isFuture || withoutSuffix ? ' év' : ' éve'); - } - return ''; - } - function week(isFuture) { - return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]'; - } + var suffixes = { + 0: '-ум', + 1: '-ум', + 2: '-юм', + 3: '-юм', + 4: '-ум', + 5: '-ум', + 6: '-ум', + 7: '-ум', + 8: '-ум', + 9: '-ум', + 10: '-ум', + 12: '-ум', + 13: '-ум', + 20: '-ум', + 30: '-юм', + 40: '-ум', + 50: '-ум', + 60: '-ум', + 70: '-ум', + 80: '-ум', + 90: '-ум', + 100: '-ум' + }; - var hu = moment.defineLocale('hu', { - months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'), - monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'), - weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'), - weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'), - weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'), + var tg = moment.defineLocale('tg', { + months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'), + monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'), + weekdays : 'якшанбе_душанбе_сешанбе_чоршанбе_панҷшанбе_ҷумъа_шанбе'.split('_'), + weekdaysShort : 'яшб_дшб_сшб_чшб_пшб_ҷум_шнб'.split('_'), + weekdaysMin : 'яш_дш_сш_чш_пш_ҷм_шб'.split('_'), longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'YYYY.MM.DD.', - LL : 'YYYY. MMMM D.', - LLL : 'YYYY. MMMM D. H:mm', - LLLL : 'YYYY. MMMM D., dddd H:mm' - }, - meridiemParse: /de|du/i, - isPM: function (input) { - return input.charAt(1).toLowerCase() === 'u'; - }, - meridiem : function (hours, minutes, isLower) { - if (hours < 12) { - return isLower === true ? 'de' : 'DE'; - } else { - return isLower === true ? 'du' : 'DU'; - } + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' }, calendar : { - sameDay : '[ma] LT[-kor]', - nextDay : '[holnap] LT[-kor]', - nextWeek : function () { - return week.call(this, true); - }, - lastDay : '[tegnap] LT[-kor]', - lastWeek : function () { - return week.call(this, false); - }, + sameDay : '[Имрӯз соати] LT', + nextDay : '[Пагоҳ соати] LT', + lastDay : '[Дирӯз соати] LT', + nextWeek : 'dddd[и] [ҳафтаи оянда соати] LT', + lastWeek : 'dddd[и] [ҳафтаи гузашта соати] LT', sameElse : 'L' }, relativeTime : { - future : '%s múlva', - past : '%s', - s : translate, - ss : translate, - m : translate, - mm : translate, - h : translate, - hh : translate, - d : translate, - dd : translate, - M : translate, - MM : translate, - y : translate, - yy : translate + future : 'баъди %s', + past : '%s пеш', + s : 'якчанд сония', + m : 'як дақиқа', + mm : '%d дақиқа', + h : 'як соат', + hh : '%d соат', + d : 'як рӯз', + dd : '%d рӯз', + M : 'як моҳ', + MM : '%d моҳ', + y : 'як сол', + yy : '%d сол' + }, + meridiemParse: /шаб|субҳ|рӯз|бегоҳ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'шаб') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'субҳ') { + return hour; + } else if (meridiem === 'рӯз') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'бегоҳ') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'шаб'; + } else if (hour < 11) { + return 'субҳ'; + } else if (hour < 16) { + return 'рӯз'; + } else if (hour < 19) { + return 'бегоҳ'; + } else { + return 'шаб'; + } + }, + dayOfMonthOrdinalParse: /\d{1,2}-(ум|юм)/, + ordinal: function (number) { + var a = number % 10, + b = number >= 100 ? 100 : null; + return number + (suffixes[number] || suffixes[a] || suffixes[b]); }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + doy : 7 // The week that contains Jan 1th is the first week of the year. } }); - return hu; + return tg; }))); /***/ }), -/* 97 */ +/* 122 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var hyAm = moment.defineLocale('hy-am', { - months : { - format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'), - standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_') - }, - monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'), - weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'), - weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), - weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), + var th = moment.defineLocale('th', { + months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'), + monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'), + monthsParseExact: true, + weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'), + weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference + weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'), + weekdaysParseExact : true, longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY թ.', - LLL : 'D MMMM YYYY թ., HH:mm', - LLLL : 'dddd, D MMMM YYYY թ., HH:mm' - }, - calendar : { - sameDay: '[այսօր] LT', - nextDay: '[վաղը] LT', - lastDay: '[երեկ] LT', - nextWeek: function () { - return 'dddd [օրը ժամը] LT'; - }, - lastWeek: function () { - return '[անցած] dddd [օրը ժամը] LT'; - }, - sameElse: 'L' - }, - relativeTime : { - future : '%s հետո', - past : '%s առաջ', - s : 'մի քանի վայրկյան', - ss : '%d վայրկյան', - m : 'րոպե', - mm : '%d րոպե', - h : 'ժամ', - hh : '%d ժամ', - d : 'օր', - dd : '%d օր', - M : 'ամիս', - MM : '%d ամիս', - y : 'տարի', - yy : '%d տարի' + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY เวลา H:mm', + LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm' }, - meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/, + meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/, isPM: function (input) { - return /^(ցերեկվա|երեկոյան)$/.test(input); + return input === 'หลังเที่ยง'; }, - meridiem : function (hour) { - if (hour < 4) { - return 'գիշերվա'; - } else if (hour < 12) { - return 'առավոտվա'; - } else if (hour < 17) { - return 'ցերեկվա'; + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ก่อนเที่ยง'; } else { - return 'երեկոյան'; + return 'หลังเที่ยง'; } }, - dayOfMonthOrdinalParse: /\d{1,2}|\d{1,2}-(ին|րդ)/, - ordinal: function (number, period) { - switch (period) { - case 'DDD': - case 'w': - case 'W': - case 'DDDo': - if (number === 1) { - return number + '-ին'; - } - return number + '-րդ'; - default: - return number; - } + calendar : { + sameDay : '[วันนี้ เวลา] LT', + nextDay : '[พรุ่งนี้ เวลา] LT', + nextWeek : 'dddd[หน้า เวลา] LT', + lastDay : '[เมื่อวานนี้ เวลา] LT', + lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT', + sameElse : 'L' }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. + relativeTime : { + future : 'อีก %s', + past : '%sที่แล้ว', + s : 'ไม่กี่วินาที', + ss : '%d วินาที', + m : '1 นาที', + mm : '%d นาที', + h : '1 ชั่วโมง', + hh : '%d ชั่วโมง', + d : '1 วัน', + dd : '%d วัน', + M : '1 เดือน', + MM : '%d เดือน', + y : '1 ปี', + yy : '%d ปี' } }); - return hyAm; + return th; }))); /***/ }), -/* 98 */ +/* 123 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var id = moment.defineLocale('id', { - months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Agt_Sep_Okt_Nov_Des'.split('_'), - weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'), - weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'), - weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'), + var tlPh = moment.defineLocale('tl-ph', { + months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'), + monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'), + weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'), + weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'), + weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'), longDateFormat : { - LT : 'HH.mm', - LTS : 'HH.mm.ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY [pukul] HH.mm', - LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' - }, - meridiemParse: /pagi|siang|sore|malam/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'pagi') { - return hour; - } else if (meridiem === 'siang') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === 'sore' || meridiem === 'malam') { - return hour + 12; - } - }, - meridiem : function (hours, minutes, isLower) { - if (hours < 11) { - return 'pagi'; - } else if (hours < 15) { - return 'siang'; - } else if (hours < 19) { - return 'sore'; - } else { - return 'malam'; - } + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'MM/D/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY HH:mm', + LLLL : 'dddd, MMMM DD, YYYY HH:mm' }, calendar : { - sameDay : '[Hari ini pukul] LT', - nextDay : '[Besok pukul] LT', - nextWeek : 'dddd [pukul] LT', - lastDay : '[Kemarin pukul] LT', - lastWeek : 'dddd [lalu pukul] LT', - sameElse : 'L' + sameDay: 'LT [ngayong araw]', + nextDay: '[Bukas ng] LT', + nextWeek: 'LT [sa susunod na] dddd', + lastDay: 'LT [kahapon]', + lastWeek: 'LT [noong nakaraang] dddd', + sameElse: 'L' }, relativeTime : { - future : 'dalam %s', - past : '%s yang lalu', - s : 'beberapa detik', - ss : '%d detik', - m : 'semenit', - mm : '%d menit', - h : 'sejam', - hh : '%d jam', - d : 'sehari', - dd : '%d hari', - M : 'sebulan', - MM : '%d bulan', - y : 'setahun', - yy : '%d tahun' + future : 'sa loob ng %s', + past : '%s ang nakalipas', + s : 'ilang segundo', + ss : '%d segundo', + m : 'isang minuto', + mm : '%d minuto', + h : 'isang oras', + hh : '%d oras', + d : 'isang araw', + dd : '%d araw', + M : 'isang buwan', + MM : '%d buwan', + y : 'isang taon', + yy : '%d taon' + }, + dayOfMonthOrdinalParse: /\d{1,2}/, + ordinal : function (number) { + return number; }, week : { dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. + doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return id; + return tlPh; }))); /***/ }), -/* 99 */ +/* 124 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - function plural(n) { - if (n % 100 === 11) { - return true; - } else if (n % 10 === 1) { - return false; - } - return true; + var numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_'); + + function translateFuture(output) { + var time = output; + time = (output.indexOf('jaj') !== -1) ? + time.slice(0, -3) + 'leS' : + (output.indexOf('jar') !== -1) ? + time.slice(0, -3) + 'waQ' : + (output.indexOf('DIS') !== -1) ? + time.slice(0, -3) + 'nem' : + time + ' pIq'; + return time; } - function translate(number, withoutSuffix, key, isFuture) { - var result = number + ' '; - switch (key) { - case 's': - return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum'; - case 'ss': - if (plural(number)) { - return result + (withoutSuffix || isFuture ? 'sekúndur' : 'sekúndum'); - } - return result + 'sekúnda'; - case 'm': - return withoutSuffix ? 'mínúta' : 'mínútu'; + + function translatePast(output) { + var time = output; + time = (output.indexOf('jaj') !== -1) ? + time.slice(0, -3) + 'Hu’' : + (output.indexOf('jar') !== -1) ? + time.slice(0, -3) + 'wen' : + (output.indexOf('DIS') !== -1) ? + time.slice(0, -3) + 'ben' : + time + ' ret'; + return time; + } + + function translate(number, withoutSuffix, string, isFuture) { + var numberNoun = numberAsNoun(number); + switch (string) { + case 'ss': + return numberNoun + ' lup'; case 'mm': - if (plural(number)) { - return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum'); - } else if (withoutSuffix) { - return result + 'mínúta'; - } - return result + 'mínútu'; + return numberNoun + ' tup'; case 'hh': - if (plural(number)) { - return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum'); - } - return result + 'klukkustund'; - case 'd': - if (withoutSuffix) { - return 'dagur'; - } - return isFuture ? 'dag' : 'degi'; + return numberNoun + ' rep'; case 'dd': - if (plural(number)) { - if (withoutSuffix) { - return result + 'dagar'; - } - return result + (isFuture ? 'daga' : 'dögum'); - } else if (withoutSuffix) { - return result + 'dagur'; - } - return result + (isFuture ? 'dag' : 'degi'); - case 'M': - if (withoutSuffix) { - return 'mánuður'; - } - return isFuture ? 'mánuð' : 'mánuði'; + return numberNoun + ' jaj'; case 'MM': - if (plural(number)) { - if (withoutSuffix) { - return result + 'mánuðir'; - } - return result + (isFuture ? 'mánuði' : 'mánuðum'); - } else if (withoutSuffix) { - return result + 'mánuður'; - } - return result + (isFuture ? 'mánuð' : 'mánuði'); - case 'y': - return withoutSuffix || isFuture ? 'ár' : 'ári'; + return numberNoun + ' jar'; case 'yy': - if (plural(number)) { - return result + (withoutSuffix || isFuture ? 'ár' : 'árum'); - } - return result + (withoutSuffix || isFuture ? 'ár' : 'ári'); + return numberNoun + ' DIS'; } } - var is = moment.defineLocale('is', { - months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'), - monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'), - weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'), - weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'), - weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'), + function numberAsNoun(number) { + var hundred = Math.floor((number % 1000) / 100), + ten = Math.floor((number % 100) / 10), + one = number % 10, + word = ''; + if (hundred > 0) { + word += numbersNouns[hundred] + 'vatlh'; + } + if (ten > 0) { + word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH'; + } + if (one > 0) { + word += ((word !== '') ? ' ' : '') + numbersNouns[one]; + } + return (word === '') ? 'pagh' : word; + } + + var tlh = moment.defineLocale('tlh', { + months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'), + monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'), + monthsParseExact : true, + weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), + weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), + weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', + LT : 'HH:mm', + LTS : 'HH:mm:ss', L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY [kl.] H:mm', - LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm' + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' }, calendar : { - sameDay : '[í dag kl.] LT', - nextDay : '[á morgun kl.] LT', - nextWeek : 'dddd [kl.] LT', - lastDay : '[í gær kl.] LT', - lastWeek : '[síðasta] dddd [kl.] LT', - sameElse : 'L' + sameDay: '[DaHjaj] LT', + nextDay: '[wa’leS] LT', + nextWeek: 'LLL', + lastDay: '[wa’Hu’] LT', + lastWeek: 'LLL', + sameElse: 'L' }, relativeTime : { - future : 'eftir %s', - past : 'fyrir %s síðan', - s : translate, + future : translateFuture, + past : translatePast, + s : 'puS lup', ss : translate, - m : translate, + m : 'wa’ tup', mm : translate, - h : 'klukkustund', + h : 'wa’ rep', hh : translate, - d : translate, + d : 'wa’ jaj', dd : translate, - M : translate, + M : 'wa’ jar', MM : translate, - y : translate, + y : 'wa’ DIS', yy : translate }, dayOfMonthOrdinalParse: /\d{1,2}\./, @@ -15308,32250 +16703,27327 @@ webpackContext.id = 41; } }); - return is; + return tlh; }))); /***/ }), -/* 100 */ +/* 125 */ /***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; + var suffixes = { + 1: '\'inci', + 5: '\'inci', + 8: '\'inci', + 70: '\'inci', + 80: '\'inci', + 2: '\'nci', + 7: '\'nci', + 20: '\'nci', + 50: '\'nci', + 3: '\'üncü', + 4: '\'üncü', + 100: '\'üncü', + 6: '\'ncı', + 9: '\'uncu', + 10: '\'uncu', + 30: '\'uncu', + 60: '\'ıncı', + 90: '\'ıncı' + }; - var it = moment.defineLocale('it', { - months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'), - monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'), - weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'), - weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'), - weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'), + var tr = moment.defineLocale('tr', { + months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'), + monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'), + weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'), + weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'), + weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'), longDateFormat : { LT : 'HH:mm', LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', + L : 'DD.MM.YYYY', LL : 'D MMMM YYYY', LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' + LLLL : 'dddd, D MMMM YYYY HH:mm' }, calendar : { - sameDay: '[Oggi alle] LT', - nextDay: '[Domani alle] LT', - nextWeek: 'dddd [alle] LT', - lastDay: '[Ieri alle] LT', - lastWeek: function () { - switch (this.day()) { - case 0: - return '[la scorsa] dddd [alle] LT'; - default: - return '[lo scorso] dddd [alle] LT'; - } - }, - sameElse: 'L' + sameDay : '[bugün saat] LT', + nextDay : '[yarın saat] LT', + nextWeek : '[gelecek] dddd [saat] LT', + lastDay : '[dün] LT', + lastWeek : '[geçen] dddd [saat] LT', + sameElse : 'L' }, relativeTime : { - future : function (s) { - return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s; - }, - past : '%s fa', - s : 'alcuni secondi', - ss : '%d secondi', - m : 'un minuto', - mm : '%d minuti', - h : 'un\'ora', - hh : '%d ore', - d : 'un giorno', - dd : '%d giorni', - M : 'un mese', - MM : '%d mesi', - y : 'un anno', - yy : '%d anni' + future : '%s sonra', + past : '%s önce', + s : 'birkaç saniye', + ss : '%d saniye', + m : 'bir dakika', + mm : '%d dakika', + h : 'bir saat', + hh : '%d saat', + d : 'bir gün', + dd : '%d gün', + M : 'bir ay', + MM : '%d ay', + y : 'bir yıl', + yy : '%d yıl' + }, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'Do': + case 'DD': + return number; + default: + if (number === 0) { // special case for zero + return number + '\'ıncı'; + } + var a = number % 10, + b = number % 100 - a, + c = number >= 100 ? 100 : null; + return number + (suffixes[a] || suffixes[b] || suffixes[c]); + } }, - dayOfMonthOrdinalParse : /\d{1,2}º/, - ordinal: '%dº', week : { dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + doy : 7 // The week that contains Jan 7th is the first week of the year. } }); - return it; + return tr; }))); /***/ }), -/* 101 */ +/* 126 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var itCh = moment.defineLocale('it-ch', { - months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'), - monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'), - weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'), - weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'), - weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'), + // After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals. + // This is currently too difficult (maybe even impossible) to add. + var tzl = moment.defineLocale('tzl', { + months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'), + monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'), + weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'), + weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'), + weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'), longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', + LT : 'HH.mm', + LTS : 'HH.mm.ss', L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' + LL : 'D. MMMM [dallas] YYYY', + LLL : 'D. MMMM [dallas] YYYY HH.mm', + LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm' + }, + meridiemParse: /d\'o|d\'a/i, + isPM : function (input) { + return 'd\'o' === input.toLowerCase(); + }, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'd\'o' : 'D\'O'; + } else { + return isLower ? 'd\'a' : 'D\'A'; + } }, calendar : { - sameDay: '[Oggi alle] LT', - nextDay: '[Domani alle] LT', - nextWeek: 'dddd [alle] LT', - lastDay: '[Ieri alle] LT', - lastWeek: function () { - switch (this.day()) { - case 0: - return '[la scorsa] dddd [alle] LT'; - default: - return '[lo scorso] dddd [alle] LT'; - } - }, - sameElse: 'L' + sameDay : '[oxhi à] LT', + nextDay : '[demà à] LT', + nextWeek : 'dddd [à] LT', + lastDay : '[ieiri à] LT', + lastWeek : '[sür el] dddd [lasteu à] LT', + sameElse : 'L' }, relativeTime : { - future : function (s) { - return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s; - }, - past : '%s fa', - s : 'alcuni secondi', - ss : '%d secondi', - m : 'un minuto', - mm : '%d minuti', - h : 'un\'ora', - hh : '%d ore', - d : 'un giorno', - dd : '%d giorni', - M : 'un mese', - MM : '%d mesi', - y : 'un anno', - yy : '%d anni' + future : 'osprei %s', + past : 'ja%s', + s : processRelativeTime, + ss : processRelativeTime, + m : processRelativeTime, + mm : processRelativeTime, + h : processRelativeTime, + hh : processRelativeTime, + d : processRelativeTime, + dd : processRelativeTime, + M : processRelativeTime, + MM : processRelativeTime, + y : processRelativeTime, + yy : processRelativeTime }, - dayOfMonthOrdinalParse : /\d{1,2}º/, - ordinal: '%dº', + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal : '%d.', week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return itCh; + function processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 's': ['viensas secunds', '\'iensas secunds'], + 'ss': [number + ' secunds', '' + number + ' secunds'], + 'm': ['\'n míut', '\'iens míut'], + 'mm': [number + ' míuts', '' + number + ' míuts'], + 'h': ['\'n þora', '\'iensa þora'], + 'hh': [number + ' þoras', '' + number + ' þoras'], + 'd': ['\'n ziua', '\'iensa ziua'], + 'dd': [number + ' ziuas', '' + number + ' ziuas'], + 'M': ['\'n mes', '\'iens mes'], + 'MM': [number + ' mesen', '' + number + ' mesen'], + 'y': ['\'n ar', '\'iens ar'], + 'yy': [number + ' ars', '' + number + ' ars'] + }; + return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]); + } + + return tzl; }))); /***/ }), -/* 102 */ +/* 127 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var ja = moment.defineLocale('ja', { - months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), - monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), - weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'), - weekdaysShort : '日_月_火_水_木_金_土'.split('_'), - weekdaysMin : '日_月_火_水_木_金_土'.split('_'), + var tzm = moment.defineLocale('tzm', { + months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), + monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), + weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), longDateFormat : { LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY/MM/DD', - LL : 'YYYY年M月D日', - LLL : 'YYYY年M月D日 HH:mm', - LLLL : 'YYYY年M月D日 dddd HH:mm', - l : 'YYYY/MM/DD', - ll : 'YYYY年M月D日', - lll : 'YYYY年M月D日 HH:mm', - llll : 'YYYY年M月D日(ddd) HH:mm' - }, - meridiemParse: /午前|午後/i, - isPM : function (input) { - return input === '午後'; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return '午前'; - } else { - return '午後'; - } + LTS: 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' }, calendar : { - sameDay : '[今日] LT', - nextDay : '[明日] LT', - nextWeek : function (now) { - if (now.week() < this.week()) { - return '[来週]dddd LT'; - } else { - return 'dddd LT'; - } - }, - lastDay : '[昨日] LT', - lastWeek : function (now) { - if (this.week() < now.week()) { - return '[先週]dddd LT'; - } else { - return 'dddd LT'; - } - }, - sameElse : 'L' - }, - dayOfMonthOrdinalParse : /\d{1,2}日/, - ordinal : function (number, period) { - switch (period) { - case 'd': - case 'D': - case 'DDD': - return number + '日'; - default: - return number; - } + sameDay: '[ⴰⵙⴷⵅ ⴴ] LT', + nextDay: '[ⴰⵙⴽⴰ ⴴ] LT', + nextWeek: 'dddd [ⴴ] LT', + lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT', + lastWeek: 'dddd [ⴴ] LT', + sameElse: 'L' }, relativeTime : { - future : '%s後', - past : '%s前', - s : '数秒', - ss : '%d秒', - m : '1分', - mm : '%d分', - h : '1時間', - hh : '%d時間', - d : '1日', - dd : '%d日', - M : '1ヶ月', - MM : '%dヶ月', - y : '1年', - yy : '%d年' + future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s', + past : 'ⵢⴰⵏ %s', + s : 'ⵉⵎⵉⴽ', + ss : '%d ⵉⵎⵉⴽ', + m : 'ⵎⵉⵏⵓⴺ', + mm : '%d ⵎⵉⵏⵓⴺ', + h : 'ⵙⴰⵄⴰ', + hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ', + d : 'ⴰⵙⵙ', + dd : '%d oⵙⵙⴰⵏ', + M : 'ⴰⵢoⵓⵔ', + MM : '%d ⵉⵢⵢⵉⵔⵏ', + y : 'ⴰⵙⴳⴰⵙ', + yy : '%d ⵉⵙⴳⴰⵙⵏ' + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 12th is the first week of the year. } }); - return ja; + return tzm; }))); /***/ }), -/* 103 */ +/* 128 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var jv = moment.defineLocale('jv', { - months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'), - weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'), - weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'), - weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'), + var tzmLatn = moment.defineLocale('tzm-latn', { + months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), + monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), + weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), longDateFormat : { - LT : 'HH.mm', - LTS : 'HH.mm.ss', + LT : 'HH:mm', + LTS : 'HH:mm:ss', L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY [pukul] HH.mm', - LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' }, - meridiemParse: /enjing|siyang|sonten|ndalu/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'enjing') { - return hour; - } else if (meridiem === 'siyang') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === 'sonten' || meridiem === 'ndalu') { - return hour + 12; - } + calendar : { + sameDay: '[asdkh g] LT', + nextDay: '[aska g] LT', + nextWeek: 'dddd [g] LT', + lastDay: '[assant g] LT', + lastWeek: 'dddd [g] LT', + sameElse: 'L' }, - meridiem : function (hours, minutes, isLower) { - if (hours < 11) { - return 'enjing'; - } else if (hours < 15) { - return 'siyang'; - } else if (hours < 19) { - return 'sonten'; + relativeTime : { + future : 'dadkh s yan %s', + past : 'yan %s', + s : 'imik', + ss : '%d imik', + m : 'minuḍ', + mm : '%d minuḍ', + h : 'saɛa', + hh : '%d tassaɛin', + d : 'ass', + dd : '%d ossan', + M : 'ayowr', + MM : '%d iyyirn', + y : 'asgas', + yy : '%d isgasn' + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 12th is the first week of the year. + } + }); + + return tzmLatn; + +}))); + + +/***/ }), +/* 129 */ +/***/ (function(module, exports, __webpack_require__) { + +//! moment.js language configuration + +;(function (global, factory) { + true ? factory(__webpack_require__(10)) : + undefined +}(this, (function (moment) { 'use strict'; + + + var ugCn = moment.defineLocale('ug-cn', { + months: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split( + '_' + ), + monthsShort: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split( + '_' + ), + weekdays: 'يەكشەنبە_دۈشەنبە_سەيشەنبە_چارشەنبە_پەيشەنبە_جۈمە_شەنبە'.split( + '_' + ), + weekdaysShort: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'), + weekdaysMin: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'YYYY-MM-DD', + LL: 'YYYY-يىلىM-ئاينىڭD-كۈنى', + LLL: 'YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm', + LLLL: 'dddd، YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm' + }, + meridiemParse: /يېرىم كېچە|سەھەر|چۈشتىن بۇرۇن|چۈش|چۈشتىن كېيىن|كەچ/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ( + meridiem === 'يېرىم كېچە' || + meridiem === 'سەھەر' || + meridiem === 'چۈشتىن بۇرۇن' + ) { + return hour; + } else if (meridiem === 'چۈشتىن كېيىن' || meridiem === 'كەچ') { + return hour + 12; } else { - return 'ndalu'; + return hour >= 11 ? hour : hour + 12; } }, - calendar : { - sameDay : '[Dinten puniko pukul] LT', - nextDay : '[Mbenjang pukul] LT', - nextWeek : 'dddd [pukul] LT', - lastDay : '[Kala wingi pukul] LT', - lastWeek : 'dddd [kepengker pukul] LT', - sameElse : 'L' + meridiem: function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return 'يېرىم كېچە'; + } else if (hm < 900) { + return 'سەھەر'; + } else if (hm < 1130) { + return 'چۈشتىن بۇرۇن'; + } else if (hm < 1230) { + return 'چۈش'; + } else if (hm < 1800) { + return 'چۈشتىن كېيىن'; + } else { + return 'كەچ'; + } }, - relativeTime : { - future : 'wonten ing %s', - past : '%s ingkang kepengker', - s : 'sawetawis detik', - ss : '%d detik', - m : 'setunggal menit', - mm : '%d menit', - h : 'setunggal jam', - hh : '%d jam', - d : 'sedinten', - dd : '%d dinten', - M : 'sewulan', - MM : '%d wulan', - y : 'setaun', - yy : '%d taun' + calendar: { + sameDay: '[بۈگۈن سائەت] LT', + nextDay: '[ئەتە سائەت] LT', + nextWeek: '[كېلەركى] dddd [سائەت] LT', + lastDay: '[تۆنۈگۈن] LT', + lastWeek: '[ئالدىنقى] dddd [سائەت] LT', + sameElse: 'L' }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. + relativeTime: { + future: '%s كېيىن', + past: '%s بۇرۇن', + s: 'نەچچە سېكونت', + ss: '%d سېكونت', + m: 'بىر مىنۇت', + mm: '%d مىنۇت', + h: 'بىر سائەت', + hh: '%d سائەت', + d: 'بىر كۈن', + dd: '%d كۈن', + M: 'بىر ئاي', + MM: '%d ئاي', + y: 'بىر يىل', + yy: '%d يىل' + }, + + dayOfMonthOrdinalParse: /\d{1,2}(-كۈنى|-ئاي|-ھەپتە)/, + ordinal: function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '-كۈنى'; + case 'w': + case 'W': + return number + '-ھەپتە'; + default: + return number; + } + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week: { + // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 + dow: 1, // Monday is the first day of the week. + doy: 7 // The week that contains Jan 1st is the first week of the year. } }); - return jv; + return ugCn; }))); /***/ }), -/* 104 */ +/* 130 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var ka = moment.defineLocale('ka', { + function plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); + } + function relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'ss': withoutSuffix ? 'секунда_секунди_секунд' : 'секунду_секунди_секунд', + 'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин', + 'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин', + 'dd': 'день_дні_днів', + 'MM': 'місяць_місяці_місяців', + 'yy': 'рік_роки_років' + }; + if (key === 'm') { + return withoutSuffix ? 'хвилина' : 'хвилину'; + } + else if (key === 'h') { + return withoutSuffix ? 'година' : 'годину'; + } + else { + return number + ' ' + plural(format[key], +number); + } + } + function weekdaysCaseReplace(m, format) { + var weekdays = { + 'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'), + 'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'), + 'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_') + }; + + if (m === true) { + return weekdays['nominative'].slice(1, 7).concat(weekdays['nominative'].slice(0, 1)); + } + if (!m) { + return weekdays['nominative']; + } + + var nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ? + 'accusative' : + ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ? + 'genitive' : + 'nominative'); + return weekdays[nounCase][m.day()]; + } + function processHoursFunction(str) { + return function () { + return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT'; + }; + } + + var uk = moment.defineLocale('uk', { months : { - standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'), - format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_') - }, - monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'), - weekdays : { - standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'), - format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'), - isFormat: /(წინა|შემდეგ)/ + 'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'), + 'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_') }, - weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'), - weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'), + monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'), + weekdays : weekdaysCaseReplace, + weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), + weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY h:mm A', - LLLL : 'dddd, D MMMM YYYY h:mm A' + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY р.', + LLL : 'D MMMM YYYY р., HH:mm', + LLLL : 'dddd, D MMMM YYYY р., HH:mm' }, calendar : { - sameDay : '[დღეს] LT[-ზე]', - nextDay : '[ხვალ] LT[-ზე]', - lastDay : '[გუშინ] LT[-ზე]', - nextWeek : '[შემდეგ] dddd LT[-ზე]', - lastWeek : '[წინა] dddd LT-ზე', - sameElse : 'L' - }, - relativeTime : { - future : function (s) { - return (/(წამი|წუთი|საათი|წელი)/).test(s) ? - s.replace(/ი$/, 'ში') : - s + 'ში'; - }, - past : function (s) { - if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) { - return s.replace(/(ი|ე)$/, 'ის წინ'); - } - if ((/წელი/).test(s)) { - return s.replace(/წელი$/, 'წლის წინ'); + sameDay: processHoursFunction('[Сьогодні '), + nextDay: processHoursFunction('[Завтра '), + lastDay: processHoursFunction('[Вчора '), + nextWeek: processHoursFunction('[У] dddd ['), + lastWeek: function () { + switch (this.day()) { + case 0: + case 3: + case 5: + case 6: + return processHoursFunction('[Минулої] dddd [').call(this); + case 1: + case 2: + case 4: + return processHoursFunction('[Минулого] dddd [').call(this); } }, - s : 'რამდენიმე წამი', - ss : '%d წამი', - m : 'წუთი', - mm : '%d წუთი', - h : 'საათი', - hh : '%d საათი', - d : 'დღე', - dd : '%d დღე', - M : 'თვე', - MM : '%d თვე', - y : 'წელი', - yy : '%d წელი' + sameElse: 'L' }, - dayOfMonthOrdinalParse: /0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/, - ordinal : function (number) { - if (number === 0) { - return number; - } - if (number === 1) { - return number + '-ლი'; + relativeTime : { + future : 'за %s', + past : '%s тому', + s : 'декілька секунд', + ss : relativeTimeWithPlural, + m : relativeTimeWithPlural, + mm : relativeTimeWithPlural, + h : 'годину', + hh : relativeTimeWithPlural, + d : 'день', + dd : relativeTimeWithPlural, + M : 'місяць', + MM : relativeTimeWithPlural, + y : 'рік', + yy : relativeTimeWithPlural + }, + // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason + meridiemParse: /ночі|ранку|дня|вечора/, + isPM: function (input) { + return /^(дня|вечора)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ночі'; + } else if (hour < 12) { + return 'ранку'; + } else if (hour < 17) { + return 'дня'; + } else { + return 'вечора'; } - if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) { - return 'მე-' + number; + }, + dayOfMonthOrdinalParse: /\d{1,2}-(й|го)/, + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + case 'w': + case 'W': + return number + '-й'; + case 'D': + return number + '-го'; + default: + return number; } - return number + '-ე'; }, week : { - dow : 1, - doy : 7 + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. } }); - return ka; + return uk; }))); /***/ }), -/* 105 */ +/* 131 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var suffixes = { - 0: '-ші', - 1: '-ші', - 2: '-ші', - 3: '-ші', - 4: '-ші', - 5: '-ші', - 6: '-шы', - 7: '-ші', - 8: '-ші', - 9: '-шы', - 10: '-шы', - 20: '-шы', - 30: '-шы', - 40: '-шы', - 50: '-ші', - 60: '-шы', - 70: '-ші', - 80: '-ші', - 90: '-шы', - 100: '-ші' - }; + var months = [ + 'جنوری', + 'فروری', + 'مارچ', + 'اپریل', + 'مئی', + 'جون', + 'جولائی', + 'اگست', + 'ستمبر', + 'اکتوبر', + 'نومبر', + 'دسمبر' + ]; + var days = [ + 'اتوار', + 'پیر', + 'منگل', + 'بدھ', + 'جمعرات', + 'جمعہ', + 'ہفتہ' + ]; - var kk = moment.defineLocale('kk', { - months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'), - monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'), - weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'), - weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'), - weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'), + var ur = moment.defineLocale('ur', { + months : months, + monthsShort : months, + weekdays : days, + weekdaysShort : days, + weekdaysMin : days, longDateFormat : { LT : 'HH:mm', LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', + L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' + LLLL : 'dddd، D MMMM YYYY HH:mm' + }, + meridiemParse: /صبح|شام/, + isPM : function (input) { + return 'شام' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'صبح'; + } + return 'شام'; }, calendar : { - sameDay : '[Бүгін сағат] LT', - nextDay : '[Ертең сағат] LT', - nextWeek : 'dddd [сағат] LT', - lastDay : '[Кеше сағат] LT', - lastWeek : '[Өткен аптаның] dddd [сағат] LT', + sameDay : '[آج بوقت] LT', + nextDay : '[کل بوقت] LT', + nextWeek : 'dddd [بوقت] LT', + lastDay : '[گذشتہ روز بوقت] LT', + lastWeek : '[گذشتہ] dddd [بوقت] LT', sameElse : 'L' }, relativeTime : { - future : '%s ішінде', - past : '%s бұрын', - s : 'бірнеше секунд', - ss : '%d секунд', - m : 'бір минут', - mm : '%d минут', - h : 'бір сағат', - hh : '%d сағат', - d : 'бір күн', - dd : '%d күн', - M : 'бір ай', - MM : '%d ай', - y : 'бір жыл', - yy : '%d жыл' + future : '%s بعد', + past : '%s قبل', + s : 'چند سیکنڈ', + ss : '%d سیکنڈ', + m : 'ایک منٹ', + mm : '%d منٹ', + h : 'ایک گھنٹہ', + hh : '%d گھنٹے', + d : 'ایک دن', + dd : '%d دن', + M : 'ایک ماہ', + MM : '%d ماہ', + y : 'ایک سال', + yy : '%d سال' }, - dayOfMonthOrdinalParse: /\d{1,2}-(ші|шы)/, - ordinal : function (number) { - var a = number % 10, - b = number >= 100 ? 100 : null; - return number + (suffixes[number] || suffixes[a] || suffixes[b]); + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); }, week : { dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. + doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return kk; + return ur; }))); /***/ }), -/* 106 */ +/* 132 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var symbolMap = { - '1': '១', - '2': '២', - '3': '៣', - '4': '៤', - '5': '៥', - '6': '៦', - '7': '៧', - '8': '៨', - '9': '៩', - '0': '០' - }, numberMap = { - '១': '1', - '២': '2', - '៣': '3', - '៤': '4', - '៥': '5', - '៦': '6', - '៧': '7', - '៨': '8', - '៩': '9', - '០': '0' - }; - - var km = moment.defineLocale('km', { - months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split( - '_' - ), - monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split( - '_' - ), - weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'), - weekdaysShort: 'អា_ច_អ_ព_ព្រ_សុ_ស'.split('_'), - weekdaysMin: 'អា_ច_អ_ព_ព្រ_សុ_ស'.split('_'), - weekdaysParseExact: true, - longDateFormat: { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY HH:mm', - LLLL: 'dddd, D MMMM YYYY HH:mm' - }, - meridiemParse: /ព្រឹក|ល្ងាច/, - isPM: function (input) { - return input === 'ល្ងាច'; - }, - meridiem: function (hour, minute, isLower) { - if (hour < 12) { - return 'ព្រឹក'; - } else { - return 'ល្ងាច'; - } - }, - calendar: { - sameDay: '[ថ្ងៃនេះ ម៉ោង] LT', - nextDay: '[ស្អែក ម៉ោង] LT', - nextWeek: 'dddd [ម៉ោង] LT', - lastDay: '[ម្សិលមិញ ម៉ោង] LT', - lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT', - sameElse: 'L' - }, - relativeTime: { - future: '%sទៀត', - past: '%sមុន', - s: 'ប៉ុន្មានវិនាទី', - ss: '%d វិនាទី', - m: 'មួយនាទី', - mm: '%d នាទី', - h: 'មួយម៉ោង', - hh: '%d ម៉ោង', - d: 'មួយថ្ងៃ', - dd: '%d ថ្ងៃ', - M: 'មួយខែ', - MM: '%d ខែ', - y: 'មួយឆ្នាំ', - yy: '%d ឆ្នាំ' + var uz = moment.defineLocale('uz', { + months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'), + monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'), + weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'), + weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'), + weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'D MMMM YYYY, dddd HH:mm' }, - dayOfMonthOrdinalParse : /ទី\d{1,2}/, - ordinal : 'ទី%d', - preparse: function (string) { - return string.replace(/[១២៣៤៥៦៧៨៩០]/g, function (match) { - return numberMap[match]; - }); + calendar : { + sameDay : '[Бугун соат] LT [да]', + nextDay : '[Эртага] LT [да]', + nextWeek : 'dddd [куни соат] LT [да]', + lastDay : '[Кеча соат] LT [да]', + lastWeek : '[Утган] dddd [куни соат] LT [да]', + sameElse : 'L' }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); + relativeTime : { + future : 'Якин %s ичида', + past : 'Бир неча %s олдин', + s : 'фурсат', + ss : '%d фурсат', + m : 'бир дакика', + mm : '%d дакика', + h : 'бир соат', + hh : '%d соат', + d : 'бир кун', + dd : '%d кун', + M : 'бир ой', + MM : '%d ой', + y : 'бир йил', + yy : '%d йил' }, - week: { - dow: 1, // Monday is the first day of the week. - doy: 4 // The week that contains Jan 4th is the first week of the year. + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 4th is the first week of the year. } }); - return km; + return uz; }))); /***/ }), -/* 107 */ +/* 133 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var symbolMap = { - '1': '೧', - '2': '೨', - '3': '೩', - '4': '೪', - '5': '೫', - '6': '೬', - '7': '೭', - '8': '೮', - '9': '೯', - '0': '೦' - }, - numberMap = { - '೧': '1', - '೨': '2', - '೩': '3', - '೪': '4', - '೫': '5', - '೬': '6', - '೭': '7', - '೮': '8', - '೯': '9', - '೦': '0' - }; - - var kn = moment.defineLocale('kn', { - months : 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split('_'), - monthsShort : 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂ_ಅಕ್ಟೋ_ನವೆಂ_ಡಿಸೆಂ'.split('_'), - monthsParseExact: true, - weekdays : 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split('_'), - weekdaysShort : 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'), - weekdaysMin : 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'), + var uzLatn = moment.defineLocale('uz-latn', { + months : 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split('_'), + monthsShort : 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'), + weekdays : 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split('_'), + weekdaysShort : 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'), + weekdaysMin : 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'), longDateFormat : { - LT : 'A h:mm', - LTS : 'A h:mm:ss', + LT : 'HH:mm', + LTS : 'HH:mm:ss', L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm', - LLLL : 'dddd, D MMMM YYYY, A h:mm' + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'D MMMM YYYY, dddd HH:mm' }, calendar : { - sameDay : '[ಇಂದು] LT', - nextDay : '[ನಾಳೆ] LT', - nextWeek : 'dddd, LT', - lastDay : '[ನಿನ್ನೆ] LT', - lastWeek : '[ಕೊನೆಯ] dddd, LT', + sameDay : '[Bugun soat] LT [da]', + nextDay : '[Ertaga] LT [da]', + nextWeek : 'dddd [kuni soat] LT [da]', + lastDay : '[Kecha soat] LT [da]', + lastWeek : '[O\'tgan] dddd [kuni soat] LT [da]', sameElse : 'L' }, relativeTime : { - future : '%s ನಂತರ', - past : '%s ಹಿಂದೆ', - s : 'ಕೆಲವು ಕ್ಷಣಗಳು', - ss : '%d ಸೆಕೆಂಡುಗಳು', - m : 'ಒಂದು ನಿಮಿಷ', - mm : '%d ನಿಮಿಷ', - h : 'ಒಂದು ಗಂಟೆ', - hh : '%d ಗಂಟೆ', - d : 'ಒಂದು ದಿನ', - dd : '%d ದಿನ', - M : 'ಒಂದು ತಿಂಗಳು', - MM : '%d ತಿಂಗಳು', - y : 'ಒಂದು ವರ್ಷ', - yy : '%d ವರ್ಷ' - }, - preparse: function (string) { - return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); - }, - meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'ರಾತ್ರಿ') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') { - return hour; - } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') { - return hour >= 10 ? hour : hour + 12; - } else if (meridiem === 'ಸಂಜೆ') { - return hour + 12; - } - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'ರಾತ್ರಿ'; - } else if (hour < 10) { - return 'ಬೆಳಿಗ್ಗೆ'; - } else if (hour < 17) { - return 'ಮಧ್ಯಾಹ್ನ'; - } else if (hour < 20) { - return 'ಸಂಜೆ'; - } else { - return 'ರಾತ್ರಿ'; - } - }, - dayOfMonthOrdinalParse: /\d{1,2}(ನೇ)/, - ordinal : function (number) { - return number + 'ನೇ'; + future : 'Yaqin %s ichida', + past : 'Bir necha %s oldin', + s : 'soniya', + ss : '%d soniya', + m : 'bir daqiqa', + mm : '%d daqiqa', + h : 'bir soat', + hh : '%d soat', + d : 'bir kun', + dd : '%d kun', + M : 'bir oy', + MM : '%d oy', + y : 'bir yil', + yy : '%d yil' }, week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 7th is the first week of the year. } }); - return kn; + return uzLatn; }))); /***/ }), -/* 108 */ +/* 134 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var ko = moment.defineLocale('ko', { - months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), - monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), - weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'), - weekdaysShort : '일_월_화_수_목_금_토'.split('_'), - weekdaysMin : '일_월_화_수_목_금_토'.split('_'), + var vi = moment.defineLocale('vi', { + months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'), + monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'), + monthsParseExact : true, + weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'), + weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), + weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), + weekdaysParseExact : true, + meridiemParse: /sa|ch/i, + isPM : function (input) { + return /^ch$/i.test(input); + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 12) { + return isLower ? 'sa' : 'SA'; + } else { + return isLower ? 'ch' : 'CH'; + } + }, longDateFormat : { - LT : 'A h:mm', - LTS : 'A h:mm:ss', - L : 'YYYY.MM.DD.', - LL : 'YYYY년 MMMM D일', - LLL : 'YYYY년 MMMM D일 A h:mm', - LLLL : 'YYYY년 MMMM D일 dddd A h:mm', - l : 'YYYY.MM.DD.', - ll : 'YYYY년 MMMM D일', - lll : 'YYYY년 MMMM D일 A h:mm', - llll : 'YYYY년 MMMM D일 dddd A h:mm' + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM [năm] YYYY', + LLL : 'D MMMM [năm] YYYY HH:mm', + LLLL : 'dddd, D MMMM [năm] YYYY HH:mm', + l : 'DD/M/YYYY', + ll : 'D MMM YYYY', + lll : 'D MMM YYYY HH:mm', + llll : 'ddd, D MMM YYYY HH:mm' }, calendar : { - sameDay : '오늘 LT', - nextDay : '내일 LT', - nextWeek : 'dddd LT', - lastDay : '어제 LT', - lastWeek : '지난주 dddd LT', - sameElse : 'L' + sameDay: '[Hôm nay lúc] LT', + nextDay: '[Ngày mai lúc] LT', + nextWeek: 'dddd [tuần tới lúc] LT', + lastDay: '[Hôm qua lúc] LT', + lastWeek: 'dddd [tuần rồi lúc] LT', + sameElse: 'L' }, relativeTime : { - future : '%s 후', - past : '%s 전', - s : '몇 초', - ss : '%d초', - m : '1분', - mm : '%d분', - h : '한 시간', - hh : '%d시간', - d : '하루', - dd : '%d일', - M : '한 달', - MM : '%d달', - y : '일 년', - yy : '%d년' - }, - dayOfMonthOrdinalParse : /\d{1,2}(일|월|주)/, - ordinal : function (number, period) { - switch (period) { - case 'd': - case 'D': - case 'DDD': - return number + '일'; - case 'M': - return number + '월'; - case 'w': - case 'W': - return number + '주'; - default: - return number; - } + future : '%s tới', + past : '%s trước', + s : 'vài giây', + ss : '%d giây' , + m : 'một phút', + mm : '%d phút', + h : 'một giờ', + hh : '%d giờ', + d : 'một ngày', + dd : '%d ngày', + M : 'một tháng', + MM : '%d tháng', + y : 'một năm', + yy : '%d năm' }, - meridiemParse : /오전|오후/, - isPM : function (token) { - return token === '오후'; + dayOfMonthOrdinalParse: /\d{1,2}/, + ordinal : function (number) { + return number; }, - meridiem : function (hour, minute, isUpper) { - return hour < 12 ? '오전' : '오후'; + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return ko; + return vi; }))); /***/ }), -/* 109 */ +/* 135 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var symbolMap = { - '1': '١', - '2': '٢', - '3': '٣', - '4': '٤', - '5': '٥', - '6': '٦', - '7': '٧', - '8': '٨', - '9': '٩', - '0': '٠' - }, numberMap = { - '١': '1', - '٢': '2', - '٣': '3', - '٤': '4', - '٥': '5', - '٦': '6', - '٧': '7', - '٨': '8', - '٩': '9', - '٠': '0' - }, - months = [ - 'کانونی دووەم', - 'شوبات', - 'ئازار', - 'نیسان', - 'ئایار', - 'حوزەیران', - 'تەمموز', - 'ئاب', - 'ئەیلوول', - 'تشرینی یەكەم', - 'تشرینی دووەم', - 'كانونی یەکەم' - ]; - - - var ku = moment.defineLocale('ku', { - months : months, - monthsShort : months, - weekdays : 'یه‌كشه‌ممه‌_دووشه‌ممه‌_سێشه‌ممه‌_چوارشه‌ممه‌_پێنجشه‌ممه‌_هه‌ینی_شه‌ممه‌'.split('_'), - weekdaysShort : 'یه‌كشه‌م_دووشه‌م_سێشه‌م_چوارشه‌م_پێنجشه‌م_هه‌ینی_شه‌ممه‌'.split('_'), - weekdaysMin : 'ی_د_س_چ_پ_ه_ش'.split('_'), + var xPseudo = moment.defineLocale('x-pseudo', { + months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'), + monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'), + monthsParseExact : true, + weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'), + weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'), + weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'), weekdaysParseExact : true, longDateFormat : { LT : 'HH:mm', - LTS : 'HH:mm:ss', L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', LLL : 'D MMMM YYYY HH:mm', LLLL : 'dddd, D MMMM YYYY HH:mm' }, - meridiemParse: /ئێواره‌|به‌یانی/, - isPM: function (input) { - return /ئێواره‌/.test(input); - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'به‌یانی'; - } else { - return 'ئێواره‌'; - } - }, calendar : { - sameDay : '[ئه‌مرۆ كاتژمێر] LT', - nextDay : '[به‌یانی كاتژمێر] LT', - nextWeek : 'dddd [كاتژمێر] LT', - lastDay : '[دوێنێ كاتژمێر] LT', - lastWeek : 'dddd [كاتژمێر] LT', + sameDay : '[T~ódá~ý át] LT', + nextDay : '[T~ómó~rró~w át] LT', + nextWeek : 'dddd [át] LT', + lastDay : '[Ý~ést~érdá~ý át] LT', + lastWeek : '[L~ást] dddd [át] LT', sameElse : 'L' }, relativeTime : { - future : 'له‌ %s', - past : '%s', - s : 'چه‌ند چركه‌یه‌ك', - ss : 'چركه‌ %d', - m : 'یه‌ك خوله‌ك', - mm : '%d خوله‌ك', - h : 'یه‌ك كاتژمێر', - hh : '%d كاتژمێر', - d : 'یه‌ك ڕۆژ', - dd : '%d ڕۆژ', - M : 'یه‌ك مانگ', - MM : '%d مانگ', - y : 'یه‌ك ساڵ', - yy : '%d ساڵ' - }, - preparse: function (string) { - return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { - return numberMap[match]; - }).replace(/،/g, ','); + future : 'í~ñ %s', + past : '%s á~gó', + s : 'á ~féw ~sécó~ñds', + ss : '%d s~écóñ~ds', + m : 'á ~míñ~úté', + mm : '%d m~íñú~tés', + h : 'á~ñ hó~úr', + hh : '%d h~óúrs', + d : 'á ~dáý', + dd : '%d d~áýs', + M : 'á ~móñ~th', + MM : '%d m~óñt~hs', + y : 'á ~ýéár', + yy : '%d ý~éárs' }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }).replace(/,/g, '،'); + dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; }, week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return ku; + return xPseudo; }))); /***/ }), -/* 110 */ +/* 136 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var suffixes = { - 0: '-чү', - 1: '-чи', - 2: '-чи', - 3: '-чү', - 4: '-чү', - 5: '-чи', - 6: '-чы', - 7: '-чи', - 8: '-чи', - 9: '-чу', - 10: '-чу', - 20: '-чы', - 30: '-чу', - 40: '-чы', - 50: '-чү', - 60: '-чы', - 70: '-чи', - 80: '-чи', - 90: '-чу', - 100: '-чү' - }; - - var ky = moment.defineLocale('ky', { - months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'), - monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'), - weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'), - weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'), - weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', + var yo = moment.defineLocale('yo', { + months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'), + monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'), + weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'), + weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'), + weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' }, calendar : { - sameDay : '[Бүгүн саат] LT', - nextDay : '[Эртең саат] LT', - nextWeek : 'dddd [саат] LT', - lastDay : '[Кечээ саат] LT', - lastWeek : '[Өткөн аптанын] dddd [күнү] [саат] LT', + sameDay : '[Ònì ni] LT', + nextDay : '[Ọ̀la ni] LT', + nextWeek : 'dddd [Ọsẹ̀ tón\'bọ] [ni] LT', + lastDay : '[Àna ni] LT', + lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT', sameElse : 'L' }, relativeTime : { - future : '%s ичинде', - past : '%s мурун', - s : 'бирнече секунд', - ss : '%d секунд', - m : 'бир мүнөт', - mm : '%d мүнөт', - h : 'бир саат', - hh : '%d саат', - d : 'бир күн', - dd : '%d күн', - M : 'бир ай', - MM : '%d ай', - y : 'бир жыл', - yy : '%d жыл' - }, - dayOfMonthOrdinalParse: /\d{1,2}-(чи|чы|чү|чу)/, - ordinal : function (number) { - var a = number % 10, - b = number >= 100 ? 100 : null; - return number + (suffixes[number] || suffixes[a] || suffixes[b]); + future : 'ní %s', + past : '%s kọjá', + s : 'ìsẹjú aayá die', + ss :'aayá %d', + m : 'ìsẹjú kan', + mm : 'ìsẹjú %d', + h : 'wákati kan', + hh : 'wákati %d', + d : 'ọjọ́ kan', + dd : 'ọjọ́ %d', + M : 'osù kan', + MM : 'osù %d', + y : 'ọdún kan', + yy : 'ọdún %d' }, + dayOfMonthOrdinalParse : /ọjọ́\s\d{1,2}/, + ordinal : 'ọjọ́ %d', week : { dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. + doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return ky; + return yo; }))); /***/ }), -/* 111 */ +/* 137 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - function processRelativeTime(number, withoutSuffix, key, isFuture) { - var format = { - 'm': ['eng Minutt', 'enger Minutt'], - 'h': ['eng Stonn', 'enger Stonn'], - 'd': ['een Dag', 'engem Dag'], - 'M': ['ee Mount', 'engem Mount'], - 'y': ['ee Joer', 'engem Joer'] - }; - return withoutSuffix ? format[key][0] : format[key][1]; - } - function processFutureTime(string) { - var number = string.substr(0, string.indexOf(' ')); - if (eifelerRegelAppliesToNumber(number)) { - return 'a ' + string; - } - return 'an ' + string; - } - function processPastTime(string) { - var number = string.substr(0, string.indexOf(' ')); - if (eifelerRegelAppliesToNumber(number)) { - return 'viru ' + string; - } - return 'virun ' + string; - } - /** - * Returns true if the word before the given number loses the '-n' ending. - * e.g. 'an 10 Deeg' but 'a 5 Deeg' - * - * @param number {integer} - * @returns {boolean} - */ - function eifelerRegelAppliesToNumber(number) { - number = parseInt(number, 10); - if (isNaN(number)) { - return false; - } - if (number < 0) { - // Negative Number --> always true - return true; - } else if (number < 10) { - // Only 1 digit - if (4 <= number && number <= 7) { - return true; + var zhCn = moment.defineLocale('zh-cn', { + months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'), + weekdaysMin : '日_一_二_三_四_五_六'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY/MM/DD', + LL : 'YYYY年M月D日', + LLL : 'YYYY年M月D日Ah点mm分', + LLLL : 'YYYY年M月D日ddddAh点mm分', + l : 'YYYY/M/D', + ll : 'YYYY年M月D日', + lll : 'YYYY年M月D日 HH:mm', + llll : 'YYYY年M月D日dddd HH:mm' + }, + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; } - return false; - } else if (number < 100) { - // 2 digits - var lastDigit = number % 10, firstDigit = number / 10; - if (lastDigit === 0) { - return eifelerRegelAppliesToNumber(firstDigit); + if (meridiem === '凌晨' || meridiem === '早上' || + meridiem === '上午') { + return hour; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } else { + // '中午' + return hour >= 11 ? hour : hour + 12; } - return eifelerRegelAppliesToNumber(lastDigit); - } else if (number < 10000) { - // 3 or 4 digits --> recursively check first digit - while (number >= 10) { - number = number / 10; + }, + meridiem : function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1130) { + return '上午'; + } else if (hm < 1230) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } else { + return '晚上'; } - return eifelerRegelAppliesToNumber(number); - } else { - // Anything larger than 4 digits: recursively check first n-3 digits - number = number / 1000; - return eifelerRegelAppliesToNumber(number); - } - } - - var lb = moment.defineLocale('lb', { - months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), - monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'), - monthsParseExact : true, - weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'), - weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'), - weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'), - weekdaysParseExact : true, - longDateFormat: { - LT: 'H:mm [Auer]', - LTS: 'H:mm:ss [Auer]', - L: 'DD.MM.YYYY', - LL: 'D. MMMM YYYY', - LLL: 'D. MMMM YYYY H:mm [Auer]', - LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]' }, - calendar: { - sameDay: '[Haut um] LT', - sameElse: 'L', - nextDay: '[Muer um] LT', - nextWeek: 'dddd [um] LT', - lastDay: '[Gëschter um] LT', - lastWeek: function () { - // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule - switch (this.day()) { - case 2: - case 4: - return '[Leschten] dddd [um] LT'; - default: - return '[Leschte] dddd [um] LT'; - } + calendar : { + sameDay : '[今天]LT', + nextDay : '[明天]LT', + nextWeek : '[下]ddddLT', + lastDay : '[昨天]LT', + lastWeek : '[上]ddddLT', + sameElse : 'L' + }, + dayOfMonthOrdinalParse: /\d{1,2}(日|月|周)/, + ordinal : function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '日'; + case 'M': + return number + '月'; + case 'w': + case 'W': + return number + '周'; + default: + return number; } }, relativeTime : { - future : processFutureTime, - past : processPastTime, - s : 'e puer Sekonnen', - ss : '%d Sekonnen', - m : processRelativeTime, - mm : '%d Minutten', - h : processRelativeTime, - hh : '%d Stonnen', - d : processRelativeTime, - dd : '%d Deeg', - M : processRelativeTime, - MM : '%d Méint', - y : processRelativeTime, - yy : '%d Joer' + future : '%s内', + past : '%s前', + s : '几秒', + ss : '%d 秒', + m : '1 分钟', + mm : '%d 分钟', + h : '1 小时', + hh : '%d 小时', + d : '1 天', + dd : '%d 天', + M : '1 个月', + MM : '%d 个月', + y : '1 年', + yy : '%d 年' }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal: '%d.', - week: { - dow: 1, // Monday is the first day of the week. - doy: 4 // The week that contains Jan 4th is the first week of the year. + week : { + // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. } }); - return lb; + return zhCn; }))); /***/ }), -/* 112 */ +/* 138 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var lo = moment.defineLocale('lo', { - months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'), - monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'), - weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), - weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), - weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'), - weekdaysParseExact : true, + var zhHk = moment.defineLocale('zh-hk', { + months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'), + weekdaysMin : '日_一_二_三_四_五_六'.split('_'), longDateFormat : { LT : 'HH:mm', LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'ວັນdddd D MMMM YYYY HH:mm' + L : 'YYYY/MM/DD', + LL : 'YYYY年M月D日', + LLL : 'YYYY年M月D日 HH:mm', + LLLL : 'YYYY年M月D日dddd HH:mm', + l : 'YYYY/M/D', + ll : 'YYYY年M月D日', + lll : 'YYYY年M月D日 HH:mm', + llll : 'YYYY年M月D日dddd HH:mm' }, - meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/, - isPM: function (input) { - return input === 'ຕອນແລງ'; + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') { + return hour; + } else if (meridiem === '中午') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } }, meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'ຕອນເຊົ້າ'; + var hm = hour * 100 + minute; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1130) { + return '上午'; + } else if (hm < 1230) { + return '中午'; + } else if (hm < 1800) { + return '下午'; } else { - return 'ຕອນແລງ'; + return '晚上'; } }, calendar : { - sameDay : '[ມື້ນີ້ເວລາ] LT', - nextDay : '[ມື້ອື່ນເວລາ] LT', - nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT', - lastDay : '[ມື້ວານນີ້ເວລາ] LT', - lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT', + sameDay : '[今天]LT', + nextDay : '[明天]LT', + nextWeek : '[下]ddddLT', + lastDay : '[昨天]LT', + lastWeek : '[上]ddddLT', sameElse : 'L' }, - relativeTime : { - future : 'ອີກ %s', - past : '%sຜ່ານມາ', - s : 'ບໍ່ເທົ່າໃດວິນາທີ', - ss : '%d ວິນາທີ' , - m : '1 ນາທີ', - mm : '%d ນາທີ', - h : '1 ຊົ່ວໂມງ', - hh : '%d ຊົ່ວໂມງ', - d : '1 ມື້', - dd : '%d ມື້', - M : '1 ເດືອນ', - MM : '%d ເດືອນ', - y : '1 ປີ', - yy : '%d ປີ' + dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/, + ordinal : function (number, period) { + switch (period) { + case 'd' : + case 'D' : + case 'DDD' : + return number + '日'; + case 'M' : + return number + '月'; + case 'w' : + case 'W' : + return number + '週'; + default : + return number; + } }, - dayOfMonthOrdinalParse: /(ທີ່)\d{1,2}/, - ordinal : function (number) { - return 'ທີ່' + number; + relativeTime : { + future : '%s內', + past : '%s前', + s : '幾秒', + ss : '%d 秒', + m : '1 分鐘', + mm : '%d 分鐘', + h : '1 小時', + hh : '%d 小時', + d : '1 天', + dd : '%d 天', + M : '1 個月', + MM : '%d 個月', + y : '1 年', + yy : '%d 年' } }); - return lo; + return zhHk; }))); /***/ }), -/* 113 */ +/* 139 */ /***/ (function(module, exports, __webpack_require__) { //! moment.js locale configuration ;(function (global, factory) { - true ? factory(__webpack_require__(40)) : + true ? factory(__webpack_require__(10)) : undefined }(this, (function (moment) { 'use strict'; - var units = { - 'ss' : 'sekundė_sekundžių_sekundes', - 'm' : 'minutė_minutės_minutę', - 'mm': 'minutės_minučių_minutes', - 'h' : 'valanda_valandos_valandą', - 'hh': 'valandos_valandų_valandas', - 'd' : 'diena_dienos_dieną', - 'dd': 'dienos_dienų_dienas', - 'M' : 'mėnuo_mėnesio_mėnesį', - 'MM': 'mėnesiai_mėnesių_mėnesius', - 'y' : 'metai_metų_metus', - 'yy': 'metai_metų_metus' - }; - function translateSeconds(number, withoutSuffix, key, isFuture) { - if (withoutSuffix) { - return 'kelios sekundės'; - } else { - return isFuture ? 'kelių sekundžių' : 'kelias sekundes'; - } - } - function translateSingular(number, withoutSuffix, key, isFuture) { - return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]); - } - function special(number) { - return number % 10 === 0 || (number > 10 && number < 20); - } - function forms(key) { - return units[key].split('_'); - } - function translate(number, withoutSuffix, key, isFuture) { - var result = number + ' '; - if (number === 1) { - return result + translateSingular(number, withoutSuffix, key[0], isFuture); - } else if (withoutSuffix) { - return result + (special(number) ? forms(key)[1] : forms(key)[0]); - } else { - if (isFuture) { - return result + forms(key)[1]; - } else { - return result + (special(number) ? forms(key)[1] : forms(key)[2]); - } - } - } - var lt = moment.defineLocale('lt', { - months : { - format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'), - standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'), - isFormat: /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/ - }, - monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'), - weekdays : { - format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'), - standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'), - isFormat: /dddd HH:mm/ - }, - weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'), - weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'), - weekdaysParseExact : true, + var zhTw = moment.defineLocale('zh-tw', { + months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'), + weekdaysMin : '日_一_二_三_四_五_六'.split('_'), longDateFormat : { LT : 'HH:mm', LTS : 'HH:mm:ss', - L : 'YYYY-MM-DD', - LL : 'YYYY [m.] MMMM D [d.]', - LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]', - LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]', - l : 'YYYY-MM-DD', - ll : 'YYYY [m.] MMMM D [d.]', - lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]', - llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]' + L : 'YYYY/MM/DD', + LL : 'YYYY年M月D日', + LLL : 'YYYY年M月D日 HH:mm', + LLLL : 'YYYY年M月D日dddd HH:mm', + l : 'YYYY/M/D', + ll : 'YYYY年M月D日', + lll : 'YYYY年M月D日 HH:mm', + llll : 'YYYY年M月D日dddd HH:mm' + }, + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') { + return hour; + } else if (meridiem === '中午') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1130) { + return '上午'; + } else if (hm < 1230) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } else { + return '晚上'; + } }, calendar : { - sameDay : '[Šiandien] LT', - nextDay : '[Rytoj] LT', - nextWeek : 'dddd LT', - lastDay : '[Vakar] LT', - lastWeek : '[Praėjusį] dddd LT', + sameDay : '[今天] LT', + nextDay : '[明天] LT', + nextWeek : '[下]dddd LT', + lastDay : '[昨天] LT', + lastWeek : '[上]dddd LT', sameElse : 'L' }, - relativeTime : { - future : 'po %s', - past : 'prieš %s', - s : translateSeconds, - ss : translate, - m : translateSingular, - mm : translate, - h : translateSingular, - hh : translate, - d : translateSingular, - dd : translate, - M : translateSingular, - MM : translate, - y : translateSingular, - yy : translate - }, - dayOfMonthOrdinalParse: /\d{1,2}-oji/, - ordinal : function (number) { - return number + '-oji'; + dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/, + ordinal : function (number, period) { + switch (period) { + case 'd' : + case 'D' : + case 'DDD' : + return number + '日'; + case 'M' : + return number + '月'; + case 'w' : + case 'W' : + return number + '週'; + default : + return number; + } }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + relativeTime : { + future : '%s內', + past : '%s前', + s : '幾秒', + ss : '%d 秒', + m : '1 分鐘', + mm : '%d 分鐘', + h : '1 小時', + hh : '%d 小時', + d : '1 天', + dd : '%d 天', + M : '1 個月', + MM : '%d 個月', + y : '1 年', + yy : '%d 年' } }); - return lt; + return zhTw; }))); /***/ }), -/* 114 */ -/***/ (function(module, exports, __webpack_require__) { +/* 140 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _internal_Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Observable", function() { return _internal_Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]; }); -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/* harmony import */ var _internal_observable_ConnectableObservable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(157); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ConnectableObservable", function() { return _internal_observable_ConnectableObservable__WEBPACK_IMPORTED_MODULE_1__["ConnectableObservable"]; }); +/* harmony import */ var _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(162); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GroupedObservable", function() { return _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_2__["GroupedObservable"]; }); - var units = { - 'ss': 'sekundes_sekundēm_sekunde_sekundes'.split('_'), - 'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'), - 'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'), - 'h': 'stundas_stundām_stunda_stundas'.split('_'), - 'hh': 'stundas_stundām_stunda_stundas'.split('_'), - 'd': 'dienas_dienām_diena_dienas'.split('_'), - 'dd': 'dienas_dienām_diena_dienas'.split('_'), - 'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), - 'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), - 'y': 'gada_gadiem_gads_gadi'.split('_'), - 'yy': 'gada_gadiem_gads_gadi'.split('_') - }; - /** - * @param withoutSuffix boolean true = a length of time; false = before/after a period of time. - */ - function format(forms, number, withoutSuffix) { - if (withoutSuffix) { - // E.g. "21 minūte", "3 minūtes". - return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3]; - } else { - // E.g. "21 minūtes" as in "pēc 21 minūtes". - // E.g. "3 minūtēm" as in "pēc 3 minūtēm". - return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1]; - } - } - function relativeTimeWithPlural(number, withoutSuffix, key) { - return number + ' ' + format(units[key], number, withoutSuffix); - } - function relativeTimeWithSingular(number, withoutSuffix, key) { - return format(units[key], number, withoutSuffix); - } - function relativeSeconds(number, withoutSuffix) { - return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm'; - } +/* harmony import */ var _internal_symbol_observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(154); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "observable", function() { return _internal_symbol_observable__WEBPACK_IMPORTED_MODULE_3__["observable"]; }); - var lv = moment.defineLocale('lv', { - months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'), - monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'), - weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'), - weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'), - weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY.', - LL : 'YYYY. [gada] D. MMMM', - LLL : 'YYYY. [gada] D. MMMM, HH:mm', - LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm' - }, - calendar : { - sameDay : '[Šodien pulksten] LT', - nextDay : '[Rīt pulksten] LT', - nextWeek : 'dddd [pulksten] LT', - lastDay : '[Vakar pulksten] LT', - lastWeek : '[Pagājušā] dddd [pulksten] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'pēc %s', - past : 'pirms %s', - s : relativeSeconds, - ss : relativeTimeWithPlural, - m : relativeTimeWithSingular, - mm : relativeTimeWithPlural, - h : relativeTimeWithSingular, - hh : relativeTimeWithPlural, - d : relativeTimeWithSingular, - dd : relativeTimeWithPlural, - M : relativeTimeWithSingular, - MM : relativeTimeWithPlural, - y : relativeTimeWithSingular, - yy : relativeTimeWithPlural - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); +/* harmony import */ var _internal_Subject__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(158); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Subject", function() { return _internal_Subject__WEBPACK_IMPORTED_MODULE_4__["Subject"]; }); - return lv; +/* harmony import */ var _internal_BehaviorSubject__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(163); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BehaviorSubject", function() { return _internal_BehaviorSubject__WEBPACK_IMPORTED_MODULE_5__["BehaviorSubject"]; }); -}))); +/* harmony import */ var _internal_ReplaySubject__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(164); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ReplaySubject", function() { return _internal_ReplaySubject__WEBPACK_IMPORTED_MODULE_6__["ReplaySubject"]; }); +/* harmony import */ var _internal_AsyncSubject__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(181); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AsyncSubject", function() { return _internal_AsyncSubject__WEBPACK_IMPORTED_MODULE_7__["AsyncSubject"]; }); -/***/ }), -/* 115 */ -/***/ (function(module, exports, __webpack_require__) { +/* harmony import */ var _internal_scheduler_asap__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(182); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "asapScheduler", function() { return _internal_scheduler_asap__WEBPACK_IMPORTED_MODULE_8__["asap"]; }); -//! moment.js locale configuration +/* harmony import */ var _internal_scheduler_async__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(186); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "asyncScheduler", function() { return _internal_scheduler_async__WEBPACK_IMPORTED_MODULE_9__["async"]; }); -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/* harmony import */ var _internal_scheduler_queue__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(165); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "queueScheduler", function() { return _internal_scheduler_queue__WEBPACK_IMPORTED_MODULE_10__["queue"]; }); +/* harmony import */ var _internal_scheduler_animationFrame__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(187); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "animationFrameScheduler", function() { return _internal_scheduler_animationFrame__WEBPACK_IMPORTED_MODULE_11__["animationFrame"]; }); - var translator = { - words: { //Different grammatical cases - ss: ['sekund', 'sekunda', 'sekundi'], - m: ['jedan minut', 'jednog minuta'], - mm: ['minut', 'minuta', 'minuta'], - h: ['jedan sat', 'jednog sata'], - hh: ['sat', 'sata', 'sati'], - dd: ['dan', 'dana', 'dana'], - MM: ['mjesec', 'mjeseca', 'mjeseci'], - yy: ['godina', 'godine', 'godina'] - }, - correctGrammaticalCase: function (number, wordKey) { - return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); - }, - translate: function (number, withoutSuffix, key) { - var wordKey = translator.words[key]; - if (key.length === 1) { - return withoutSuffix ? wordKey[0] : wordKey[1]; - } else { - return number + ' ' + translator.correctGrammaticalCase(number, wordKey); - } - } - }; +/* harmony import */ var _internal_scheduler_VirtualTimeScheduler__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(190); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VirtualTimeScheduler", function() { return _internal_scheduler_VirtualTimeScheduler__WEBPACK_IMPORTED_MODULE_12__["VirtualTimeScheduler"]; }); - var me = moment.defineLocale('me', { - months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'), - monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'), - monthsParseExact : true, - weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), - weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), - weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'), - weekdaysParseExact : true, - longDateFormat: { - LT: 'H:mm', - LTS : 'H:mm:ss', - L: 'DD.MM.YYYY', - LL: 'D. MMMM YYYY', - LLL: 'D. MMMM YYYY H:mm', - LLLL: 'dddd, D. MMMM YYYY H:mm' - }, - calendar: { - sameDay: '[danas u] LT', - nextDay: '[sjutra u] LT', +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VirtualAction", function() { return _internal_scheduler_VirtualTimeScheduler__WEBPACK_IMPORTED_MODULE_12__["VirtualAction"]; }); - nextWeek: function () { - switch (this.day()) { - case 0: - return '[u] [nedjelju] [u] LT'; - case 3: - return '[u] [srijedu] [u] LT'; - case 6: - return '[u] [subotu] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[u] dddd [u] LT'; - } - }, - lastDay : '[juče u] LT', - lastWeek : function () { - var lastWeekDays = [ - '[prošle] [nedjelje] [u] LT', - '[prošlog] [ponedjeljka] [u] LT', - '[prošlog] [utorka] [u] LT', - '[prošle] [srijede] [u] LT', - '[prošlog] [četvrtka] [u] LT', - '[prošlog] [petka] [u] LT', - '[prošle] [subote] [u] LT' - ]; - return lastWeekDays[this.day()]; - }, - sameElse : 'L' - }, - relativeTime : { - future : 'za %s', - past : 'prije %s', - s : 'nekoliko sekundi', - ss : translator.translate, - m : translator.translate, - mm : translator.translate, - h : translator.translate, - hh : translator.translate, - d : 'dan', - dd : translator.translate, - M : 'mjesec', - MM : translator.translate, - y : 'godinu', - yy : translator.translate - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); +/* harmony import */ var _internal_Scheduler__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(171); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Scheduler", function() { return _internal_Scheduler__WEBPACK_IMPORTED_MODULE_13__["Scheduler"]; }); - return me; +/* harmony import */ var _internal_Subscription__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(148); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Subscription", function() { return _internal_Subscription__WEBPACK_IMPORTED_MODULE_14__["Subscription"]; }); -}))); +/* harmony import */ var _internal_Subscriber__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(143); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Subscriber", function() { return _internal_Subscriber__WEBPACK_IMPORTED_MODULE_15__["Subscriber"]; }); +/* harmony import */ var _internal_Notification__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(173); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Notification", function() { return _internal_Notification__WEBPACK_IMPORTED_MODULE_16__["Notification"]; }); -/***/ }), -/* 116 */ -/***/ (function(module, exports, __webpack_require__) { +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NotificationKind", function() { return _internal_Notification__WEBPACK_IMPORTED_MODULE_16__["NotificationKind"]; }); -//! moment.js locale configuration +/* harmony import */ var _internal_util_pipe__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(155); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pipe", function() { return _internal_util_pipe__WEBPACK_IMPORTED_MODULE_17__["pipe"]; }); -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/* harmony import */ var _internal_util_noop__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(156); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "noop", function() { return _internal_util_noop__WEBPACK_IMPORTED_MODULE_18__["noop"]; }); +/* harmony import */ var _internal_util_identity__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(191); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "identity", function() { return _internal_util_identity__WEBPACK_IMPORTED_MODULE_19__["identity"]; }); - var mi = moment.defineLocale('mi', { - months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'), - monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'), - monthsRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, - monthsStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, - monthsShortRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, - monthsShortStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i, - weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'), - weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'), - weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'), - longDateFormat: { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY [i] HH:mm', - LLLL: 'dddd, D MMMM YYYY [i] HH:mm' - }, - calendar: { - sameDay: '[i teie mahana, i] LT', - nextDay: '[apopo i] LT', - nextWeek: 'dddd [i] LT', - lastDay: '[inanahi i] LT', - lastWeek: 'dddd [whakamutunga i] LT', - sameElse: 'L' - }, - relativeTime: { - future: 'i roto i %s', - past: '%s i mua', - s: 'te hēkona ruarua', - ss: '%d hēkona', - m: 'he meneti', - mm: '%d meneti', - h: 'te haora', - hh: '%d haora', - d: 'he ra', - dd: '%d ra', - M: 'he marama', - MM: '%d marama', - y: 'he tau', - yy: '%d tau' - }, - dayOfMonthOrdinalParse: /\d{1,2}º/, - ordinal: '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); +/* harmony import */ var _internal_util_isObservable__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(192); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "isObservable", function() { return _internal_util_isObservable__WEBPACK_IMPORTED_MODULE_20__["isObservable"]; }); - return mi; +/* harmony import */ var _internal_util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(193); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArgumentOutOfRangeError", function() { return _internal_util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_21__["ArgumentOutOfRangeError"]; }); -}))); +/* harmony import */ var _internal_util_EmptyError__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(194); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EmptyError", function() { return _internal_util_EmptyError__WEBPACK_IMPORTED_MODULE_22__["EmptyError"]; }); +/* harmony import */ var _internal_util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(159); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ObjectUnsubscribedError", function() { return _internal_util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_23__["ObjectUnsubscribedError"]; }); -/***/ }), -/* 117 */ -/***/ (function(module, exports, __webpack_require__) { +/* harmony import */ var _internal_util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(151); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "UnsubscriptionError", function() { return _internal_util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_24__["UnsubscriptionError"]; }); -//! moment.js locale configuration +/* harmony import */ var _internal_util_TimeoutError__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(195); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TimeoutError", function() { return _internal_util_TimeoutError__WEBPACK_IMPORTED_MODULE_25__["TimeoutError"]; }); -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/* harmony import */ var _internal_observable_bindCallback__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(196); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bindCallback", function() { return _internal_observable_bindCallback__WEBPACK_IMPORTED_MODULE_26__["bindCallback"]; }); +/* harmony import */ var _internal_observable_bindNodeCallback__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(198); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bindNodeCallback", function() { return _internal_observable_bindNodeCallback__WEBPACK_IMPORTED_MODULE_27__["bindNodeCallback"]; }); - var mk = moment.defineLocale('mk', { - months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'), - monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'), - weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'), - weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'), - weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'), - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'D.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY H:mm', - LLLL : 'dddd, D MMMM YYYY H:mm' - }, - calendar : { - sameDay : '[Денес во] LT', - nextDay : '[Утре во] LT', - nextWeek : '[Во] dddd [во] LT', - lastDay : '[Вчера во] LT', - lastWeek : function () { - switch (this.day()) { - case 0: - case 3: - case 6: - return '[Изминатата] dddd [во] LT'; - case 1: - case 2: - case 4: - case 5: - return '[Изминатиот] dddd [во] LT'; - } - }, - sameElse : 'L' - }, - relativeTime : { - future : 'после %s', - past : 'пред %s', - s : 'неколку секунди', - ss : '%d секунди', - m : 'минута', - mm : '%d минути', - h : 'час', - hh : '%d часа', - d : 'ден', - dd : '%d дена', - M : 'месец', - MM : '%d месеци', - y : 'година', - yy : '%d години' - }, - dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, - ordinal : function (number) { - var lastDigit = number % 10, - last2Digits = number % 100; - if (number === 0) { - return number + '-ев'; - } else if (last2Digits === 0) { - return number + '-ен'; - } else if (last2Digits > 10 && last2Digits < 20) { - return number + '-ти'; - } else if (lastDigit === 1) { - return number + '-ви'; - } else if (lastDigit === 2) { - return number + '-ри'; - } else if (lastDigit === 7 || lastDigit === 8) { - return number + '-ми'; - } else { - return number + '-ти'; - } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); +/* harmony import */ var _internal_observable_combineLatest__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(199); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return _internal_observable_combineLatest__WEBPACK_IMPORTED_MODULE_28__["combineLatest"]; }); - return mk; +/* harmony import */ var _internal_observable_concat__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(210); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return _internal_observable_concat__WEBPACK_IMPORTED_MODULE_29__["concat"]; }); -}))); +/* harmony import */ var _internal_observable_defer__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(221); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "defer", function() { return _internal_observable_defer__WEBPACK_IMPORTED_MODULE_30__["defer"]; }); +/* harmony import */ var _internal_observable_empty__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(174); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "empty", function() { return _internal_observable_empty__WEBPACK_IMPORTED_MODULE_31__["empty"]; }); -/***/ }), -/* 118 */ -/***/ (function(module, exports, __webpack_require__) { +/* harmony import */ var _internal_observable_forkJoin__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(222); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "forkJoin", function() { return _internal_observable_forkJoin__WEBPACK_IMPORTED_MODULE_32__["forkJoin"]; }); -//! moment.js locale configuration +/* harmony import */ var _internal_observable_from__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(214); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "from", function() { return _internal_observable_from__WEBPACK_IMPORTED_MODULE_33__["from"]; }); -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/* harmony import */ var _internal_observable_fromEvent__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(223); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "fromEvent", function() { return _internal_observable_fromEvent__WEBPACK_IMPORTED_MODULE_34__["fromEvent"]; }); +/* harmony import */ var _internal_observable_fromEventPattern__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(224); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "fromEventPattern", function() { return _internal_observable_fromEventPattern__WEBPACK_IMPORTED_MODULE_35__["fromEventPattern"]; }); - var ml = moment.defineLocale('ml', { - months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'), - monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'), - monthsParseExact : true, - weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'), - weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'), - weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'), - longDateFormat : { - LT : 'A h:mm -നു', - LTS : 'A h:mm:ss -നു', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm -നു', - LLLL : 'dddd, D MMMM YYYY, A h:mm -നു' - }, - calendar : { - sameDay : '[ഇന്ന്] LT', - nextDay : '[നാളെ] LT', - nextWeek : 'dddd, LT', - lastDay : '[ഇന്നലെ] LT', - lastWeek : '[കഴിഞ്ഞ] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s കഴിഞ്ഞ്', - past : '%s മുൻപ്', - s : 'അൽപ നിമിഷങ്ങൾ', - ss : '%d സെക്കൻഡ്', - m : 'ഒരു മിനിറ്റ്', - mm : '%d മിനിറ്റ്', - h : 'ഒരു മണിക്കൂർ', - hh : '%d മണിക്കൂർ', - d : 'ഒരു ദിവസം', - dd : '%d ദിവസം', - M : 'ഒരു മാസം', - MM : '%d മാസം', - y : 'ഒരു വർഷം', - yy : '%d വർഷം' - }, - meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if ((meridiem === 'രാത്രി' && hour >= 4) || - meridiem === 'ഉച്ച കഴിഞ്ഞ്' || - meridiem === 'വൈകുന്നേരം') { - return hour + 12; - } else { - return hour; - } - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'രാത്രി'; - } else if (hour < 12) { - return 'രാവിലെ'; - } else if (hour < 17) { - return 'ഉച്ച കഴിഞ്ഞ്'; - } else if (hour < 20) { - return 'വൈകുന്നേരം'; - } else { - return 'രാത്രി'; - } - } - }); +/* harmony import */ var _internal_observable_generate__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(225); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "generate", function() { return _internal_observable_generate__WEBPACK_IMPORTED_MODULE_36__["generate"]; }); - return ml; +/* harmony import */ var _internal_observable_iif__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(226); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "iif", function() { return _internal_observable_iif__WEBPACK_IMPORTED_MODULE_37__["iif"]; }); -}))); +/* harmony import */ var _internal_observable_interval__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(227); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "interval", function() { return _internal_observable_interval__WEBPACK_IMPORTED_MODULE_38__["interval"]; }); +/* harmony import */ var _internal_observable_merge__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(229); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return _internal_observable_merge__WEBPACK_IMPORTED_MODULE_39__["merge"]; }); -/***/ }), -/* 119 */ -/***/ (function(module, exports, __webpack_require__) { +/* harmony import */ var _internal_observable_never__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(230); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "never", function() { return _internal_observable_never__WEBPACK_IMPORTED_MODULE_40__["never"]; }); -//! moment.js locale configuration +/* harmony import */ var _internal_observable_of__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(175); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "of", function() { return _internal_observable_of__WEBPACK_IMPORTED_MODULE_41__["of"]; }); -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/* harmony import */ var _internal_observable_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(231); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return _internal_observable_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_42__["onErrorResumeNext"]; }); +/* harmony import */ var _internal_observable_pairs__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(232); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pairs", function() { return _internal_observable_pairs__WEBPACK_IMPORTED_MODULE_43__["pairs"]; }); - function translate(number, withoutSuffix, key, isFuture) { - switch (key) { - case 's': - return withoutSuffix ? 'хэдхэн секунд' : 'хэдхэн секундын'; - case 'ss': - return number + (withoutSuffix ? ' секунд' : ' секундын'); - case 'm': - case 'mm': - return number + (withoutSuffix ? ' минут' : ' минутын'); - case 'h': - case 'hh': - return number + (withoutSuffix ? ' цаг' : ' цагийн'); - case 'd': - case 'dd': - return number + (withoutSuffix ? ' өдөр' : ' өдрийн'); - case 'M': - case 'MM': - return number + (withoutSuffix ? ' сар' : ' сарын'); - case 'y': - case 'yy': - return number + (withoutSuffix ? ' жил' : ' жилийн'); - default: - return number; - } - } +/* harmony import */ var _internal_observable_partition__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(233); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return _internal_observable_partition__WEBPACK_IMPORTED_MODULE_44__["partition"]; }); - var mn = moment.defineLocale('mn', { - months : 'Нэгдүгээр сар_Хоёрдугаар сар_Гуравдугаар сар_Дөрөвдүгээр сар_Тавдугаар сар_Зургадугаар сар_Долдугаар сар_Наймдугаар сар_Есдүгээр сар_Аравдугаар сар_Арван нэгдүгээр сар_Арван хоёрдугаар сар'.split('_'), - monthsShort : '1 сар_2 сар_3 сар_4 сар_5 сар_6 сар_7 сар_8 сар_9 сар_10 сар_11 сар_12 сар'.split('_'), - monthsParseExact : true, - weekdays : 'Ням_Даваа_Мягмар_Лхагва_Пүрэв_Баасан_Бямба'.split('_'), - weekdaysShort : 'Ням_Дав_Мяг_Лха_Пүр_Баа_Бям'.split('_'), - weekdaysMin : 'Ня_Да_Мя_Лх_Пү_Ба_Бя'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY-MM-DD', - LL : 'YYYY оны MMMMын D', - LLL : 'YYYY оны MMMMын D HH:mm', - LLLL : 'dddd, YYYY оны MMMMын D HH:mm' - }, - meridiemParse: /ҮӨ|ҮХ/i, - isPM : function (input) { - return input === 'ҮХ'; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'ҮӨ'; - } else { - return 'ҮХ'; - } - }, - calendar : { - sameDay : '[Өнөөдөр] LT', - nextDay : '[Маргааш] LT', - nextWeek : '[Ирэх] dddd LT', - lastDay : '[Өчигдөр] LT', - lastWeek : '[Өнгөрсөн] dddd LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s дараа', - past : '%s өмнө', - s : translate, - ss : translate, - m : translate, - mm : translate, - h : translate, - hh : translate, - d : translate, - dd : translate, - M : translate, - MM : translate, - y : translate, - yy : translate - }, - dayOfMonthOrdinalParse: /\d{1,2} өдөр/, - ordinal : function (number, period) { - switch (period) { - case 'd': - case 'D': - case 'DDD': - return number + ' өдөр'; - default: - return number; - } - } - }); +/* harmony import */ var _internal_observable_race__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(236); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "race", function() { return _internal_observable_race__WEBPACK_IMPORTED_MODULE_45__["race"]; }); - return mn; +/* harmony import */ var _internal_observable_range__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(237); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "range", function() { return _internal_observable_range__WEBPACK_IMPORTED_MODULE_46__["range"]; }); -}))); +/* harmony import */ var _internal_observable_throwError__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(180); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throwError", function() { return _internal_observable_throwError__WEBPACK_IMPORTED_MODULE_47__["throwError"]; }); +/* harmony import */ var _internal_observable_timer__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(238); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timer", function() { return _internal_observable_timer__WEBPACK_IMPORTED_MODULE_48__["timer"]; }); -/***/ }), -/* 120 */ -/***/ (function(module, exports, __webpack_require__) { +/* harmony import */ var _internal_observable_using__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(239); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "using", function() { return _internal_observable_using__WEBPACK_IMPORTED_MODULE_49__["using"]; }); -//! moment.js locale configuration +/* harmony import */ var _internal_observable_zip__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(240); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return _internal_observable_zip__WEBPACK_IMPORTED_MODULE_50__["zip"]; }); -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/* harmony import */ var _internal_scheduled_scheduled__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(215); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "scheduled", function() { return _internal_scheduled_scheduled__WEBPACK_IMPORTED_MODULE_51__["scheduled"]; }); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EMPTY", function() { return _internal_observable_empty__WEBPACK_IMPORTED_MODULE_31__["EMPTY"]; }); - var symbolMap = { - '1': '१', - '2': '२', - '3': '३', - '4': '४', - '5': '५', - '6': '६', - '7': '७', - '8': '८', - '9': '९', - '0': '०' - }, - numberMap = { - '१': '1', - '२': '2', - '३': '3', - '४': '4', - '५': '5', - '६': '6', - '७': '7', - '८': '8', - '९': '9', - '०': '0' - }; +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NEVER", function() { return _internal_observable_never__WEBPACK_IMPORTED_MODULE_40__["NEVER"]; }); - function relativeTimeMr(number, withoutSuffix, string, isFuture) - { - var output = ''; - if (withoutSuffix) { - switch (string) { - case 's': output = 'काही सेकंद'; break; - case 'ss': output = '%d सेकंद'; break; - case 'm': output = 'एक मिनिट'; break; - case 'mm': output = '%d मिनिटे'; break; - case 'h': output = 'एक तास'; break; - case 'hh': output = '%d तास'; break; - case 'd': output = 'एक दिवस'; break; - case 'dd': output = '%d दिवस'; break; - case 'M': output = 'एक महिना'; break; - case 'MM': output = '%d महिने'; break; - case 'y': output = 'एक वर्ष'; break; - case 'yy': output = '%d वर्षे'; break; - } - } - else { - switch (string) { - case 's': output = 'काही सेकंदां'; break; - case 'ss': output = '%d सेकंदां'; break; - case 'm': output = 'एका मिनिटा'; break; - case 'mm': output = '%d मिनिटां'; break; - case 'h': output = 'एका तासा'; break; - case 'hh': output = '%d तासां'; break; - case 'd': output = 'एका दिवसा'; break; - case 'dd': output = '%d दिवसां'; break; - case 'M': output = 'एका महिन्या'; break; - case 'MM': output = '%d महिन्यां'; break; - case 'y': output = 'एका वर्षा'; break; - case 'yy': output = '%d वर्षां'; break; - } - } - return output.replace(/%d/i, number); - } +/* harmony import */ var _internal_config__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(146); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "config", function() { return _internal_config__WEBPACK_IMPORTED_MODULE_52__["config"]; }); - var mr = moment.defineLocale('mr', { - months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'), - monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'), - monthsParseExact : true, - weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), - weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'), - weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), - longDateFormat : { - LT : 'A h:mm वाजता', - LTS : 'A h:mm:ss वाजता', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm वाजता', - LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता' - }, - calendar : { - sameDay : '[आज] LT', - nextDay : '[उद्या] LT', - nextWeek : 'dddd, LT', - lastDay : '[काल] LT', - lastWeek: '[मागील] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future: '%sमध्ये', - past: '%sपूर्वी', - s: relativeTimeMr, - ss: relativeTimeMr, - m: relativeTimeMr, - mm: relativeTimeMr, - h: relativeTimeMr, - hh: relativeTimeMr, - d: relativeTimeMr, - dd: relativeTimeMr, - M: relativeTimeMr, - MM: relativeTimeMr, - y: relativeTimeMr, - yy: relativeTimeMr - }, - preparse: function (string) { - return string.replace(/[१२३४५६७८९०]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); - }, - meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'रात्री') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'सकाळी') { - return hour; - } else if (meridiem === 'दुपारी') { - return hour >= 10 ? hour : hour + 12; - } else if (meridiem === 'सायंकाळी') { - return hour + 12; - } - }, - meridiem: function (hour, minute, isLower) { - if (hour < 4) { - return 'रात्री'; - } else if (hour < 10) { - return 'सकाळी'; - } else if (hour < 17) { - return 'दुपारी'; - } else if (hour < 20) { - return 'सायंकाळी'; - } else { - return 'रात्री'; - } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - } - }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ - return mr; -}))); -/***/ }), -/* 121 */ -/***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var ms = moment.defineLocale('ms', { - months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'), - monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), - weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), - weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), - weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), - longDateFormat : { - LT : 'HH.mm', - LTS : 'HH.mm.ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY [pukul] HH.mm', - LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' - }, - meridiemParse: /pagi|tengahari|petang|malam/, - meridiemHour: function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'pagi') { - return hour; - } else if (meridiem === 'tengahari') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === 'petang' || meridiem === 'malam') { - return hour + 12; - } - }, - meridiem : function (hours, minutes, isLower) { - if (hours < 11) { - return 'pagi'; - } else if (hours < 15) { - return 'tengahari'; - } else if (hours < 19) { - return 'petang'; - } else { - return 'malam'; - } - }, - calendar : { - sameDay : '[Hari ini pukul] LT', - nextDay : '[Esok pukul] LT', - nextWeek : 'dddd [pukul] LT', - lastDay : '[Kelmarin pukul] LT', - lastWeek : 'dddd [lepas pukul] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'dalam %s', - past : '%s yang lepas', - s : 'beberapa saat', - ss : '%d saat', - m : 'seminit', - mm : '%d minit', - h : 'sejam', - hh : '%d jam', - d : 'sehari', - dd : '%d hari', - M : 'sebulan', - MM : '%d bulan', - y : 'setahun', - yy : '%d tahun' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - return ms; -}))); -/***/ }), -/* 122 */ -/***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var msMy = moment.defineLocale('ms-my', { - months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'), - monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), - weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), - weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), - weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), - longDateFormat : { - LT : 'HH.mm', - LTS : 'HH.mm.ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY [pukul] HH.mm', - LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' - }, - meridiemParse: /pagi|tengahari|petang|malam/, - meridiemHour: function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'pagi') { - return hour; - } else if (meridiem === 'tengahari') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === 'petang' || meridiem === 'malam') { - return hour + 12; - } - }, - meridiem : function (hours, minutes, isLower) { - if (hours < 11) { - return 'pagi'; - } else if (hours < 15) { - return 'tengahari'; - } else if (hours < 19) { - return 'petang'; - } else { - return 'malam'; - } - }, - calendar : { - sameDay : '[Hari ini pukul] LT', - nextDay : '[Esok pukul] LT', - nextWeek : 'dddd [pukul] LT', - lastDay : '[Kelmarin pukul] LT', - lastWeek : 'dddd [lepas pukul] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'dalam %s', - past : '%s yang lepas', - s : 'beberapa saat', - ss : '%d saat', - m : 'seminit', - mm : '%d minit', - h : 'sejam', - hh : '%d jam', - d : 'sehari', - dd : '%d hari', - M : 'sebulan', - MM : '%d bulan', - y : 'setahun', - yy : '%d tahun' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - return msMy; -}))); -/***/ }), -/* 123 */ -/***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var mt = moment.defineLocale('mt', { - months : 'Jannar_Frar_Marzu_April_Mejju_Ġunju_Lulju_Awwissu_Settembru_Ottubru_Novembru_Diċembru'.split('_'), - monthsShort : 'Jan_Fra_Mar_Apr_Mej_Ġun_Lul_Aww_Set_Ott_Nov_Diċ'.split('_'), - weekdays : 'Il-Ħadd_It-Tnejn_It-Tlieta_L-Erbgħa_Il-Ħamis_Il-Ġimgħa_Is-Sibt'.split('_'), - weekdaysShort : 'Ħad_Tne_Tli_Erb_Ħam_Ġim_Sib'.split('_'), - weekdaysMin : 'Ħa_Tn_Tl_Er_Ħa_Ġi_Si'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Illum fil-]LT', - nextDay : '[Għada fil-]LT', - nextWeek : 'dddd [fil-]LT', - lastDay : '[Il-bieraħ fil-]LT', - lastWeek : 'dddd [li għadda] [fil-]LT', - sameElse : 'L' - }, - relativeTime : { - future : 'f’ %s', - past : '%s ilu', - s : 'ftit sekondi', - ss : '%d sekondi', - m : 'minuta', - mm : '%d minuti', - h : 'siegħa', - hh : '%d siegħat', - d : 'ġurnata', - dd : '%d ġranet', - M : 'xahar', - MM : '%d xhur', - y : 'sena', - yy : '%d sni' - }, - dayOfMonthOrdinalParse : /\d{1,2}º/, - ordinal: '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - return mt; -}))); -/***/ }), -/* 124 */ -/***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var symbolMap = { - '1': '၁', - '2': '၂', - '3': '၃', - '4': '၄', - '5': '၅', - '6': '၆', - '7': '၇', - '8': '၈', - '9': '၉', - '0': '၀' - }, numberMap = { - '၁': '1', - '၂': '2', - '၃': '3', - '၄': '4', - '၅': '5', - '၆': '6', - '၇': '7', - '၈': '8', - '၉': '9', - '၀': '0' - }; - var my = moment.defineLocale('my', { - months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'), - monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'), - weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'), - weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), - weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), - longDateFormat: { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY HH:mm', - LLLL: 'dddd D MMMM YYYY HH:mm' - }, - calendar: { - sameDay: '[ယနေ.] LT [မှာ]', - nextDay: '[မနက်ဖြန်] LT [မှာ]', - nextWeek: 'dddd LT [မှာ]', - lastDay: '[မနေ.က] LT [မှာ]', - lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]', - sameElse: 'L' - }, - relativeTime: { - future: 'လာမည့် %s မှာ', - past: 'လွန်ခဲ့သော %s က', - s: 'စက္ကန်.အနည်းငယ်', - ss : '%d စက္ကန့်', - m: 'တစ်မိနစ်', - mm: '%d မိနစ်', - h: 'တစ်နာရီ', - hh: '%d နာရီ', - d: 'တစ်ရက်', - dd: '%d ရက်', - M: 'တစ်လ', - MM: '%d လ', - y: 'တစ်နှစ်', - yy: '%d နှစ်' - }, - preparse: function (string) { - return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); - }, - week: { - dow: 1, // Monday is the first day of the week. - doy: 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - return my; -}))); -/***/ }), -/* 125 */ -/***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var nb = moment.defineLocale('nb', { - months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), - monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'), - monthsParseExact : true, - weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), - weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'), - weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY [kl.] HH:mm', - LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm' - }, - calendar : { - sameDay: '[i dag kl.] LT', - nextDay: '[i morgen kl.] LT', - nextWeek: 'dddd [kl.] LT', - lastDay: '[i går kl.] LT', - lastWeek: '[forrige] dddd [kl.] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'om %s', - past : '%s siden', - s : 'noen sekunder', - ss : '%d sekunder', - m : 'ett minutt', - mm : '%d minutter', - h : 'en time', - hh : '%d timer', - d : 'en dag', - dd : '%d dager', - M : 'en måned', - MM : '%d måneder', - y : 'ett år', - yy : '%d år' - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - return nb; -}))); -/***/ }), -/* 126 */ -/***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var symbolMap = { - '1': '१', - '2': '२', - '3': '३', - '4': '४', - '5': '५', - '6': '६', - '7': '७', - '8': '८', - '9': '९', - '0': '०' - }, - numberMap = { - '१': '1', - '२': '2', - '३': '3', - '४': '4', - '५': '5', - '६': '6', - '७': '7', - '८': '8', - '९': '9', - '०': '0' - }; - var ne = moment.defineLocale('ne', { - months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'), - monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'), - monthsParseExact : true, - weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'), - weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'), - weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'Aको h:mm बजे', - LTS : 'Aको h:mm:ss बजे', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, Aको h:mm बजे', - LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे' - }, - preparse: function (string) { - return string.replace(/[१२३४५६७८९०]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); - }, - meridiemParse: /राति|बिहान|दिउँसो|साँझ/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'राति') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'बिहान') { - return hour; - } else if (meridiem === 'दिउँसो') { - return hour >= 10 ? hour : hour + 12; - } else if (meridiem === 'साँझ') { - return hour + 12; - } - }, - meridiem : function (hour, minute, isLower) { - if (hour < 3) { - return 'राति'; - } else if (hour < 12) { - return 'बिहान'; - } else if (hour < 16) { - return 'दिउँसो'; - } else if (hour < 20) { - return 'साँझ'; - } else { - return 'राति'; - } - }, - calendar : { - sameDay : '[आज] LT', - nextDay : '[भोलि] LT', - nextWeek : '[आउँदो] dddd[,] LT', - lastDay : '[हिजो] LT', - lastWeek : '[गएको] dddd[,] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%sमा', - past : '%s अगाडि', - s : 'केही क्षण', - ss : '%d सेकेण्ड', - m : 'एक मिनेट', - mm : '%d मिनेट', - h : 'एक घण्टा', - hh : '%d घण्टा', - d : 'एक दिन', - dd : '%d दिन', - M : 'एक महिना', - MM : '%d महिना', - y : 'एक बर्ष', - yy : '%d बर्ष' - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - } - }); - return ne; -}))); -/***/ }), -/* 127 */ -/***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration +//# sourceMappingURL=index.js.map -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/***/ }), +/* 141 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'), - monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_'); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Observable", function() { return Observable; }); +/* harmony import */ var _util_canReportError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(142); +/* harmony import */ var _util_toSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(153); +/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(154); +/* harmony import */ var _util_pipe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(155); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(146); +/** PURE_IMPORTS_START _util_canReportError,_util_toSubscriber,_symbol_observable,_util_pipe,_config PURE_IMPORTS_END */ - var monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i]; - var monthsRegex = /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i; - var nl = moment.defineLocale('nl', { - months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'), - monthsShort : function (m, format) { - if (!m) { - return monthsShortWithDots; - } else if (/-MMM-/.test(format)) { - return monthsShortWithoutDots[m.month()]; - } else { - return monthsShortWithDots[m.month()]; - } - }, - monthsRegex: monthsRegex, - monthsShortRegex: monthsRegex, - monthsStrictRegex: /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i, - monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i, - monthsParse : monthsParse, - longMonthsParse : monthsParse, - shortMonthsParse : monthsParse, - weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'), - weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'), - weekdaysMin : 'zo_ma_di_wo_do_vr_za'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD-MM-YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[vandaag om] LT', - nextDay: '[morgen om] LT', - nextWeek: 'dddd [om] LT', - lastDay: '[gisteren om] LT', - lastWeek: '[afgelopen] dddd [om] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'over %s', - past : '%s geleden', - s : 'een paar seconden', - ss : '%d seconden', - m : 'één minuut', - mm : '%d minuten', - h : 'één uur', - hh : '%d uur', - d : 'één dag', - dd : '%d dagen', - M : 'één maand', - MM : '%d maanden', - y : 'één jaar', - yy : '%d jaar' - }, - dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, - ordinal : function (number) { - return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. +var Observable = /*@__PURE__*/ (function () { + function Observable(subscribe) { + this._isScalar = false; + if (subscribe) { + this._subscribe = subscribe; } - }); - - return nl; + } + Observable.prototype.lift = function (operator) { + var observable = new Observable(); + observable.source = this; + observable.operator = operator; + return observable; + }; + Observable.prototype.subscribe = function (observerOrNext, error, complete) { + var operator = this.operator; + var sink = Object(_util_toSubscriber__WEBPACK_IMPORTED_MODULE_1__["toSubscriber"])(observerOrNext, error, complete); + if (operator) { + sink.add(operator.call(sink, this.source)); + } + else { + sink.add(this.source || (_config__WEBPACK_IMPORTED_MODULE_4__["config"].useDeprecatedSynchronousErrorHandling && !sink.syncErrorThrowable) ? + this._subscribe(sink) : + this._trySubscribe(sink)); + } + if (_config__WEBPACK_IMPORTED_MODULE_4__["config"].useDeprecatedSynchronousErrorHandling) { + if (sink.syncErrorThrowable) { + sink.syncErrorThrowable = false; + if (sink.syncErrorThrown) { + throw sink.syncErrorValue; + } + } + } + return sink; + }; + Observable.prototype._trySubscribe = function (sink) { + try { + return this._subscribe(sink); + } + catch (err) { + if (_config__WEBPACK_IMPORTED_MODULE_4__["config"].useDeprecatedSynchronousErrorHandling) { + sink.syncErrorThrown = true; + sink.syncErrorValue = err; + } + if (Object(_util_canReportError__WEBPACK_IMPORTED_MODULE_0__["canReportError"])(sink)) { + sink.error(err); + } + else { + console.warn(err); + } + } + }; + Observable.prototype.forEach = function (next, promiseCtor) { + var _this = this; + promiseCtor = getPromiseCtor(promiseCtor); + return new promiseCtor(function (resolve, reject) { + var subscription; + subscription = _this.subscribe(function (value) { + try { + next(value); + } + catch (err) { + reject(err); + if (subscription) { + subscription.unsubscribe(); + } + } + }, reject, resolve); + }); + }; + Observable.prototype._subscribe = function (subscriber) { + var source = this.source; + return source && source.subscribe(subscriber); + }; + Observable.prototype[_symbol_observable__WEBPACK_IMPORTED_MODULE_2__["observable"]] = function () { + return this; + }; + Observable.prototype.pipe = function () { + var operations = []; + for (var _i = 0; _i < arguments.length; _i++) { + operations[_i] = arguments[_i]; + } + if (operations.length === 0) { + return this; + } + return Object(_util_pipe__WEBPACK_IMPORTED_MODULE_3__["pipeFromArray"])(operations)(this); + }; + Observable.prototype.toPromise = function (promiseCtor) { + var _this = this; + promiseCtor = getPromiseCtor(promiseCtor); + return new promiseCtor(function (resolve, reject) { + var value; + _this.subscribe(function (x) { return value = x; }, function (err) { return reject(err); }, function () { return resolve(value); }); + }); + }; + Observable.create = function (subscribe) { + return new Observable(subscribe); + }; + return Observable; +}()); -}))); +function getPromiseCtor(promiseCtor) { + if (!promiseCtor) { + promiseCtor = _config__WEBPACK_IMPORTED_MODULE_4__["config"].Promise || Promise; + } + if (!promiseCtor) { + throw new Error('no Promise impl found'); + } + return promiseCtor; +} +//# sourceMappingURL=Observable.js.map /***/ }), -/* 128 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration - -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - +/* 142 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'), - monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_'); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "canReportError", function() { return canReportError; }); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(143); +/** PURE_IMPORTS_START _Subscriber PURE_IMPORTS_END */ - var monthsParse = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i]; - var monthsRegex = /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i; +function canReportError(observer) { + while (observer) { + var _a = observer, closed_1 = _a.closed, destination = _a.destination, isStopped = _a.isStopped; + if (closed_1 || isStopped) { + return false; + } + else if (destination && destination instanceof _Subscriber__WEBPACK_IMPORTED_MODULE_0__["Subscriber"]) { + observer = destination; + } + else { + observer = null; + } + } + return true; +} +//# sourceMappingURL=canReportError.js.map - var nlBe = moment.defineLocale('nl-be', { - months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'), - monthsShort : function (m, format) { - if (!m) { - return monthsShortWithDots; - } else if (/-MMM-/.test(format)) { - return monthsShortWithoutDots[m.month()]; - } else { - return monthsShortWithDots[m.month()]; - } - }, - monthsRegex: monthsRegex, - monthsShortRegex: monthsRegex, - monthsStrictRegex: /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i, - monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i, +/***/ }), +/* 143 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - monthsParse : monthsParse, - longMonthsParse : monthsParse, - shortMonthsParse : monthsParse, +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Subscriber", function() { return Subscriber; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SafeSubscriber", function() { return SafeSubscriber; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(144); +/* harmony import */ var _Observer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(145); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(148); +/* harmony import */ var _internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(152); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(146); +/* harmony import */ var _util_hostReportError__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(147); +/** PURE_IMPORTS_START tslib,_util_isFunction,_Observer,_Subscription,_internal_symbol_rxSubscriber,_config,_util_hostReportError PURE_IMPORTS_END */ - weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'), - weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'), - weekdaysMin : 'zo_ma_di_wo_do_vr_za'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[vandaag om] LT', - nextDay: '[morgen om] LT', - nextWeek: 'dddd [om] LT', - lastDay: '[gisteren om] LT', - lastWeek: '[afgelopen] dddd [om] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'over %s', - past : '%s geleden', - s : 'een paar seconden', - ss : '%d seconden', - m : 'één minuut', - mm : '%d minuten', - h : 'één uur', - hh : '%d uur', - d : 'één dag', - dd : '%d dagen', - M : 'één maand', - MM : '%d maanden', - y : 'één jaar', - yy : '%d jaar' - }, - dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, - ordinal : function (number) { - return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - return nlBe; -}))); -/***/ }), -/* 129 */ -/***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - - - var nn = moment.defineLocale('nn', { - months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), - monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), - weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'), - weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'), - weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY [kl.] H:mm', - LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm' - }, - calendar : { - sameDay: '[I dag klokka] LT', - nextDay: '[I morgon klokka] LT', - nextWeek: 'dddd [klokka] LT', - lastDay: '[I går klokka] LT', - lastWeek: '[Føregåande] dddd [klokka] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'om %s', - past : '%s sidan', - s : 'nokre sekund', - ss : '%d sekund', - m : 'eit minutt', - mm : '%d minutt', - h : 'ein time', - hh : '%d timar', - d : 'ein dag', - dd : '%d dagar', - M : 'ein månad', - MM : '%d månader', - y : 'eit år', - yy : '%d år' - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. +var Subscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](Subscriber, _super); + function Subscriber(destinationOrNext, error, complete) { + var _this = _super.call(this) || this; + _this.syncErrorValue = null; + _this.syncErrorThrown = false; + _this.syncErrorThrowable = false; + _this.isStopped = false; + switch (arguments.length) { + case 0: + _this.destination = _Observer__WEBPACK_IMPORTED_MODULE_2__["empty"]; + break; + case 1: + if (!destinationOrNext) { + _this.destination = _Observer__WEBPACK_IMPORTED_MODULE_2__["empty"]; + break; + } + if (typeof destinationOrNext === 'object') { + if (destinationOrNext instanceof Subscriber) { + _this.syncErrorThrowable = destinationOrNext.syncErrorThrowable; + _this.destination = destinationOrNext; + destinationOrNext.add(_this); + } + else { + _this.syncErrorThrowable = true; + _this.destination = new SafeSubscriber(_this, destinationOrNext); + } + break; + } + default: + _this.syncErrorThrowable = true; + _this.destination = new SafeSubscriber(_this, destinationOrNext, error, complete); + break; } - }); + return _this; + } + Subscriber.prototype[_internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_4__["rxSubscriber"]] = function () { return this; }; + Subscriber.create = function (next, error, complete) { + var subscriber = new Subscriber(next, error, complete); + subscriber.syncErrorThrowable = false; + return subscriber; + }; + Subscriber.prototype.next = function (value) { + if (!this.isStopped) { + this._next(value); + } + }; + Subscriber.prototype.error = function (err) { + if (!this.isStopped) { + this.isStopped = true; + this._error(err); + } + }; + Subscriber.prototype.complete = function () { + if (!this.isStopped) { + this.isStopped = true; + this._complete(); + } + }; + Subscriber.prototype.unsubscribe = function () { + if (this.closed) { + return; + } + this.isStopped = true; + _super.prototype.unsubscribe.call(this); + }; + Subscriber.prototype._next = function (value) { + this.destination.next(value); + }; + Subscriber.prototype._error = function (err) { + this.destination.error(err); + this.unsubscribe(); + }; + Subscriber.prototype._complete = function () { + this.destination.complete(); + this.unsubscribe(); + }; + Subscriber.prototype._unsubscribeAndRecycle = function () { + var _parentOrParents = this._parentOrParents; + this._parentOrParents = null; + this.unsubscribe(); + this.closed = false; + this.isStopped = false; + this._parentOrParents = _parentOrParents; + return this; + }; + return Subscriber; +}(_Subscription__WEBPACK_IMPORTED_MODULE_3__["Subscription"])); - return nn; +var SafeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SafeSubscriber, _super); + function SafeSubscriber(_parentSubscriber, observerOrNext, error, complete) { + var _this = _super.call(this) || this; + _this._parentSubscriber = _parentSubscriber; + var next; + var context = _this; + if (Object(_util_isFunction__WEBPACK_IMPORTED_MODULE_1__["isFunction"])(observerOrNext)) { + next = observerOrNext; + } + else if (observerOrNext) { + next = observerOrNext.next; + error = observerOrNext.error; + complete = observerOrNext.complete; + if (observerOrNext !== _Observer__WEBPACK_IMPORTED_MODULE_2__["empty"]) { + context = Object.create(observerOrNext); + if (Object(_util_isFunction__WEBPACK_IMPORTED_MODULE_1__["isFunction"])(context.unsubscribe)) { + _this.add(context.unsubscribe.bind(context)); + } + context.unsubscribe = _this.unsubscribe.bind(_this); + } + } + _this._context = context; + _this._next = next; + _this._error = error; + _this._complete = complete; + return _this; + } + SafeSubscriber.prototype.next = function (value) { + if (!this.isStopped && this._next) { + var _parentSubscriber = this._parentSubscriber; + if (!_config__WEBPACK_IMPORTED_MODULE_5__["config"].useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { + this.__tryOrUnsub(this._next, value); + } + else if (this.__tryOrSetError(_parentSubscriber, this._next, value)) { + this.unsubscribe(); + } + } + }; + SafeSubscriber.prototype.error = function (err) { + if (!this.isStopped) { + var _parentSubscriber = this._parentSubscriber; + var useDeprecatedSynchronousErrorHandling = _config__WEBPACK_IMPORTED_MODULE_5__["config"].useDeprecatedSynchronousErrorHandling; + if (this._error) { + if (!useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { + this.__tryOrUnsub(this._error, err); + this.unsubscribe(); + } + else { + this.__tryOrSetError(_parentSubscriber, this._error, err); + this.unsubscribe(); + } + } + else if (!_parentSubscriber.syncErrorThrowable) { + this.unsubscribe(); + if (useDeprecatedSynchronousErrorHandling) { + throw err; + } + Object(_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__["hostReportError"])(err); + } + else { + if (useDeprecatedSynchronousErrorHandling) { + _parentSubscriber.syncErrorValue = err; + _parentSubscriber.syncErrorThrown = true; + } + else { + Object(_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__["hostReportError"])(err); + } + this.unsubscribe(); + } + } + }; + SafeSubscriber.prototype.complete = function () { + var _this = this; + if (!this.isStopped) { + var _parentSubscriber = this._parentSubscriber; + if (this._complete) { + var wrappedComplete = function () { return _this._complete.call(_this._context); }; + if (!_config__WEBPACK_IMPORTED_MODULE_5__["config"].useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { + this.__tryOrUnsub(wrappedComplete); + this.unsubscribe(); + } + else { + this.__tryOrSetError(_parentSubscriber, wrappedComplete); + this.unsubscribe(); + } + } + else { + this.unsubscribe(); + } + } + }; + SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) { + try { + fn.call(this._context, value); + } + catch (err) { + this.unsubscribe(); + if (_config__WEBPACK_IMPORTED_MODULE_5__["config"].useDeprecatedSynchronousErrorHandling) { + throw err; + } + else { + Object(_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__["hostReportError"])(err); + } + } + }; + SafeSubscriber.prototype.__tryOrSetError = function (parent, fn, value) { + if (!_config__WEBPACK_IMPORTED_MODULE_5__["config"].useDeprecatedSynchronousErrorHandling) { + throw new Error('bad call'); + } + try { + fn.call(this._context, value); + } + catch (err) { + if (_config__WEBPACK_IMPORTED_MODULE_5__["config"].useDeprecatedSynchronousErrorHandling) { + parent.syncErrorValue = err; + parent.syncErrorThrown = true; + return true; + } + else { + Object(_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__["hostReportError"])(err); + return true; + } + } + return false; + }; + SafeSubscriber.prototype._unsubscribe = function () { + var _parentSubscriber = this._parentSubscriber; + this._context = null; + this._parentSubscriber = null; + _parentSubscriber.unsubscribe(); + }; + return SafeSubscriber; +}(Subscriber)); -}))); +//# sourceMappingURL=Subscriber.js.map /***/ }), -/* 130 */ -/***/ (function(module, exports, __webpack_require__) { +/* 144 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isFunction", function() { return isFunction; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function isFunction(x) { + return typeof x === 'function'; +} +//# sourceMappingURL=isFunction.js.map -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/***/ }), +/* 145 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "empty", function() { return empty; }); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(146); +/* harmony import */ var _util_hostReportError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(147); +/** PURE_IMPORTS_START _config,_util_hostReportError PURE_IMPORTS_END */ - var symbolMap = { - '1': '੧', - '2': '੨', - '3': '੩', - '4': '੪', - '5': '੫', - '6': '੬', - '7': '੭', - '8': '੮', - '9': '੯', - '0': '੦' + +var empty = { + closed: true, + next: function (value) { }, + error: function (err) { + if (_config__WEBPACK_IMPORTED_MODULE_0__["config"].useDeprecatedSynchronousErrorHandling) { + throw err; + } + else { + Object(_util_hostReportError__WEBPACK_IMPORTED_MODULE_1__["hostReportError"])(err); + } }, - numberMap = { - '੧': '1', - '੨': '2', - '੩': '3', - '੪': '4', - '੫': '5', - '੬': '6', - '੭': '7', - '੮': '8', - '੯': '9', - '੦': '0' - }; + complete: function () { } +}; +//# sourceMappingURL=Observer.js.map - var paIn = moment.defineLocale('pa-in', { - // There are months name as per Nanakshahi Calendar but they are not used as rigidly in modern Punjabi. - months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'), - monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'), - weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'), - weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'), - weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'), - longDateFormat : { - LT : 'A h:mm ਵਜੇ', - LTS : 'A h:mm:ss ਵਜੇ', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm ਵਜੇ', - LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ' - }, - calendar : { - sameDay : '[ਅਜ] LT', - nextDay : '[ਕਲ] LT', - nextWeek : '[ਅਗਲਾ] dddd, LT', - lastDay : '[ਕਲ] LT', - lastWeek : '[ਪਿਛਲੇ] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s ਵਿੱਚ', - past : '%s ਪਿਛਲੇ', - s : 'ਕੁਝ ਸਕਿੰਟ', - ss : '%d ਸਕਿੰਟ', - m : 'ਇਕ ਮਿੰਟ', - mm : '%d ਮਿੰਟ', - h : 'ਇੱਕ ਘੰਟਾ', - hh : '%d ਘੰਟੇ', - d : 'ਇੱਕ ਦਿਨ', - dd : '%d ਦਿਨ', - M : 'ਇੱਕ ਮਹੀਨਾ', - MM : '%d ਮਹੀਨੇ', - y : 'ਇੱਕ ਸਾਲ', - yy : '%d ਸਾਲ' - }, - preparse: function (string) { - return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); - }, - // Punjabi notation for meridiems are quite fuzzy in practice. While there exists - // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi. - meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'ਰਾਤ') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'ਸਵੇਰ') { - return hour; - } else if (meridiem === 'ਦੁਪਹਿਰ') { - return hour >= 10 ? hour : hour + 12; - } else if (meridiem === 'ਸ਼ਾਮ') { - return hour + 12; - } - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'ਰਾਤ'; - } else if (hour < 10) { - return 'ਸਵੇਰ'; - } else if (hour < 17) { - return 'ਦੁਪਹਿਰ'; - } else if (hour < 20) { - return 'ਸ਼ਾਮ'; - } else { - return 'ਰਾਤ'; - } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. + +/***/ }), +/* 146 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "config", function() { return config; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var _enable_super_gross_mode_that_will_cause_bad_things = false; +var config = { + Promise: undefined, + set useDeprecatedSynchronousErrorHandling(value) { + if (value) { + var error = /*@__PURE__*/ new Error(); + /*@__PURE__*/ console.warn('DEPRECATED! RxJS was set to use deprecated synchronous error handling behavior by code at: \n' + error.stack); } - }); + else if (_enable_super_gross_mode_that_will_cause_bad_things) { + /*@__PURE__*/ console.log('RxJS: Back to a better error behavior. Thank you. <3'); + } + _enable_super_gross_mode_that_will_cause_bad_things = value; + }, + get useDeprecatedSynchronousErrorHandling() { + return _enable_super_gross_mode_that_will_cause_bad_things; + }, +}; +//# sourceMappingURL=config.js.map - return paIn; -}))); +/***/ }), +/* 147 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hostReportError", function() { return hostReportError; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function hostReportError(err) { + setTimeout(function () { throw err; }, 0); +} +//# sourceMappingURL=hostReportError.js.map /***/ }), -/* 131 */ -/***/ (function(module, exports, __webpack_require__) { +/* 148 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Subscription", function() { return Subscription; }); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(149); +/* harmony import */ var _util_isObject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(150); +/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); +/* harmony import */ var _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(151); +/** PURE_IMPORTS_START _util_isArray,_util_isObject,_util_isFunction,_util_UnsubscriptionError PURE_IMPORTS_END */ -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'), - monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_'); - function plural(n) { - return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1); - } - function translate(number, withoutSuffix, key) { - var result = number + ' '; - switch (key) { - case 'ss': - return result + (plural(number) ? 'sekundy' : 'sekund'); - case 'm': - return withoutSuffix ? 'minuta' : 'minutę'; - case 'mm': - return result + (plural(number) ? 'minuty' : 'minut'); - case 'h': - return withoutSuffix ? 'godzina' : 'godzinę'; - case 'hh': - return result + (plural(number) ? 'godziny' : 'godzin'); - case 'MM': - return result + (plural(number) ? 'miesiące' : 'miesięcy'); - case 'yy': - return result + (plural(number) ? 'lata' : 'lat'); + +var Subscription = /*@__PURE__*/ (function () { + function Subscription(unsubscribe) { + this.closed = false; + this._parentOrParents = null; + this._subscriptions = null; + if (unsubscribe) { + this._unsubscribe = unsubscribe; } } - - var pl = moment.defineLocale('pl', { - months : function (momentToFormat, format) { - if (!momentToFormat) { - return monthsNominative; - } else if (format === '') { - // Hack: if format empty we know this is used to generate - // RegExp by moment. Give then back both valid forms of months - // in RegExp ready format. - return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')'; - } else if (/D MMMM/.test(format)) { - return monthsSubjective[momentToFormat.month()]; - } else { - return monthsNominative[momentToFormat.month()]; - } - }, - monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'), - weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'), - weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'), - weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[Dziś o] LT', - nextDay: '[Jutro o] LT', - nextWeek: function () { - switch (this.day()) { - case 0: - return '[W niedzielę o] LT'; - - case 2: - return '[We wtorek o] LT'; - - case 3: - return '[W środę o] LT'; - - case 6: - return '[W sobotę o] LT'; - - default: - return '[W] dddd [o] LT'; + Subscription.prototype.unsubscribe = function () { + var errors; + if (this.closed) { + return; + } + var _a = this, _parentOrParents = _a._parentOrParents, _unsubscribe = _a._unsubscribe, _subscriptions = _a._subscriptions; + this.closed = true; + this._parentOrParents = null; + this._subscriptions = null; + if (_parentOrParents instanceof Subscription) { + _parentOrParents.remove(this); + } + else if (_parentOrParents !== null) { + for (var index = 0; index < _parentOrParents.length; ++index) { + var parent_1 = _parentOrParents[index]; + parent_1.remove(this); + } + } + if (Object(_util_isFunction__WEBPACK_IMPORTED_MODULE_2__["isFunction"])(_unsubscribe)) { + try { + _unsubscribe.call(this); + } + catch (e) { + errors = e instanceof _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_3__["UnsubscriptionError"] ? flattenUnsubscriptionErrors(e.errors) : [e]; + } + } + if (Object(_util_isArray__WEBPACK_IMPORTED_MODULE_0__["isArray"])(_subscriptions)) { + var index = -1; + var len = _subscriptions.length; + while (++index < len) { + var sub = _subscriptions[index]; + if (Object(_util_isObject__WEBPACK_IMPORTED_MODULE_1__["isObject"])(sub)) { + try { + sub.unsubscribe(); + } + catch (e) { + errors = errors || []; + if (e instanceof _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_3__["UnsubscriptionError"]) { + errors = errors.concat(flattenUnsubscriptionErrors(e.errors)); + } + else { + errors.push(e); + } + } } - }, - lastDay: '[Wczoraj o] LT', - lastWeek: function () { - switch (this.day()) { - case 0: - return '[W zeszłą niedzielę o] LT'; - case 3: - return '[W zeszłą środę o] LT'; - case 6: - return '[W zeszłą sobotę o] LT'; - default: - return '[W zeszły] dddd [o] LT'; + } + } + if (errors) { + throw new _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_3__["UnsubscriptionError"](errors); + } + }; + Subscription.prototype.add = function (teardown) { + var subscription = teardown; + if (!teardown) { + return Subscription.EMPTY; + } + switch (typeof teardown) { + case 'function': + subscription = new Subscription(teardown); + case 'object': + if (subscription === this || subscription.closed || typeof subscription.unsubscribe !== 'function') { + return subscription; } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'za %s', - past : '%s temu', - s : 'kilka sekund', - ss : translate, - m : translate, - mm : translate, - h : translate, - hh : translate, - d : '1 dzień', - dd : '%d dni', - M : 'miesiąc', - MM : translate, - y : 'rok', - yy : translate - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + else if (this.closed) { + subscription.unsubscribe(); + return subscription; + } + else if (!(subscription instanceof Subscription)) { + var tmp = subscription; + subscription = new Subscription(); + subscription._subscriptions = [tmp]; + } + break; + default: { + throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.'); + } } - }); - - return pl; + var _parentOrParents = subscription._parentOrParents; + if (_parentOrParents === null) { + subscription._parentOrParents = this; + } + else if (_parentOrParents instanceof Subscription) { + if (_parentOrParents === this) { + return subscription; + } + subscription._parentOrParents = [_parentOrParents, this]; + } + else if (_parentOrParents.indexOf(this) === -1) { + _parentOrParents.push(this); + } + else { + return subscription; + } + var subscriptions = this._subscriptions; + if (subscriptions === null) { + this._subscriptions = [subscription]; + } + else { + subscriptions.push(subscription); + } + return subscription; + }; + Subscription.prototype.remove = function (subscription) { + var subscriptions = this._subscriptions; + if (subscriptions) { + var subscriptionIndex = subscriptions.indexOf(subscription); + if (subscriptionIndex !== -1) { + subscriptions.splice(subscriptionIndex, 1); + } + } + }; + Subscription.EMPTY = (function (empty) { + empty.closed = true; + return empty; + }(new Subscription())); + return Subscription; +}()); -}))); +function flattenUnsubscriptionErrors(errors) { + return errors.reduce(function (errs, err) { return errs.concat((err instanceof _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_3__["UnsubscriptionError"]) ? err.errors : err); }, []); +} +//# sourceMappingURL=Subscription.js.map /***/ }), -/* 132 */ -/***/ (function(module, exports, __webpack_require__) { +/* 149 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isArray", function() { return isArray; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var isArray = /*@__PURE__*/ (function () { return Array.isArray || (function (x) { return x && typeof x.length === 'number'; }); })(); +//# sourceMappingURL=isArray.js.map -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/***/ }), +/* 150 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - var pt = moment.defineLocale('pt', { - months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'), - monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'), - weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'), - weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), - weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D [de] MMMM [de] YYYY', - LLL : 'D [de] MMMM [de] YYYY HH:mm', - LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm' - }, - calendar : { - sameDay: '[Hoje às] LT', - nextDay: '[Amanhã às] LT', - nextWeek: 'dddd [às] LT', - lastDay: '[Ontem às] LT', - lastWeek: function () { - return (this.day() === 0 || this.day() === 6) ? - '[Último] dddd [às] LT' : // Saturday + Sunday - '[Última] dddd [às] LT'; // Monday - Friday - }, - sameElse: 'L' - }, - relativeTime : { - future : 'em %s', - past : 'há %s', - s : 'segundos', - ss : '%d segundos', - m : 'um minuto', - mm : '%d minutos', - h : 'uma hora', - hh : '%d horas', - d : 'um dia', - dd : '%d dias', - M : 'um mês', - MM : '%d meses', - y : 'um ano', - yy : '%d anos' - }, - dayOfMonthOrdinalParse: /\d{1,2}º/, - ordinal : '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isObject", function() { return isObject; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function isObject(x) { + return x !== null && typeof x === 'object'; +} +//# sourceMappingURL=isObject.js.map - return pt; -}))); +/***/ }), +/* 151 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UnsubscriptionError", function() { return UnsubscriptionError; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var UnsubscriptionErrorImpl = /*@__PURE__*/ (function () { + function UnsubscriptionErrorImpl(errors) { + Error.call(this); + this.message = errors ? + errors.length + " errors occurred during unsubscription:\n" + errors.map(function (err, i) { return i + 1 + ") " + err.toString(); }).join('\n ') : ''; + this.name = 'UnsubscriptionError'; + this.errors = errors; + return this; + } + UnsubscriptionErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); + return UnsubscriptionErrorImpl; +})(); +var UnsubscriptionError = UnsubscriptionErrorImpl; +//# sourceMappingURL=UnsubscriptionError.js.map /***/ }), -/* 133 */ -/***/ (function(module, exports, __webpack_require__) { +/* 152 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rxSubscriber", function() { return rxSubscriber; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "$$rxSubscriber", function() { return $$rxSubscriber; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var rxSubscriber = /*@__PURE__*/ (function () { + return typeof Symbol === 'function' + ? /*@__PURE__*/ Symbol('rxSubscriber') + : '@@rxSubscriber_' + /*@__PURE__*/ Math.random(); +})(); +var $$rxSubscriber = rxSubscriber; +//# sourceMappingURL=rxSubscriber.js.map -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/***/ }), +/* 153 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - var ptBr = moment.defineLocale('pt-br', { - months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'), - monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'), - weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'), - weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), - weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D [de] MMMM [de] YYYY', - LLL : 'D [de] MMMM [de] YYYY [às] HH:mm', - LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm' - }, - calendar : { - sameDay: '[Hoje às] LT', - nextDay: '[Amanhã às] LT', - nextWeek: 'dddd [às] LT', - lastDay: '[Ontem às] LT', - lastWeek: function () { - return (this.day() === 0 || this.day() === 6) ? - '[Último] dddd [às] LT' : // Saturday + Sunday - '[Última] dddd [às] LT'; // Monday - Friday - }, - sameElse: 'L' - }, - relativeTime : { - future : 'em %s', - past : 'há %s', - s : 'poucos segundos', - ss : '%d segundos', - m : 'um minuto', - mm : '%d minutos', - h : 'uma hora', - hh : '%d horas', - d : 'um dia', - dd : '%d dias', - M : 'um mês', - MM : '%d meses', - y : 'um ano', - yy : '%d anos' - }, - dayOfMonthOrdinalParse: /\d{1,2}º/, - ordinal : '%dº' - }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toSubscriber", function() { return toSubscriber; }); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(143); +/* harmony import */ var _symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(152); +/* harmony import */ var _Observer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(145); +/** PURE_IMPORTS_START _Subscriber,_symbol_rxSubscriber,_Observer PURE_IMPORTS_END */ - return ptBr; -}))); + +function toSubscriber(nextOrObserver, error, complete) { + if (nextOrObserver) { + if (nextOrObserver instanceof _Subscriber__WEBPACK_IMPORTED_MODULE_0__["Subscriber"]) { + return nextOrObserver; + } + if (nextOrObserver[_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_1__["rxSubscriber"]]) { + return nextOrObserver[_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_1__["rxSubscriber"]](); + } + } + if (!nextOrObserver && !error && !complete) { + return new _Subscriber__WEBPACK_IMPORTED_MODULE_0__["Subscriber"](_Observer__WEBPACK_IMPORTED_MODULE_2__["empty"]); + } + return new _Subscriber__WEBPACK_IMPORTED_MODULE_0__["Subscriber"](nextOrObserver, error, complete); +} +//# sourceMappingURL=toSubscriber.js.map /***/ }), -/* 134 */ -/***/ (function(module, exports, __webpack_require__) { +/* 154 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "observable", function() { return observable; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var observable = /*@__PURE__*/ (function () { return typeof Symbol === 'function' && Symbol.observable || '@@observable'; })(); +//# sourceMappingURL=observable.js.map -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/***/ }), +/* 155 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - function relativeTimeWithPlural(number, withoutSuffix, key) { - var format = { - 'ss': 'secunde', - 'mm': 'minute', - 'hh': 'ore', - 'dd': 'zile', - 'MM': 'luni', - 'yy': 'ani' - }, - separator = ' '; - if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) { - separator = ' de '; - } - return number + separator + format[key]; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pipe", function() { return pipe; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pipeFromArray", function() { return pipeFromArray; }); +/* harmony import */ var _noop__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(156); +/** PURE_IMPORTS_START _noop PURE_IMPORTS_END */ + +function pipe() { + var fns = []; + for (var _i = 0; _i < arguments.length; _i++) { + fns[_i] = arguments[_i]; + } + return pipeFromArray(fns); +} +function pipeFromArray(fns) { + if (!fns) { + return _noop__WEBPACK_IMPORTED_MODULE_0__["noop"]; + } + if (fns.length === 1) { + return fns[0]; } + return function piped(input) { + return fns.reduce(function (prev, fn) { return fn(prev); }, input); + }; +} +//# sourceMappingURL=pipe.js.map - var ro = moment.defineLocale('ro', { - months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'), - monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'), - monthsParseExact: true, - weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'), - weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'), - weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'), - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY H:mm', - LLLL : 'dddd, D MMMM YYYY H:mm' - }, - calendar : { - sameDay: '[azi la] LT', - nextDay: '[mâine la] LT', - nextWeek: 'dddd [la] LT', - lastDay: '[ieri la] LT', - lastWeek: '[fosta] dddd [la] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'peste %s', - past : '%s în urmă', - s : 'câteva secunde', - ss : relativeTimeWithPlural, - m : 'un minut', - mm : relativeTimeWithPlural, - h : 'o oră', - hh : relativeTimeWithPlural, - d : 'o zi', - dd : relativeTimeWithPlural, - M : 'o lună', - MM : relativeTimeWithPlural, - y : 'un an', - yy : relativeTimeWithPlural - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - return ro; +/***/ }), +/* 156 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -}))); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "noop", function() { return noop; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function noop() { } +//# sourceMappingURL=noop.js.map /***/ }), -/* 135 */ -/***/ (function(module, exports, __webpack_require__) { +/* 157 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ConnectableObservable", function() { return ConnectableObservable; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "connectableObservableDescriptor", function() { return connectableObservableDescriptor; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(158); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(141); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(143); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(148); +/* harmony import */ var _operators_refCount__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(161); +/** PURE_IMPORTS_START tslib,_Subject,_Observable,_Subscriber,_Subscription,_operators_refCount PURE_IMPORTS_END */ -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - function plural(word, num) { - var forms = word.split('_'); - return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); - } - function relativeTimeWithPlural(number, withoutSuffix, key) { - var format = { - 'ss': withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд', - 'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут', - 'hh': 'час_часа_часов', - 'dd': 'день_дня_дней', - 'MM': 'месяц_месяца_месяцев', - 'yy': 'год_года_лет' - }; - if (key === 'm') { - return withoutSuffix ? 'минута' : 'минуту'; - } - else { - return number + ' ' + plural(format[key], +number); - } - } - var monthsParse = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i]; - - // http://new.gramota.ru/spravka/rules/139-prop : § 103 - // Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637 - // CLDR data: http://www.unicode.org/cldr/charts/28/summary/ru.html#1753 - var ru = moment.defineLocale('ru', { - months : { - format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'), - standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_') - }, - monthsShort : { - // по CLDR именно "июл." и "июн.", но какой смысл менять букву на точку ? - format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'), - standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_') - }, - weekdays : { - standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'), - format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'), - isFormat: /\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/ - }, - weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'), - weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'), - monthsParse : monthsParse, - longMonthsParse : monthsParse, - shortMonthsParse : monthsParse, - - // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки - monthsRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i, - // копия предыдущего - monthsShortRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i, - // полные названия с падежами - monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i, - // Выражение, которое соотвествует только сокращённым формам - monthsShortStrictRegex: /^(янв\.|февр?\.|мар[т.]|апр\.|ма[яй]|июн[ья.]|июл[ья.]|авг\.|сент?\.|окт\.|нояб?\.|дек\.)/i, - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY г.', - LLL : 'D MMMM YYYY г., H:mm', - LLLL : 'dddd, D MMMM YYYY г., H:mm' - }, - calendar : { - sameDay: '[Сегодня, в] LT', - nextDay: '[Завтра, в] LT', - lastDay: '[Вчера, в] LT', - nextWeek: function (now) { - if (now.week() !== this.week()) { - switch (this.day()) { - case 0: - return '[В следующее] dddd, [в] LT'; - case 1: - case 2: - case 4: - return '[В следующий] dddd, [в] LT'; - case 3: - case 5: - case 6: - return '[В следующую] dddd, [в] LT'; - } - } else { - if (this.day() === 2) { - return '[Во] dddd, [в] LT'; - } else { - return '[В] dddd, [в] LT'; - } - } - }, - lastWeek: function (now) { - if (now.week() !== this.week()) { - switch (this.day()) { - case 0: - return '[В прошлое] dddd, [в] LT'; - case 1: - case 2: - case 4: - return '[В прошлый] dddd, [в] LT'; - case 3: - case 5: - case 6: - return '[В прошлую] dddd, [в] LT'; - } - } else { - if (this.day() === 2) { - return '[Во] dddd, [в] LT'; - } else { - return '[В] dddd, [в] LT'; - } - } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'через %s', - past : '%s назад', - s : 'несколько секунд', - ss : relativeTimeWithPlural, - m : relativeTimeWithPlural, - mm : relativeTimeWithPlural, - h : 'час', - hh : relativeTimeWithPlural, - d : 'день', - dd : relativeTimeWithPlural, - M : 'месяц', - MM : relativeTimeWithPlural, - y : 'год', - yy : relativeTimeWithPlural - }, - meridiemParse: /ночи|утра|дня|вечера/i, - isPM : function (input) { - return /^(дня|вечера)$/.test(input); - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'ночи'; - } else if (hour < 12) { - return 'утра'; - } else if (hour < 17) { - return 'дня'; - } else { - return 'вечера'; - } - }, - dayOfMonthOrdinalParse: /\d{1,2}-(й|го|я)/, - ordinal: function (number, period) { - switch (period) { - case 'M': - case 'd': - case 'DDD': - return number + '-й'; - case 'D': - return number + '-го'; - case 'w': - case 'W': - return number + '-я'; - default: - return number; +var ConnectableObservable = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ConnectableObservable, _super); + function ConnectableObservable(source, subjectFactory) { + var _this = _super.call(this) || this; + _this.source = source; + _this.subjectFactory = subjectFactory; + _this._refCount = 0; + _this._isComplete = false; + return _this; + } + ConnectableObservable.prototype._subscribe = function (subscriber) { + return this.getSubject().subscribe(subscriber); + }; + ConnectableObservable.prototype.getSubject = function () { + var subject = this._subject; + if (!subject || subject.isStopped) { + this._subject = this.subjectFactory(); + } + return this._subject; + }; + ConnectableObservable.prototype.connect = function () { + var connection = this._connection; + if (!connection) { + this._isComplete = false; + connection = this._connection = new _Subscription__WEBPACK_IMPORTED_MODULE_4__["Subscription"](); + connection.add(this.source + .subscribe(new ConnectableSubscriber(this.getSubject(), this))); + if (connection.closed) { + this._connection = null; + connection = _Subscription__WEBPACK_IMPORTED_MODULE_4__["Subscription"].EMPTY; } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. } - }); - - return ru; - -}))); - - -/***/ }), -/* 136 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration - -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - - - var months = [ - 'جنوري', - 'فيبروري', - 'مارچ', - 'اپريل', - 'مئي', - 'جون', - 'جولاءِ', - 'آگسٽ', - 'سيپٽمبر', - 'آڪٽوبر', - 'نومبر', - 'ڊسمبر' - ]; - var days = [ - 'آچر', - 'سومر', - 'اڱارو', - 'اربع', - 'خميس', - 'جمع', - 'ڇنڇر' - ]; + return connection; + }; + ConnectableObservable.prototype.refCount = function () { + return Object(_operators_refCount__WEBPACK_IMPORTED_MODULE_5__["refCount"])()(this); + }; + return ConnectableObservable; +}(_Observable__WEBPACK_IMPORTED_MODULE_2__["Observable"])); - var sd = moment.defineLocale('sd', { - months : months, - monthsShort : months, - weekdays : days, - weekdaysShort : days, - weekdaysMin : days, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd، D MMMM YYYY HH:mm' - }, - meridiemParse: /صبح|شام/, - isPM : function (input) { - return 'شام' === input; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'صبح'; +var connectableObservableDescriptor = /*@__PURE__*/ (function () { + var connectableProto = ConnectableObservable.prototype; + return { + operator: { value: null }, + _refCount: { value: 0, writable: true }, + _subject: { value: null, writable: true }, + _connection: { value: null, writable: true }, + _subscribe: { value: connectableProto._subscribe }, + _isComplete: { value: connectableProto._isComplete, writable: true }, + getSubject: { value: connectableProto.getSubject }, + connect: { value: connectableProto.connect }, + refCount: { value: connectableProto.refCount } + }; +})(); +var ConnectableSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ConnectableSubscriber, _super); + function ConnectableSubscriber(destination, connectable) { + var _this = _super.call(this, destination) || this; + _this.connectable = connectable; + return _this; + } + ConnectableSubscriber.prototype._error = function (err) { + this._unsubscribe(); + _super.prototype._error.call(this, err); + }; + ConnectableSubscriber.prototype._complete = function () { + this.connectable._isComplete = true; + this._unsubscribe(); + _super.prototype._complete.call(this); + }; + ConnectableSubscriber.prototype._unsubscribe = function () { + var connectable = this.connectable; + if (connectable) { + this.connectable = null; + var connection = connectable._connection; + connectable._refCount = 0; + connectable._subject = null; + connectable._connection = null; + if (connection) { + connection.unsubscribe(); } - return 'شام'; - }, - calendar : { - sameDay : '[اڄ] LT', - nextDay : '[سڀاڻي] LT', - nextWeek : 'dddd [اڳين هفتي تي] LT', - lastDay : '[ڪالهه] LT', - lastWeek : '[گزريل هفتي] dddd [تي] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s پوء', - past : '%s اڳ', - s : 'چند سيڪنڊ', - ss : '%d سيڪنڊ', - m : 'هڪ منٽ', - mm : '%d منٽ', - h : 'هڪ ڪلاڪ', - hh : '%d ڪلاڪ', - d : 'هڪ ڏينهن', - dd : '%d ڏينهن', - M : 'هڪ مهينو', - MM : '%d مهينا', - y : 'هڪ سال', - yy : '%d سال' - }, - preparse: function (string) { - return string.replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/,/g, '،'); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. } - }); - - return sd; - -}))); + }; + return ConnectableSubscriber; +}(_Subject__WEBPACK_IMPORTED_MODULE_1__["SubjectSubscriber"])); +var RefCountOperator = /*@__PURE__*/ (function () { + function RefCountOperator(connectable) { + this.connectable = connectable; + } + RefCountOperator.prototype.call = function (subscriber, source) { + var connectable = this.connectable; + connectable._refCount++; + var refCounter = new RefCountSubscriber(subscriber, connectable); + var subscription = source.subscribe(refCounter); + if (!refCounter.closed) { + refCounter.connection = connectable.connect(); + } + return subscription; + }; + return RefCountOperator; +}()); +var RefCountSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RefCountSubscriber, _super); + function RefCountSubscriber(destination, connectable) { + var _this = _super.call(this, destination) || this; + _this.connectable = connectable; + return _this; + } + RefCountSubscriber.prototype._unsubscribe = function () { + var connectable = this.connectable; + if (!connectable) { + this.connection = null; + return; + } + this.connectable = null; + var refCount = connectable._refCount; + if (refCount <= 0) { + this.connection = null; + return; + } + connectable._refCount = refCount - 1; + if (refCount > 1) { + this.connection = null; + return; + } + var connection = this.connection; + var sharedConnection = connectable._connection; + this.connection = null; + if (sharedConnection && (!connection || sharedConnection === connection)) { + sharedConnection.unsubscribe(); + } + }; + return RefCountSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__["Subscriber"])); +//# sourceMappingURL=ConnectableObservable.js.map /***/ }), -/* 137 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration - -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - +/* 158 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - var se = moment.defineLocale('se', { - months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'), - monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'), - weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'), - weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'), - weekdaysMin : 's_v_m_g_d_b_L'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'MMMM D. [b.] YYYY', - LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm', - LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm' - }, - calendar : { - sameDay: '[otne ti] LT', - nextDay: '[ihttin ti] LT', - nextWeek: 'dddd [ti] LT', - lastDay: '[ikte ti] LT', - lastWeek: '[ovddit] dddd [ti] LT', - sameElse: 'L' - }, - relativeTime : { - future : '%s geažes', - past : 'maŋit %s', - s : 'moadde sekunddat', - ss: '%d sekunddat', - m : 'okta minuhta', - mm : '%d minuhtat', - h : 'okta diimmu', - hh : '%d diimmut', - d : 'okta beaivi', - dd : '%d beaivvit', - M : 'okta mánnu', - MM : '%d mánut', - y : 'okta jahki', - yy : '%d jagit' - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubjectSubscriber", function() { return SubjectSubscriber; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Subject", function() { return Subject; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnonymousSubject", function() { return AnonymousSubject; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(141); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(143); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(148); +/* harmony import */ var _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(159); +/* harmony import */ var _SubjectSubscription__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(160); +/* harmony import */ var _internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(152); +/** PURE_IMPORTS_START tslib,_Observable,_Subscriber,_Subscription,_util_ObjectUnsubscribedError,_SubjectSubscription,_internal_symbol_rxSubscriber PURE_IMPORTS_END */ - return se; -}))); -/***/ }), -/* 138 */ -/***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +var SubjectSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubjectSubscriber, _super); + function SubjectSubscriber(destination) { + var _this = _super.call(this, destination) || this; + _this.destination = destination; + return _this; + } + return SubjectSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_2__["Subscriber"])); - /*jshint -W100*/ - var si = moment.defineLocale('si', { - months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'), - monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'), - weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'), - weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'), - weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'a h:mm', - LTS : 'a h:mm:ss', - L : 'YYYY/MM/DD', - LL : 'YYYY MMMM D', - LLL : 'YYYY MMMM D, a h:mm', - LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss' - }, - calendar : { - sameDay : '[අද] LT[ට]', - nextDay : '[හෙට] LT[ට]', - nextWeek : 'dddd LT[ට]', - lastDay : '[ඊයේ] LT[ට]', - lastWeek : '[පසුගිය] dddd LT[ට]', - sameElse : 'L' - }, - relativeTime : { - future : '%sකින්', - past : '%sකට පෙර', - s : 'තත්පර කිහිපය', - ss : 'තත්පර %d', - m : 'මිනිත්තුව', - mm : 'මිනිත්තු %d', - h : 'පැය', - hh : 'පැය %d', - d : 'දිනය', - dd : 'දින %d', - M : 'මාසය', - MM : 'මාස %d', - y : 'වසර', - yy : 'වසර %d' - }, - dayOfMonthOrdinalParse: /\d{1,2} වැනි/, - ordinal : function (number) { - return number + ' වැනි'; - }, - meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./, - isPM : function (input) { - return input === 'ප.ව.' || input === 'පස් වරු'; - }, - meridiem : function (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'ප.ව.' : 'පස් වරු'; - } else { - return isLower ? 'පෙ.ව.' : 'පෙර වරු'; +var Subject = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](Subject, _super); + function Subject() { + var _this = _super.call(this) || this; + _this.observers = []; + _this.closed = false; + _this.isStopped = false; + _this.hasError = false; + _this.thrownError = null; + return _this; + } + Subject.prototype[_internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_6__["rxSubscriber"]] = function () { + return new SubjectSubscriber(this); + }; + Subject.prototype.lift = function (operator) { + var subject = new AnonymousSubject(this, this); + subject.operator = operator; + return subject; + }; + Subject.prototype.next = function (value) { + if (this.closed) { + throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_4__["ObjectUnsubscribedError"](); + } + if (!this.isStopped) { + var observers = this.observers; + var len = observers.length; + var copy = observers.slice(); + for (var i = 0; i < len; i++) { + copy[i].next(value); } } - }); + }; + Subject.prototype.error = function (err) { + if (this.closed) { + throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_4__["ObjectUnsubscribedError"](); + } + this.hasError = true; + this.thrownError = err; + this.isStopped = true; + var observers = this.observers; + var len = observers.length; + var copy = observers.slice(); + for (var i = 0; i < len; i++) { + copy[i].error(err); + } + this.observers.length = 0; + }; + Subject.prototype.complete = function () { + if (this.closed) { + throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_4__["ObjectUnsubscribedError"](); + } + this.isStopped = true; + var observers = this.observers; + var len = observers.length; + var copy = observers.slice(); + for (var i = 0; i < len; i++) { + copy[i].complete(); + } + this.observers.length = 0; + }; + Subject.prototype.unsubscribe = function () { + this.isStopped = true; + this.closed = true; + this.observers = null; + }; + Subject.prototype._trySubscribe = function (subscriber) { + if (this.closed) { + throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_4__["ObjectUnsubscribedError"](); + } + else { + return _super.prototype._trySubscribe.call(this, subscriber); + } + }; + Subject.prototype._subscribe = function (subscriber) { + if (this.closed) { + throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_4__["ObjectUnsubscribedError"](); + } + else if (this.hasError) { + subscriber.error(this.thrownError); + return _Subscription__WEBPACK_IMPORTED_MODULE_3__["Subscription"].EMPTY; + } + else if (this.isStopped) { + subscriber.complete(); + return _Subscription__WEBPACK_IMPORTED_MODULE_3__["Subscription"].EMPTY; + } + else { + this.observers.push(subscriber); + return new _SubjectSubscription__WEBPACK_IMPORTED_MODULE_5__["SubjectSubscription"](this, subscriber); + } + }; + Subject.prototype.asObservable = function () { + var observable = new _Observable__WEBPACK_IMPORTED_MODULE_1__["Observable"](); + observable.source = this; + return observable; + }; + Subject.create = function (destination, source) { + return new AnonymousSubject(destination, source); + }; + return Subject; +}(_Observable__WEBPACK_IMPORTED_MODULE_1__["Observable"])); - return si; +var AnonymousSubject = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AnonymousSubject, _super); + function AnonymousSubject(destination, source) { + var _this = _super.call(this) || this; + _this.destination = destination; + _this.source = source; + return _this; + } + AnonymousSubject.prototype.next = function (value) { + var destination = this.destination; + if (destination && destination.next) { + destination.next(value); + } + }; + AnonymousSubject.prototype.error = function (err) { + var destination = this.destination; + if (destination && destination.error) { + this.destination.error(err); + } + }; + AnonymousSubject.prototype.complete = function () { + var destination = this.destination; + if (destination && destination.complete) { + this.destination.complete(); + } + }; + AnonymousSubject.prototype._subscribe = function (subscriber) { + var source = this.source; + if (source) { + return this.source.subscribe(subscriber); + } + else { + return _Subscription__WEBPACK_IMPORTED_MODULE_3__["Subscription"].EMPTY; + } + }; + return AnonymousSubject; +}(Subject)); -}))); +//# sourceMappingURL=Subject.js.map /***/ }), -/* 139 */ -/***/ (function(module, exports, __webpack_require__) { +/* 159 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ObjectUnsubscribedError", function() { return ObjectUnsubscribedError; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var ObjectUnsubscribedErrorImpl = /*@__PURE__*/ (function () { + function ObjectUnsubscribedErrorImpl() { + Error.call(this); + this.message = 'object unsubscribed'; + this.name = 'ObjectUnsubscribedError'; + return this; + } + ObjectUnsubscribedErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); + return ObjectUnsubscribedErrorImpl; +})(); +var ObjectUnsubscribedError = ObjectUnsubscribedErrorImpl; +//# sourceMappingURL=ObjectUnsubscribedError.js.map -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/***/ }), +/* 160 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - var months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'), - monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_'); - function plural(n) { - return (n > 1) && (n < 5); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubjectSubscription", function() { return SubjectSubscription; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(148); +/** PURE_IMPORTS_START tslib,_Subscription PURE_IMPORTS_END */ + + +var SubjectSubscription = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubjectSubscription, _super); + function SubjectSubscription(subject, subscriber) { + var _this = _super.call(this) || this; + _this.subject = subject; + _this.subscriber = subscriber; + _this.closed = false; + return _this; } - function translate(number, withoutSuffix, key, isFuture) { - var result = number + ' '; - switch (key) { - case 's': // a few seconds / in a few seconds / a few seconds ago - return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami'; - case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'sekundy' : 'sekúnd'); - } else { - return result + 'sekundami'; - } - break; - case 'm': // a minute / in a minute / a minute ago - return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou'); - case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'minúty' : 'minút'); - } else { - return result + 'minútami'; - } - break; - case 'h': // an hour / in an hour / an hour ago - return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); - case 'hh': // 9 hours / in 9 hours / 9 hours ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'hodiny' : 'hodín'); - } else { - return result + 'hodinami'; - } - break; - case 'd': // a day / in a day / a day ago - return (withoutSuffix || isFuture) ? 'deň' : 'dňom'; - case 'dd': // 9 days / in 9 days / 9 days ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'dni' : 'dní'); - } else { - return result + 'dňami'; - } - break; - case 'M': // a month / in a month / a month ago - return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom'; - case 'MM': // 9 months / in 9 months / 9 months ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'mesiace' : 'mesiacov'); - } else { - return result + 'mesiacmi'; - } - break; - case 'y': // a year / in a year / a year ago - return (withoutSuffix || isFuture) ? 'rok' : 'rokom'; - case 'yy': // 9 years / in 9 years / 9 years ago - if (withoutSuffix || isFuture) { - return result + (plural(number) ? 'roky' : 'rokov'); - } else { - return result + 'rokmi'; - } - break; + SubjectSubscription.prototype.unsubscribe = function () { + if (this.closed) { + return; } - } - - var sk = moment.defineLocale('sk', { - months : months, - monthsShort : monthsShort, - weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'), - weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'), - weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'), - longDateFormat : { - LT: 'H:mm', - LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY H:mm', - LLLL : 'dddd D. MMMM YYYY H:mm' - }, - calendar : { - sameDay: '[dnes o] LT', - nextDay: '[zajtra o] LT', - nextWeek: function () { - switch (this.day()) { - case 0: - return '[v nedeľu o] LT'; - case 1: - case 2: - return '[v] dddd [o] LT'; - case 3: - return '[v stredu o] LT'; - case 4: - return '[vo štvrtok o] LT'; - case 5: - return '[v piatok o] LT'; - case 6: - return '[v sobotu o] LT'; - } - }, - lastDay: '[včera o] LT', - lastWeek: function () { - switch (this.day()) { - case 0: - return '[minulú nedeľu o] LT'; - case 1: - case 2: - return '[minulý] dddd [o] LT'; - case 3: - return '[minulú stredu o] LT'; - case 4: - case 5: - return '[minulý] dddd [o] LT'; - case 6: - return '[minulú sobotu o] LT'; - } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'za %s', - past : 'pred %s', - s : translate, - ss : translate, - m : translate, - mm : translate, - h : translate, - hh : translate, - d : translate, - dd : translate, - M : translate, - MM : translate, - y : translate, - yy : translate - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + this.closed = true; + var subject = this.subject; + var observers = subject.observers; + this.subject = null; + if (!observers || observers.length === 0 || subject.isStopped || subject.closed) { + return; } - }); - - return sk; + var subscriberIndex = observers.indexOf(this.subscriber); + if (subscriberIndex !== -1) { + observers.splice(subscriberIndex, 1); + } + }; + return SubjectSubscription; +}(_Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"])); -}))); +//# sourceMappingURL=SubjectSubscription.js.map /***/ }), -/* 140 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration +/* 161 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "refCount", function() { return refCount; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ - function processRelativeTime(number, withoutSuffix, key, isFuture) { - var result = number + ' '; - switch (key) { - case 's': - return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami'; - case 'ss': - if (number === 1) { - result += withoutSuffix ? 'sekundo' : 'sekundi'; - } else if (number === 2) { - result += withoutSuffix || isFuture ? 'sekundi' : 'sekundah'; - } else if (number < 5) { - result += withoutSuffix || isFuture ? 'sekunde' : 'sekundah'; - } else { - result += 'sekund'; - } - return result; - case 'm': - return withoutSuffix ? 'ena minuta' : 'eno minuto'; - case 'mm': - if (number === 1) { - result += withoutSuffix ? 'minuta' : 'minuto'; - } else if (number === 2) { - result += withoutSuffix || isFuture ? 'minuti' : 'minutama'; - } else if (number < 5) { - result += withoutSuffix || isFuture ? 'minute' : 'minutami'; - } else { - result += withoutSuffix || isFuture ? 'minut' : 'minutami'; - } - return result; - case 'h': - return withoutSuffix ? 'ena ura' : 'eno uro'; - case 'hh': - if (number === 1) { - result += withoutSuffix ? 'ura' : 'uro'; - } else if (number === 2) { - result += withoutSuffix || isFuture ? 'uri' : 'urama'; - } else if (number < 5) { - result += withoutSuffix || isFuture ? 'ure' : 'urami'; - } else { - result += withoutSuffix || isFuture ? 'ur' : 'urami'; - } - return result; - case 'd': - return withoutSuffix || isFuture ? 'en dan' : 'enim dnem'; - case 'dd': - if (number === 1) { - result += withoutSuffix || isFuture ? 'dan' : 'dnem'; - } else if (number === 2) { - result += withoutSuffix || isFuture ? 'dni' : 'dnevoma'; - } else { - result += withoutSuffix || isFuture ? 'dni' : 'dnevi'; - } - return result; - case 'M': - return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem'; - case 'MM': - if (number === 1) { - result += withoutSuffix || isFuture ? 'mesec' : 'mesecem'; - } else if (number === 2) { - result += withoutSuffix || isFuture ? 'meseca' : 'mesecema'; - } else if (number < 5) { - result += withoutSuffix || isFuture ? 'mesece' : 'meseci'; - } else { - result += withoutSuffix || isFuture ? 'mesecev' : 'meseci'; - } - return result; - case 'y': - return withoutSuffix || isFuture ? 'eno leto' : 'enim letom'; - case 'yy': - if (number === 1) { - result += withoutSuffix || isFuture ? 'leto' : 'letom'; - } else if (number === 2) { - result += withoutSuffix || isFuture ? 'leti' : 'letoma'; - } else if (number < 5) { - result += withoutSuffix || isFuture ? 'leta' : 'leti'; - } else { - result += withoutSuffix || isFuture ? 'let' : 'leti'; - } - return result; +function refCount() { + return function refCountOperatorFunction(source) { + return source.lift(new RefCountOperator(source)); + }; +} +var RefCountOperator = /*@__PURE__*/ (function () { + function RefCountOperator(connectable) { + this.connectable = connectable; + } + RefCountOperator.prototype.call = function (subscriber, source) { + var connectable = this.connectable; + connectable._refCount++; + var refCounter = new RefCountSubscriber(subscriber, connectable); + var subscription = source.subscribe(refCounter); + if (!refCounter.closed) { + refCounter.connection = connectable.connect(); } + return subscription; + }; + return RefCountOperator; +}()); +var RefCountSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RefCountSubscriber, _super); + function RefCountSubscriber(destination, connectable) { + var _this = _super.call(this, destination) || this; + _this.connectable = connectable; + return _this; } + RefCountSubscriber.prototype._unsubscribe = function () { + var connectable = this.connectable; + if (!connectable) { + this.connection = null; + return; + } + this.connectable = null; + var refCount = connectable._refCount; + if (refCount <= 0) { + this.connection = null; + return; + } + connectable._refCount = refCount - 1; + if (refCount > 1) { + this.connection = null; + return; + } + var connection = this.connection; + var sharedConnection = connectable._connection; + this.connection = null; + if (sharedConnection && (!connection || sharedConnection === connection)) { + sharedConnection.unsubscribe(); + } + }; + return RefCountSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=refCount.js.map - var sl = moment.defineLocale('sl', { - months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'), - monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'), - monthsParseExact: true, - weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'), - weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'), - weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY H:mm', - LLLL : 'dddd, D. MMMM YYYY H:mm' - }, - calendar : { - sameDay : '[danes ob] LT', - nextDay : '[jutri ob] LT', - nextWeek : function () { - switch (this.day()) { - case 0: - return '[v] [nedeljo] [ob] LT'; - case 3: - return '[v] [sredo] [ob] LT'; - case 6: - return '[v] [soboto] [ob] LT'; - case 1: - case 2: - case 4: - case 5: - return '[v] dddd [ob] LT'; - } - }, - lastDay : '[včeraj ob] LT', - lastWeek : function () { - switch (this.day()) { - case 0: - return '[prejšnjo] [nedeljo] [ob] LT'; - case 3: - return '[prejšnjo] [sredo] [ob] LT'; - case 6: - return '[prejšnjo] [soboto] [ob] LT'; - case 1: - case 2: - case 4: - case 5: - return '[prejšnji] dddd [ob] LT'; - } - }, - sameElse : 'L' - }, - relativeTime : { - future : 'čez %s', - past : 'pred %s', - s : processRelativeTime, - ss : processRelativeTime, - m : processRelativeTime, - mm : processRelativeTime, - h : processRelativeTime, - hh : processRelativeTime, - d : processRelativeTime, - dd : processRelativeTime, - M : processRelativeTime, - MM : processRelativeTime, - y : processRelativeTime, - yy : processRelativeTime - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - return sl; - -}))); +/***/ }), +/* 162 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "groupBy", function() { return groupBy; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GroupedObservable", function() { return GroupedObservable; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(148); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(141); +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(158); +/** PURE_IMPORTS_START tslib,_Subscriber,_Subscription,_Observable,_Subject PURE_IMPORTS_END */ -/***/ }), -/* 141 */ -/***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var sq = moment.defineLocale('sq', { - months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'), - monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'), - weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'), - weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'), - weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'), - weekdaysParseExact : true, - meridiemParse: /PD|MD/, - isPM: function (input) { - return input.charAt(0) === 'M'; - }, - meridiem : function (hours, minutes, isLower) { - return hours < 12 ? 'PD' : 'MD'; - }, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Sot në] LT', - nextDay : '[Nesër në] LT', - nextWeek : 'dddd [në] LT', - lastDay : '[Dje në] LT', - lastWeek : 'dddd [e kaluar në] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'në %s', - past : '%s më parë', - s : 'disa sekonda', - ss : '%d sekonda', - m : 'një minutë', - mm : '%d minuta', - h : 'një orë', - hh : '%d orë', - d : 'një ditë', - dd : '%d ditë', - M : 'një muaj', - MM : '%d muaj', - y : 'një vit', - yy : '%d vite' - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. +function groupBy(keySelector, elementSelector, durationSelector, subjectSelector) { + return function (source) { + return source.lift(new GroupByOperator(keySelector, elementSelector, durationSelector, subjectSelector)); + }; +} +var GroupByOperator = /*@__PURE__*/ (function () { + function GroupByOperator(keySelector, elementSelector, durationSelector, subjectSelector) { + this.keySelector = keySelector; + this.elementSelector = elementSelector; + this.durationSelector = durationSelector; + this.subjectSelector = subjectSelector; + } + GroupByOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new GroupBySubscriber(subscriber, this.keySelector, this.elementSelector, this.durationSelector, this.subjectSelector)); + }; + return GroupByOperator; +}()); +var GroupBySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](GroupBySubscriber, _super); + function GroupBySubscriber(destination, keySelector, elementSelector, durationSelector, subjectSelector) { + var _this = _super.call(this, destination) || this; + _this.keySelector = keySelector; + _this.elementSelector = elementSelector; + _this.durationSelector = durationSelector; + _this.subjectSelector = subjectSelector; + _this.groups = null; + _this.attemptedToUnsubscribe = false; + _this.count = 0; + return _this; + } + GroupBySubscriber.prototype._next = function (value) { + var key; + try { + key = this.keySelector(value); } - }); - - return sq; + catch (err) { + this.error(err); + return; + } + this._group(value, key); + }; + GroupBySubscriber.prototype._group = function (value, key) { + var groups = this.groups; + if (!groups) { + groups = this.groups = new Map(); + } + var group = groups.get(key); + var element; + if (this.elementSelector) { + try { + element = this.elementSelector(value); + } + catch (err) { + this.error(err); + } + } + else { + element = value; + } + if (!group) { + group = (this.subjectSelector ? this.subjectSelector() : new _Subject__WEBPACK_IMPORTED_MODULE_4__["Subject"]()); + groups.set(key, group); + var groupedObservable = new GroupedObservable(key, group, this); + this.destination.next(groupedObservable); + if (this.durationSelector) { + var duration = void 0; + try { + duration = this.durationSelector(new GroupedObservable(key, group)); + } + catch (err) { + this.error(err); + return; + } + this.add(duration.subscribe(new GroupDurationSubscriber(key, group, this))); + } + } + if (!group.closed) { + group.next(element); + } + }; + GroupBySubscriber.prototype._error = function (err) { + var groups = this.groups; + if (groups) { + groups.forEach(function (group, key) { + group.error(err); + }); + groups.clear(); + } + this.destination.error(err); + }; + GroupBySubscriber.prototype._complete = function () { + var groups = this.groups; + if (groups) { + groups.forEach(function (group, key) { + group.complete(); + }); + groups.clear(); + } + this.destination.complete(); + }; + GroupBySubscriber.prototype.removeGroup = function (key) { + this.groups.delete(key); + }; + GroupBySubscriber.prototype.unsubscribe = function () { + if (!this.closed) { + this.attemptedToUnsubscribe = true; + if (this.count === 0) { + _super.prototype.unsubscribe.call(this); + } + } + }; + return GroupBySubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +var GroupDurationSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](GroupDurationSubscriber, _super); + function GroupDurationSubscriber(key, group, parent) { + var _this = _super.call(this, group) || this; + _this.key = key; + _this.group = group; + _this.parent = parent; + return _this; + } + GroupDurationSubscriber.prototype._next = function (value) { + this.complete(); + }; + GroupDurationSubscriber.prototype._unsubscribe = function () { + var _a = this, parent = _a.parent, key = _a.key; + this.key = this.parent = null; + if (parent) { + parent.removeGroup(key); + } + }; + return GroupDurationSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +var GroupedObservable = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](GroupedObservable, _super); + function GroupedObservable(key, groupSubject, refCountSubscription) { + var _this = _super.call(this) || this; + _this.key = key; + _this.groupSubject = groupSubject; + _this.refCountSubscription = refCountSubscription; + return _this; + } + GroupedObservable.prototype._subscribe = function (subscriber) { + var subscription = new _Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"](); + var _a = this, refCountSubscription = _a.refCountSubscription, groupSubject = _a.groupSubject; + if (refCountSubscription && !refCountSubscription.closed) { + subscription.add(new InnerRefCountSubscription(refCountSubscription)); + } + subscription.add(groupSubject.subscribe(subscriber)); + return subscription; + }; + return GroupedObservable; +}(_Observable__WEBPACK_IMPORTED_MODULE_3__["Observable"])); -}))); +var InnerRefCountSubscription = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](InnerRefCountSubscription, _super); + function InnerRefCountSubscription(parent) { + var _this = _super.call(this) || this; + _this.parent = parent; + parent.count++; + return _this; + } + InnerRefCountSubscription.prototype.unsubscribe = function () { + var parent = this.parent; + if (!parent.closed && !this.closed) { + _super.prototype.unsubscribe.call(this); + parent.count -= 1; + if (parent.count === 0 && parent.attemptedToUnsubscribe) { + parent.unsubscribe(); + } + } + }; + return InnerRefCountSubscription; +}(_Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"])); +//# sourceMappingURL=groupBy.js.map /***/ }), -/* 142 */ -/***/ (function(module, exports, __webpack_require__) { +/* 163 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BehaviorSubject", function() { return BehaviorSubject; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(158); +/* harmony import */ var _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(159); +/** PURE_IMPORTS_START tslib,_Subject,_util_ObjectUnsubscribedError PURE_IMPORTS_END */ -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var translator = { - words: { //Different grammatical cases - ss: ['sekunda', 'sekunde', 'sekundi'], - m: ['jedan minut', 'jedne minute'], - mm: ['minut', 'minute', 'minuta'], - h: ['jedan sat', 'jednog sata'], - hh: ['sat', 'sata', 'sati'], - dd: ['dan', 'dana', 'dana'], - MM: ['mesec', 'meseca', 'meseci'], - yy: ['godina', 'godine', 'godina'] - }, - correctGrammaticalCase: function (number, wordKey) { - return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); +var BehaviorSubject = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BehaviorSubject, _super); + function BehaviorSubject(_value) { + var _this = _super.call(this) || this; + _this._value = _value; + return _this; + } + Object.defineProperty(BehaviorSubject.prototype, "value", { + get: function () { + return this.getValue(); }, - translate: function (number, withoutSuffix, key) { - var wordKey = translator.words[key]; - if (key.length === 1) { - return withoutSuffix ? wordKey[0] : wordKey[1]; - } else { - return number + ' ' + translator.correctGrammaticalCase(number, wordKey); - } + enumerable: true, + configurable: true + }); + BehaviorSubject.prototype._subscribe = function (subscriber) { + var subscription = _super.prototype._subscribe.call(this, subscriber); + if (subscription && !subscription.closed) { + subscriber.next(this._value); } + return subscription; }; - - var sr = moment.defineLocale('sr', { - months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'), - monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'), - monthsParseExact: true, - weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'), - weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'), - weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'), - weekdaysParseExact : true, - longDateFormat: { - LT: 'H:mm', - LTS : 'H:mm:ss', - L: 'DD.MM.YYYY', - LL: 'D. MMMM YYYY', - LLL: 'D. MMMM YYYY H:mm', - LLLL: 'dddd, D. MMMM YYYY H:mm' - }, - calendar: { - sameDay: '[danas u] LT', - nextDay: '[sutra u] LT', - nextWeek: function () { - switch (this.day()) { - case 0: - return '[u] [nedelju] [u] LT'; - case 3: - return '[u] [sredu] [u] LT'; - case 6: - return '[u] [subotu] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[u] dddd [u] LT'; - } - }, - lastDay : '[juče u] LT', - lastWeek : function () { - var lastWeekDays = [ - '[prošle] [nedelje] [u] LT', - '[prošlog] [ponedeljka] [u] LT', - '[prošlog] [utorka] [u] LT', - '[prošle] [srede] [u] LT', - '[prošlog] [četvrtka] [u] LT', - '[prošlog] [petka] [u] LT', - '[prošle] [subote] [u] LT' - ]; - return lastWeekDays[this.day()]; - }, - sameElse : 'L' - }, - relativeTime : { - future : 'za %s', - past : 'pre %s', - s : 'nekoliko sekundi', - ss : translator.translate, - m : translator.translate, - mm : translator.translate, - h : translator.translate, - hh : translator.translate, - d : 'dan', - dd : translator.translate, - M : 'mesec', - MM : translator.translate, - y : 'godinu', - yy : translator.translate - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. + BehaviorSubject.prototype.getValue = function () { + if (this.hasError) { + throw this.thrownError; } - }); - - return sr; + else if (this.closed) { + throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_2__["ObjectUnsubscribedError"](); + } + else { + return this._value; + } + }; + BehaviorSubject.prototype.next = function (value) { + _super.prototype.next.call(this, this._value = value); + }; + return BehaviorSubject; +}(_Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"])); -}))); +//# sourceMappingURL=BehaviorSubject.js.map /***/ }), -/* 143 */ -/***/ (function(module, exports, __webpack_require__) { +/* 164 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ReplaySubject", function() { return ReplaySubject; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(158); +/* harmony import */ var _scheduler_queue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(165); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(148); +/* harmony import */ var _operators_observeOn__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(172); +/* harmony import */ var _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(159); +/* harmony import */ var _SubjectSubscription__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(160); +/** PURE_IMPORTS_START tslib,_Subject,_scheduler_queue,_Subscription,_operators_observeOn,_util_ObjectUnsubscribedError,_SubjectSubscription PURE_IMPORTS_END */ -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var translator = { - words: { //Different grammatical cases - ss: ['секунда', 'секунде', 'секунди'], - m: ['један минут', 'једне минуте'], - mm: ['минут', 'минуте', 'минута'], - h: ['један сат', 'једног сата'], - hh: ['сат', 'сата', 'сати'], - dd: ['дан', 'дана', 'дана'], - MM: ['месец', 'месеца', 'месеци'], - yy: ['година', 'године', 'година'] - }, - correctGrammaticalCase: function (number, wordKey) { - return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); - }, - translate: function (number, withoutSuffix, key) { - var wordKey = translator.words[key]; - if (key.length === 1) { - return withoutSuffix ? wordKey[0] : wordKey[1]; - } else { - return number + ' ' + translator.correctGrammaticalCase(number, wordKey); - } + + + + +var ReplaySubject = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ReplaySubject, _super); + function ReplaySubject(bufferSize, windowTime, scheduler) { + if (bufferSize === void 0) { + bufferSize = Number.POSITIVE_INFINITY; + } + if (windowTime === void 0) { + windowTime = Number.POSITIVE_INFINITY; + } + var _this = _super.call(this) || this; + _this.scheduler = scheduler; + _this._events = []; + _this._infiniteTimeWindow = false; + _this._bufferSize = bufferSize < 1 ? 1 : bufferSize; + _this._windowTime = windowTime < 1 ? 1 : windowTime; + if (windowTime === Number.POSITIVE_INFINITY) { + _this._infiniteTimeWindow = true; + _this.next = _this.nextInfiniteTimeWindow; + } + else { + _this.next = _this.nextTimeWindow; + } + return _this; + } + ReplaySubject.prototype.nextInfiniteTimeWindow = function (value) { + var _events = this._events; + _events.push(value); + if (_events.length > this._bufferSize) { + _events.shift(); } + _super.prototype.next.call(this, value); }; - - var srCyrl = moment.defineLocale('sr-cyrl', { - months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'), - monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'), - monthsParseExact: true, - weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'), - weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'), - weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'), - weekdaysParseExact : true, - longDateFormat: { - LT: 'H:mm', - LTS : 'H:mm:ss', - L: 'DD.MM.YYYY', - LL: 'D. MMMM YYYY', - LLL: 'D. MMMM YYYY H:mm', - LLLL: 'dddd, D. MMMM YYYY H:mm' - }, - calendar: { - sameDay: '[данас у] LT', - nextDay: '[сутра у] LT', - nextWeek: function () { - switch (this.day()) { - case 0: - return '[у] [недељу] [у] LT'; - case 3: - return '[у] [среду] [у] LT'; - case 6: - return '[у] [суботу] [у] LT'; - case 1: - case 2: - case 4: - case 5: - return '[у] dddd [у] LT'; - } - }, - lastDay : '[јуче у] LT', - lastWeek : function () { - var lastWeekDays = [ - '[прошле] [недеље] [у] LT', - '[прошлог] [понедељка] [у] LT', - '[прошлог] [уторка] [у] LT', - '[прошле] [среде] [у] LT', - '[прошлог] [четвртка] [у] LT', - '[прошлог] [петка] [у] LT', - '[прошле] [суботе] [у] LT' - ]; - return lastWeekDays[this.day()]; - }, - sameElse : 'L' - }, - relativeTime : { - future : 'за %s', - past : 'пре %s', - s : 'неколико секунди', - ss : translator.translate, - m : translator.translate, - mm : translator.translate, - h : translator.translate, - hh : translator.translate, - d : 'дан', - dd : translator.translate, - M : 'месец', - MM : translator.translate, - y : 'годину', - yy : translator.translate - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. + ReplaySubject.prototype.nextTimeWindow = function (value) { + this._events.push(new ReplayEvent(this._getNow(), value)); + this._trimBufferThenGetEvents(); + _super.prototype.next.call(this, value); + }; + ReplaySubject.prototype._subscribe = function (subscriber) { + var _infiniteTimeWindow = this._infiniteTimeWindow; + var _events = _infiniteTimeWindow ? this._events : this._trimBufferThenGetEvents(); + var scheduler = this.scheduler; + var len = _events.length; + var subscription; + if (this.closed) { + throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_5__["ObjectUnsubscribedError"](); } - }); - - return srCyrl; + else if (this.isStopped || this.hasError) { + subscription = _Subscription__WEBPACK_IMPORTED_MODULE_3__["Subscription"].EMPTY; + } + else { + this.observers.push(subscriber); + subscription = new _SubjectSubscription__WEBPACK_IMPORTED_MODULE_6__["SubjectSubscription"](this, subscriber); + } + if (scheduler) { + subscriber.add(subscriber = new _operators_observeOn__WEBPACK_IMPORTED_MODULE_4__["ObserveOnSubscriber"](subscriber, scheduler)); + } + if (_infiniteTimeWindow) { + for (var i = 0; i < len && !subscriber.closed; i++) { + subscriber.next(_events[i]); + } + } + else { + for (var i = 0; i < len && !subscriber.closed; i++) { + subscriber.next(_events[i].value); + } + } + if (this.hasError) { + subscriber.error(this.thrownError); + } + else if (this.isStopped) { + subscriber.complete(); + } + return subscription; + }; + ReplaySubject.prototype._getNow = function () { + return (this.scheduler || _scheduler_queue__WEBPACK_IMPORTED_MODULE_2__["queue"]).now(); + }; + ReplaySubject.prototype._trimBufferThenGetEvents = function () { + var now = this._getNow(); + var _bufferSize = this._bufferSize; + var _windowTime = this._windowTime; + var _events = this._events; + var eventsCount = _events.length; + var spliceCount = 0; + while (spliceCount < eventsCount) { + if ((now - _events[spliceCount].time) < _windowTime) { + break; + } + spliceCount++; + } + if (eventsCount > _bufferSize) { + spliceCount = Math.max(spliceCount, eventsCount - _bufferSize); + } + if (spliceCount > 0) { + _events.splice(0, spliceCount); + } + return _events; + }; + return ReplaySubject; +}(_Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"])); -}))); +var ReplayEvent = /*@__PURE__*/ (function () { + function ReplayEvent(time, value) { + this.time = time; + this.value = value; + } + return ReplayEvent; +}()); +//# sourceMappingURL=ReplaySubject.js.map /***/ }), -/* 144 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration - -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - +/* 165 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - var ss = moment.defineLocale('ss', { - months : "Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split('_'), - monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'), - weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'), - weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'), - weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY h:mm A', - LLLL : 'dddd, D MMMM YYYY h:mm A' - }, - calendar : { - sameDay : '[Namuhla nga] LT', - nextDay : '[Kusasa nga] LT', - nextWeek : 'dddd [nga] LT', - lastDay : '[Itolo nga] LT', - lastWeek : 'dddd [leliphelile] [nga] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'nga %s', - past : 'wenteka nga %s', - s : 'emizuzwana lomcane', - ss : '%d mzuzwana', - m : 'umzuzu', - mm : '%d emizuzu', - h : 'lihora', - hh : '%d emahora', - d : 'lilanga', - dd : '%d emalanga', - M : 'inyanga', - MM : '%d tinyanga', - y : 'umnyaka', - yy : '%d iminyaka' - }, - meridiemParse: /ekuseni|emini|entsambama|ebusuku/, - meridiem : function (hours, minutes, isLower) { - if (hours < 11) { - return 'ekuseni'; - } else if (hours < 15) { - return 'emini'; - } else if (hours < 19) { - return 'entsambama'; - } else { - return 'ebusuku'; - } - }, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'ekuseni') { - return hour; - } else if (meridiem === 'emini') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') { - if (hour === 0) { - return 0; - } - return hour + 12; - } - }, - dayOfMonthOrdinalParse: /\d{1,2}/, - ordinal : '%d', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "queue", function() { return queue; }); +/* harmony import */ var _QueueAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(166); +/* harmony import */ var _QueueScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(169); +/** PURE_IMPORTS_START _QueueAction,_QueueScheduler PURE_IMPORTS_END */ - return ss; -}))); +var queue = /*@__PURE__*/ new _QueueScheduler__WEBPACK_IMPORTED_MODULE_1__["QueueScheduler"](_QueueAction__WEBPACK_IMPORTED_MODULE_0__["QueueAction"]); +//# sourceMappingURL=queue.js.map /***/ }), -/* 145 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration +/* 166 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "QueueAction", function() { return QueueAction; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(167); +/** PURE_IMPORTS_START tslib,_AsyncAction PURE_IMPORTS_END */ - var sv = moment.defineLocale('sv', { - months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'), - monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), - weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'), - weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'), - weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY-MM-DD', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY [kl.] HH:mm', - LLLL : 'dddd D MMMM YYYY [kl.] HH:mm', - lll : 'D MMM YYYY HH:mm', - llll : 'ddd D MMM YYYY HH:mm' - }, - calendar : { - sameDay: '[Idag] LT', - nextDay: '[Imorgon] LT', - lastDay: '[Igår] LT', - nextWeek: '[På] dddd LT', - lastWeek: '[I] dddd[s] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'om %s', - past : 'för %s sedan', - s : 'några sekunder', - ss : '%d sekunder', - m : 'en minut', - mm : '%d minuter', - h : 'en timme', - hh : '%d timmar', - d : 'en dag', - dd : '%d dagar', - M : 'en månad', - MM : '%d månader', - y : 'ett år', - yy : '%d år' - }, - dayOfMonthOrdinalParse: /\d{1,2}(e|a)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'e' : - (b === 1) ? 'a' : - (b === 2) ? 'a' : - (b === 3) ? 'e' : 'e'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. +var QueueAction = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](QueueAction, _super); + function QueueAction(scheduler, work) { + var _this = _super.call(this, scheduler, work) || this; + _this.scheduler = scheduler; + _this.work = work; + return _this; + } + QueueAction.prototype.schedule = function (state, delay) { + if (delay === void 0) { + delay = 0; } - }); - - return sv; + if (delay > 0) { + return _super.prototype.schedule.call(this, state, delay); + } + this.delay = delay; + this.state = state; + this.scheduler.flush(this); + return this; + }; + QueueAction.prototype.execute = function (state, delay) { + return (delay > 0 || this.closed) ? + _super.prototype.execute.call(this, state, delay) : + this._execute(state, delay); + }; + QueueAction.prototype.requestAsyncId = function (scheduler, id, delay) { + if (delay === void 0) { + delay = 0; + } + if ((delay !== null && delay > 0) || (delay === null && this.delay > 0)) { + return _super.prototype.requestAsyncId.call(this, scheduler, id, delay); + } + return scheduler.flush(this); + }; + return QueueAction; +}(_AsyncAction__WEBPACK_IMPORTED_MODULE_1__["AsyncAction"])); -}))); +//# sourceMappingURL=QueueAction.js.map /***/ }), -/* 146 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration +/* 167 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AsyncAction", function() { return AsyncAction; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Action__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(168); +/** PURE_IMPORTS_START tslib,_Action PURE_IMPORTS_END */ - var sw = moment.defineLocale('sw', { - months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'), - monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'), - weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'), - weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'), - weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[leo saa] LT', - nextDay : '[kesho saa] LT', - nextWeek : '[wiki ijayo] dddd [saat] LT', - lastDay : '[jana] LT', - lastWeek : '[wiki iliyopita] dddd [saat] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s baadaye', - past : 'tokea %s', - s : 'hivi punde', - ss : 'sekunde %d', - m : 'dakika moja', - mm : 'dakika %d', - h : 'saa limoja', - hh : 'masaa %d', - d : 'siku moja', - dd : 'masiku %d', - M : 'mwezi mmoja', - MM : 'miezi %d', - y : 'mwaka mmoja', - yy : 'miaka %d' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. +var AsyncAction = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AsyncAction, _super); + function AsyncAction(scheduler, work) { + var _this = _super.call(this, scheduler, work) || this; + _this.scheduler = scheduler; + _this.work = work; + _this.pending = false; + return _this; + } + AsyncAction.prototype.schedule = function (state, delay) { + if (delay === void 0) { + delay = 0; } - }); - - return sw; + if (this.closed) { + return this; + } + this.state = state; + var id = this.id; + var scheduler = this.scheduler; + if (id != null) { + this.id = this.recycleAsyncId(scheduler, id, delay); + } + this.pending = true; + this.delay = delay; + this.id = this.id || this.requestAsyncId(scheduler, this.id, delay); + return this; + }; + AsyncAction.prototype.requestAsyncId = function (scheduler, id, delay) { + if (delay === void 0) { + delay = 0; + } + return setInterval(scheduler.flush.bind(scheduler, this), delay); + }; + AsyncAction.prototype.recycleAsyncId = function (scheduler, id, delay) { + if (delay === void 0) { + delay = 0; + } + if (delay !== null && this.delay === delay && this.pending === false) { + return id; + } + clearInterval(id); + return undefined; + }; + AsyncAction.prototype.execute = function (state, delay) { + if (this.closed) { + return new Error('executing a cancelled action'); + } + this.pending = false; + var error = this._execute(state, delay); + if (error) { + return error; + } + else if (this.pending === false && this.id != null) { + this.id = this.recycleAsyncId(this.scheduler, this.id, null); + } + }; + AsyncAction.prototype._execute = function (state, delay) { + var errored = false; + var errorValue = undefined; + try { + this.work(state); + } + catch (e) { + errored = true; + errorValue = !!e && e || new Error(e); + } + if (errored) { + this.unsubscribe(); + return errorValue; + } + }; + AsyncAction.prototype._unsubscribe = function () { + var id = this.id; + var scheduler = this.scheduler; + var actions = scheduler.actions; + var index = actions.indexOf(this); + this.work = null; + this.state = null; + this.pending = false; + this.scheduler = null; + if (index !== -1) { + actions.splice(index, 1); + } + if (id != null) { + this.id = this.recycleAsyncId(scheduler, id, null); + } + this.delay = null; + }; + return AsyncAction; +}(_Action__WEBPACK_IMPORTED_MODULE_1__["Action"])); -}))); +//# sourceMappingURL=AsyncAction.js.map /***/ }), -/* 147 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration +/* 168 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Action", function() { return Action; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(148); +/** PURE_IMPORTS_START tslib,_Subscription PURE_IMPORTS_END */ - var symbolMap = { - '1': '௧', - '2': '௨', - '3': '௩', - '4': '௪', - '5': '௫', - '6': '௬', - '7': '௭', - '8': '௮', - '9': '௯', - '0': '௦' - }, numberMap = { - '௧': '1', - '௨': '2', - '௩': '3', - '௪': '4', - '௫': '5', - '௬': '6', - '௭': '7', - '௮': '8', - '௯': '9', - '௦': '0' +var Action = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](Action, _super); + function Action(scheduler, work) { + return _super.call(this) || this; + } + Action.prototype.schedule = function (state, delay) { + if (delay === void 0) { + delay = 0; + } + return this; }; + return Action; +}(_Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"])); - var ta = moment.defineLocale('ta', { - months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), - monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), - weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'), - weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'), - weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, HH:mm', - LLLL : 'dddd, D MMMM YYYY, HH:mm' - }, - calendar : { - sameDay : '[இன்று] LT', - nextDay : '[நாளை] LT', - nextWeek : 'dddd, LT', - lastDay : '[நேற்று] LT', - lastWeek : '[கடந்த வாரம்] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s இல்', - past : '%s முன்', - s : 'ஒரு சில விநாடிகள்', - ss : '%d விநாடிகள்', - m : 'ஒரு நிமிடம்', - mm : '%d நிமிடங்கள்', - h : 'ஒரு மணி நேரம்', - hh : '%d மணி நேரம்', - d : 'ஒரு நாள்', - dd : '%d நாட்கள்', - M : 'ஒரு மாதம்', - MM : '%d மாதங்கள்', - y : 'ஒரு வருடம்', - yy : '%d ஆண்டுகள்' - }, - dayOfMonthOrdinalParse: /\d{1,2}வது/, - ordinal : function (number) { - return number + 'வது'; - }, - preparse: function (string) { - return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) { - return numberMap[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }); - }, - // refer http://ta.wikipedia.org/s/1er1 - meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/, - meridiem : function (hour, minute, isLower) { - if (hour < 2) { - return ' யாமம்'; - } else if (hour < 6) { - return ' வைகறை'; // வைகறை - } else if (hour < 10) { - return ' காலை'; // காலை - } else if (hour < 14) { - return ' நண்பகல்'; // நண்பகல் - } else if (hour < 18) { - return ' எற்பாடு'; // எற்பாடு - } else if (hour < 22) { - return ' மாலை'; // மாலை - } else { - return ' யாமம்'; - } - }, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'யாமம்') { - return hour < 2 ? hour : hour + 12; - } else if (meridiem === 'வைகறை' || meridiem === 'காலை') { - return hour; - } else if (meridiem === 'நண்பகல்') { - return hour >= 10 ? hour : hour + 12; - } else { - return hour + 12; - } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - } - }); +//# sourceMappingURL=Action.js.map - return ta; -}))); +/***/ }), +/* 169 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "QueueScheduler", function() { return QueueScheduler; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(170); +/** PURE_IMPORTS_START tslib,_AsyncScheduler PURE_IMPORTS_END */ -/***/ }), -/* 148 */ -/***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration +var QueueScheduler = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](QueueScheduler, _super); + function QueueScheduler() { + return _super !== null && _super.apply(this, arguments) || this; + } + return QueueScheduler; +}(_AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__["AsyncScheduler"])); -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +//# sourceMappingURL=QueueScheduler.js.map - var te = moment.defineLocale('te', { - months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జులై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'), - monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జులై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'), - monthsParseExact : true, - weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'), - weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'), - weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'), - longDateFormat : { - LT : 'A h:mm', - LTS : 'A h:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm', - LLLL : 'dddd, D MMMM YYYY, A h:mm' - }, - calendar : { - sameDay : '[నేడు] LT', - nextDay : '[రేపు] LT', - nextWeek : 'dddd, LT', - lastDay : '[నిన్న] LT', - lastWeek : '[గత] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s లో', - past : '%s క్రితం', - s : 'కొన్ని క్షణాలు', - ss : '%d సెకన్లు', - m : 'ఒక నిమిషం', - mm : '%d నిమిషాలు', - h : 'ఒక గంట', - hh : '%d గంటలు', - d : 'ఒక రోజు', - dd : '%d రోజులు', - M : 'ఒక నెల', - MM : '%d నెలలు', - y : 'ఒక సంవత్సరం', - yy : '%d సంవత్సరాలు' - }, - dayOfMonthOrdinalParse : /\d{1,2}వ/, - ordinal : '%dవ', - meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; +/***/ }), +/* 170 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AsyncScheduler", function() { return AsyncScheduler; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Scheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(171); +/** PURE_IMPORTS_START tslib,_Scheduler PURE_IMPORTS_END */ + + +var AsyncScheduler = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AsyncScheduler, _super); + function AsyncScheduler(SchedulerAction, now) { + if (now === void 0) { + now = _Scheduler__WEBPACK_IMPORTED_MODULE_1__["Scheduler"].now; + } + var _this = _super.call(this, SchedulerAction, function () { + if (AsyncScheduler.delegate && AsyncScheduler.delegate !== _this) { + return AsyncScheduler.delegate.now(); } - if (meridiem === 'రాత్రి') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'ఉదయం') { - return hour; - } else if (meridiem === 'మధ్యాహ్నం') { - return hour >= 10 ? hour : hour + 12; - } else if (meridiem === 'సాయంత్రం') { - return hour + 12; + else { + return now(); } - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'రాత్రి'; - } else if (hour < 10) { - return 'ఉదయం'; - } else if (hour < 17) { - return 'మధ్యాహ్నం'; - } else if (hour < 20) { - return 'సాయంత్రం'; - } else { - return 'రాత్రి'; + }) || this; + _this.actions = []; + _this.active = false; + _this.scheduled = undefined; + return _this; + } + AsyncScheduler.prototype.schedule = function (work, delay, state) { + if (delay === void 0) { + delay = 0; + } + if (AsyncScheduler.delegate && AsyncScheduler.delegate !== this) { + return AsyncScheduler.delegate.schedule(work, delay, state); + } + else { + return _super.prototype.schedule.call(this, work, delay, state); + } + }; + AsyncScheduler.prototype.flush = function (action) { + var actions = this.actions; + if (this.active) { + actions.push(action); + return; + } + var error; + this.active = true; + do { + if (error = action.execute(action.state, action.delay)) { + break; } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. + } while (action = actions.shift()); + this.active = false; + if (error) { + while (action = actions.shift()) { + action.unsubscribe(); + } + throw error; } - }); + }; + return AsyncScheduler; +}(_Scheduler__WEBPACK_IMPORTED_MODULE_1__["Scheduler"])); - return te; +//# sourceMappingURL=AsyncScheduler.js.map -}))); + +/***/ }), +/* 171 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Scheduler", function() { return Scheduler; }); +var Scheduler = /*@__PURE__*/ (function () { + function Scheduler(SchedulerAction, now) { + if (now === void 0) { + now = Scheduler.now; + } + this.SchedulerAction = SchedulerAction; + this.now = now; + } + Scheduler.prototype.schedule = function (work, delay, state) { + if (delay === void 0) { + delay = 0; + } + return new this.SchedulerAction(this, work).schedule(state, delay); + }; + Scheduler.now = function () { return Date.now(); }; + return Scheduler; +}()); + +//# sourceMappingURL=Scheduler.js.map /***/ }), -/* 149 */ -/***/ (function(module, exports, __webpack_require__) { +/* 172 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "observeOn", function() { return observeOn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ObserveOnOperator", function() { return ObserveOnOperator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ObserveOnSubscriber", function() { return ObserveOnSubscriber; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ObserveOnMessage", function() { return ObserveOnMessage; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _Notification__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(173); +/** PURE_IMPORTS_START tslib,_Subscriber,_Notification PURE_IMPORTS_END */ -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var tet = moment.defineLocale('tet', { - months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juñu_Jullu_Agustu_Setembru_Outubru_Novembru_Dezembru'.split('_'), - monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'), - weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sesta_Sabadu'.split('_'), - weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sest_Sab'.split('_'), - weekdaysMin : 'Do_Seg_Te_Ku_Ki_Ses_Sa'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[Ohin iha] LT', - nextDay: '[Aban iha] LT', - nextWeek: 'dddd [iha] LT', - lastDay: '[Horiseik iha] LT', - lastWeek: 'dddd [semana kotuk] [iha] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'iha %s', - past : '%s liuba', - s : 'minutu balun', - ss : 'minutu %d', - m : 'minutu ida', - mm : 'minutu %d', - h : 'oras ida', - hh : 'oras %d', - d : 'loron ida', - dd : 'loron %d', - M : 'fulan ida', - MM : 'fulan %d', - y : 'tinan ida', - yy : 'tinan %d' - }, - dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. +function observeOn(scheduler, delay) { + if (delay === void 0) { + delay = 0; + } + return function observeOnOperatorFunction(source) { + return source.lift(new ObserveOnOperator(scheduler, delay)); + }; +} +var ObserveOnOperator = /*@__PURE__*/ (function () { + function ObserveOnOperator(scheduler, delay) { + if (delay === void 0) { + delay = 0; } - }); + this.scheduler = scheduler; + this.delay = delay; + } + ObserveOnOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ObserveOnSubscriber(subscriber, this.scheduler, this.delay)); + }; + return ObserveOnOperator; +}()); - return tet; +var ObserveOnSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ObserveOnSubscriber, _super); + function ObserveOnSubscriber(destination, scheduler, delay) { + if (delay === void 0) { + delay = 0; + } + var _this = _super.call(this, destination) || this; + _this.scheduler = scheduler; + _this.delay = delay; + return _this; + } + ObserveOnSubscriber.dispatch = function (arg) { + var notification = arg.notification, destination = arg.destination; + notification.observe(destination); + this.unsubscribe(); + }; + ObserveOnSubscriber.prototype.scheduleMessage = function (notification) { + var destination = this.destination; + destination.add(this.scheduler.schedule(ObserveOnSubscriber.dispatch, this.delay, new ObserveOnMessage(notification, this.destination))); + }; + ObserveOnSubscriber.prototype._next = function (value) { + this.scheduleMessage(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createNext(value)); + }; + ObserveOnSubscriber.prototype._error = function (err) { + this.scheduleMessage(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createError(err)); + this.unsubscribe(); + }; + ObserveOnSubscriber.prototype._complete = function () { + this.scheduleMessage(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createComplete()); + this.unsubscribe(); + }; + return ObserveOnSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -}))); +var ObserveOnMessage = /*@__PURE__*/ (function () { + function ObserveOnMessage(notification, destination) { + this.notification = notification; + this.destination = destination; + } + return ObserveOnMessage; +}()); + +//# sourceMappingURL=observeOn.js.map /***/ }), -/* 150 */ -/***/ (function(module, exports, __webpack_require__) { +/* 173 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NotificationKind", function() { return NotificationKind; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Notification", function() { return Notification; }); +/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(174); +/* harmony import */ var _observable_of__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(175); +/* harmony import */ var _observable_throwError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(180); +/** PURE_IMPORTS_START _observable_empty,_observable_of,_observable_throwError PURE_IMPORTS_END */ -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var suffixes = { - 0: '-ум', - 1: '-ум', - 2: '-юм', - 3: '-юм', - 4: '-ум', - 5: '-ум', - 6: '-ум', - 7: '-ум', - 8: '-ум', - 9: '-ум', - 10: '-ум', - 12: '-ум', - 13: '-ум', - 20: '-ум', - 30: '-юм', - 40: '-ум', - 50: '-ум', - 60: '-ум', - 70: '-ум', - 80: '-ум', - 90: '-ум', - 100: '-ум' +var NotificationKind; +/*@__PURE__*/ (function (NotificationKind) { + NotificationKind["NEXT"] = "N"; + NotificationKind["ERROR"] = "E"; + NotificationKind["COMPLETE"] = "C"; +})(NotificationKind || (NotificationKind = {})); +var Notification = /*@__PURE__*/ (function () { + function Notification(kind, value, error) { + this.kind = kind; + this.value = value; + this.error = error; + this.hasValue = kind === 'N'; + } + Notification.prototype.observe = function (observer) { + switch (this.kind) { + case 'N': + return observer.next && observer.next(this.value); + case 'E': + return observer.error && observer.error(this.error); + case 'C': + return observer.complete && observer.complete(); + } }; - - var tg = moment.defineLocale('tg', { - months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'), - monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'), - weekdays : 'якшанбе_душанбе_сешанбе_чоршанбе_панҷшанбе_ҷумъа_шанбе'.split('_'), - weekdaysShort : 'яшб_дшб_сшб_чшб_пшб_ҷум_шнб'.split('_'), - weekdaysMin : 'яш_дш_сш_чш_пш_ҷм_шб'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Имрӯз соати] LT', - nextDay : '[Пагоҳ соати] LT', - lastDay : '[Дирӯз соати] LT', - nextWeek : 'dddd[и] [ҳафтаи оянда соати] LT', - lastWeek : 'dddd[и] [ҳафтаи гузашта соати] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'баъди %s', - past : '%s пеш', - s : 'якчанд сония', - m : 'як дақиқа', - mm : '%d дақиқа', - h : 'як соат', - hh : '%d соат', - d : 'як рӯз', - dd : '%d рӯз', - M : 'як моҳ', - MM : '%d моҳ', - y : 'як сол', - yy : '%d сол' - }, - meridiemParse: /шаб|субҳ|рӯз|бегоҳ/, - meridiemHour: function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'шаб') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'субҳ') { - return hour; - } else if (meridiem === 'рӯз') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === 'бегоҳ') { - return hour + 12; - } - }, - meridiem: function (hour, minute, isLower) { - if (hour < 4) { - return 'шаб'; - } else if (hour < 11) { - return 'субҳ'; - } else if (hour < 16) { - return 'рӯз'; - } else if (hour < 19) { - return 'бегоҳ'; - } else { - return 'шаб'; - } - }, - dayOfMonthOrdinalParse: /\d{1,2}-(ум|юм)/, - ordinal: function (number) { - var a = number % 10, - b = number >= 100 ? 100 : null; - return number + (suffixes[number] || suffixes[a] || suffixes[b]); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1th is the first week of the year. + Notification.prototype.do = function (next, error, complete) { + var kind = this.kind; + switch (kind) { + case 'N': + return next && next(this.value); + case 'E': + return error && error(this.error); + case 'C': + return complete && complete(); } - }); + }; + Notification.prototype.accept = function (nextOrObserver, error, complete) { + if (nextOrObserver && typeof nextOrObserver.next === 'function') { + return this.observe(nextOrObserver); + } + else { + return this.do(nextOrObserver, error, complete); + } + }; + Notification.prototype.toObservable = function () { + var kind = this.kind; + switch (kind) { + case 'N': + return Object(_observable_of__WEBPACK_IMPORTED_MODULE_1__["of"])(this.value); + case 'E': + return Object(_observable_throwError__WEBPACK_IMPORTED_MODULE_2__["throwError"])(this.error); + case 'C': + return Object(_observable_empty__WEBPACK_IMPORTED_MODULE_0__["empty"])(); + } + throw new Error('unexpected notification kind value'); + }; + Notification.createNext = function (value) { + if (typeof value !== 'undefined') { + return new Notification('N', value); + } + return Notification.undefinedValueNotification; + }; + Notification.createError = function (err) { + return new Notification('E', undefined, err); + }; + Notification.createComplete = function () { + return Notification.completeNotification; + }; + Notification.completeNotification = new Notification('C'); + Notification.undefinedValueNotification = new Notification('N', undefined); + return Notification; +}()); - return tg; +//# sourceMappingURL=Notification.js.map -}))); + +/***/ }), +/* 174 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EMPTY", function() { return EMPTY; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "empty", function() { return empty; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ + +var EMPTY = /*@__PURE__*/ new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { return subscriber.complete(); }); +function empty(scheduler) { + return scheduler ? emptyScheduled(scheduler) : EMPTY; +} +function emptyScheduled(scheduler) { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { return scheduler.schedule(function () { return subscriber.complete(); }); }); +} +//# sourceMappingURL=empty.js.map /***/ }), -/* 151 */ -/***/ (function(module, exports, __webpack_require__) { +/* 175 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "of", function() { return of; }); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(176); +/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(177); +/* harmony import */ var _scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(179); +/** PURE_IMPORTS_START _util_isScheduler,_fromArray,_scheduled_scheduleArray PURE_IMPORTS_END */ -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var th = moment.defineLocale('th', { - months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'), - monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'), - monthsParseExact: true, - weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'), - weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference - weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY เวลา H:mm', - LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm' - }, - meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/, - isPM: function (input) { - return input === 'หลังเที่ยง'; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'ก่อนเที่ยง'; - } else { - return 'หลังเที่ยง'; - } - }, - calendar : { - sameDay : '[วันนี้ เวลา] LT', - nextDay : '[พรุ่งนี้ เวลา] LT', - nextWeek : 'dddd[หน้า เวลา] LT', - lastDay : '[เมื่อวานนี้ เวลา] LT', - lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'อีก %s', - past : '%sที่แล้ว', - s : 'ไม่กี่วินาที', - ss : '%d วินาที', - m : '1 นาที', - mm : '%d นาที', - h : '1 ชั่วโมง', - hh : '%d ชั่วโมง', - d : '1 วัน', - dd : '%d วัน', - M : '1 เดือน', - MM : '%d เดือน', - y : '1 ปี', - yy : '%d ปี' - } - }); +function of() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var scheduler = args[args.length - 1]; + if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_0__["isScheduler"])(scheduler)) { + args.pop(); + return Object(_scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_2__["scheduleArray"])(args, scheduler); + } + else { + return Object(_fromArray__WEBPACK_IMPORTED_MODULE_1__["fromArray"])(args); + } +} +//# sourceMappingURL=of.js.map - return th; -}))); +/***/ }), +/* 176 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isScheduler", function() { return isScheduler; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function isScheduler(value) { + return value && typeof value.schedule === 'function'; +} +//# sourceMappingURL=isScheduler.js.map /***/ }), -/* 152 */ -/***/ (function(module, exports, __webpack_require__) { +/* 177 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fromArray", function() { return fromArray; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _util_subscribeToArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(178); +/* harmony import */ var _scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(179); +/** PURE_IMPORTS_START _Observable,_util_subscribeToArray,_scheduled_scheduleArray PURE_IMPORTS_END */ -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var tlPh = moment.defineLocale('tl-ph', { - months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'), - monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'), - weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'), - weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'), - weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'MM/D/YYYY', - LL : 'MMMM D, YYYY', - LLL : 'MMMM D, YYYY HH:mm', - LLLL : 'dddd, MMMM DD, YYYY HH:mm' - }, - calendar : { - sameDay: 'LT [ngayong araw]', - nextDay: '[Bukas ng] LT', - nextWeek: 'LT [sa susunod na] dddd', - lastDay: 'LT [kahapon]', - lastWeek: 'LT [noong nakaraang] dddd', - sameElse: 'L' - }, - relativeTime : { - future : 'sa loob ng %s', - past : '%s ang nakalipas', - s : 'ilang segundo', - ss : '%d segundo', - m : 'isang minuto', - mm : '%d minuto', - h : 'isang oras', - hh : '%d oras', - d : 'isang araw', - dd : '%d araw', - M : 'isang buwan', - MM : '%d buwan', - y : 'isang taon', - yy : '%d taon' - }, - dayOfMonthOrdinalParse: /\d{1,2}/, - ordinal : function (number) { - return number; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); +function fromArray(input, scheduler) { + if (!scheduler) { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](Object(_util_subscribeToArray__WEBPACK_IMPORTED_MODULE_1__["subscribeToArray"])(input)); + } + else { + return Object(_scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_2__["scheduleArray"])(input, scheduler); + } +} +//# sourceMappingURL=fromArray.js.map - return tlPh; -}))); +/***/ }), +/* 178 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeToArray", function() { return subscribeToArray; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var subscribeToArray = function (array) { + return function (subscriber) { + for (var i = 0, len = array.length; i < len && !subscriber.closed; i++) { + subscriber.next(array[i]); + } + subscriber.complete(); + }; +}; +//# sourceMappingURL=subscribeToArray.js.map /***/ }), -/* 153 */ -/***/ (function(module, exports, __webpack_require__) { +/* 179 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scheduleArray", function() { return scheduleArray; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(148); +/** PURE_IMPORTS_START _Observable,_Subscription PURE_IMPORTS_END */ -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; + +function scheduleArray(input, scheduler) { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + var sub = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); + var i = 0; + sub.add(scheduler.schedule(function () { + if (i === input.length) { + subscriber.complete(); + return; + } + subscriber.next(input[i++]); + if (!subscriber.closed) { + sub.add(this.schedule()); + } + })); + return sub; + }); +} +//# sourceMappingURL=scheduleArray.js.map - var numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_'); +/***/ }), +/* 180 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - function translateFuture(output) { - var time = output; - time = (output.indexOf('jaj') !== -1) ? - time.slice(0, -3) + 'leS' : - (output.indexOf('jar') !== -1) ? - time.slice(0, -3) + 'waQ' : - (output.indexOf('DIS') !== -1) ? - time.slice(0, -3) + 'nem' : - time + ' pIq'; - return time; - } +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "throwError", function() { return throwError; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ - function translatePast(output) { - var time = output; - time = (output.indexOf('jaj') !== -1) ? - time.slice(0, -3) + 'Hu’' : - (output.indexOf('jar') !== -1) ? - time.slice(0, -3) + 'wen' : - (output.indexOf('DIS') !== -1) ? - time.slice(0, -3) + 'ben' : - time + ' ret'; - return time; +function throwError(error, scheduler) { + if (!scheduler) { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { return subscriber.error(error); }); } - - function translate(number, withoutSuffix, string, isFuture) { - var numberNoun = numberAsNoun(number); - switch (string) { - case 'ss': - return numberNoun + ' lup'; - case 'mm': - return numberNoun + ' tup'; - case 'hh': - return numberNoun + ' rep'; - case 'dd': - return numberNoun + ' jaj'; - case 'MM': - return numberNoun + ' jar'; - case 'yy': - return numberNoun + ' DIS'; - } + else { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { return scheduler.schedule(dispatch, 0, { error: error, subscriber: subscriber }); }); } +} +function dispatch(_a) { + var error = _a.error, subscriber = _a.subscriber; + subscriber.error(error); +} +//# sourceMappingURL=throwError.js.map - function numberAsNoun(number) { - var hundred = Math.floor((number % 1000) / 100), - ten = Math.floor((number % 100) / 10), - one = number % 10, - word = ''; - if (hundred > 0) { - word += numbersNouns[hundred] + 'vatlh'; + +/***/ }), +/* 181 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AsyncSubject", function() { return AsyncSubject; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(158); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(148); +/** PURE_IMPORTS_START tslib,_Subject,_Subscription PURE_IMPORTS_END */ + + + +var AsyncSubject = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AsyncSubject, _super); + function AsyncSubject() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.value = null; + _this.hasNext = false; + _this.hasCompleted = false; + return _this; + } + AsyncSubject.prototype._subscribe = function (subscriber) { + if (this.hasError) { + subscriber.error(this.thrownError); + return _Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"].EMPTY; } - if (ten > 0) { - word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH'; + else if (this.hasCompleted && this.hasNext) { + subscriber.next(this.value); + subscriber.complete(); + return _Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"].EMPTY; } - if (one > 0) { - word += ((word !== '') ? ' ' : '') + numbersNouns[one]; + return _super.prototype._subscribe.call(this, subscriber); + }; + AsyncSubject.prototype.next = function (value) { + if (!this.hasCompleted) { + this.value = value; + this.hasNext = true; } - return (word === '') ? 'pagh' : word; - } - - var tlh = moment.defineLocale('tlh', { - months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'), - monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'), - monthsParseExact : true, - weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), - weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), - weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[DaHjaj] LT', - nextDay: '[wa’leS] LT', - nextWeek: 'LLL', - lastDay: '[wa’Hu’] LT', - lastWeek: 'LLL', - sameElse: 'L' - }, - relativeTime : { - future : translateFuture, - past : translatePast, - s : 'puS lup', - ss : translate, - m : 'wa’ tup', - mm : translate, - h : 'wa’ rep', - hh : translate, - d : 'wa’ jaj', - dd : translate, - M : 'wa’ jar', - MM : translate, - y : 'wa’ DIS', - yy : translate - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + }; + AsyncSubject.prototype.error = function (error) { + if (!this.hasCompleted) { + _super.prototype.error.call(this, error); } - }); - - return tlh; + }; + AsyncSubject.prototype.complete = function () { + this.hasCompleted = true; + if (this.hasNext) { + _super.prototype.next.call(this, this.value); + } + _super.prototype.complete.call(this); + }; + return AsyncSubject; +}(_Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"])); -}))); +//# sourceMappingURL=AsyncSubject.js.map /***/ }), -/* 154 */ -/***/ (function(module, exports, __webpack_require__) { +/* 182 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "asap", function() { return asap; }); +/* harmony import */ var _AsapAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(183); +/* harmony import */ var _AsapScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(185); +/** PURE_IMPORTS_START _AsapAction,_AsapScheduler PURE_IMPORTS_END */ -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var suffixes = { - 1: '\'inci', - 5: '\'inci', - 8: '\'inci', - 70: '\'inci', - 80: '\'inci', - 2: '\'nci', - 7: '\'nci', - 20: '\'nci', - 50: '\'nci', - 3: '\'üncü', - 4: '\'üncü', - 100: '\'üncü', - 6: '\'ncı', - 9: '\'uncu', - 10: '\'uncu', - 30: '\'uncu', - 60: '\'ıncı', - 90: '\'ıncı' - }; +var asap = /*@__PURE__*/ new _AsapScheduler__WEBPACK_IMPORTED_MODULE_1__["AsapScheduler"](_AsapAction__WEBPACK_IMPORTED_MODULE_0__["AsapAction"]); +//# sourceMappingURL=asap.js.map - var tr = moment.defineLocale('tr', { - months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'), - monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'), - weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'), - weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'), - weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[bugün saat] LT', - nextDay : '[yarın saat] LT', - nextWeek : '[gelecek] dddd [saat] LT', - lastDay : '[dün] LT', - lastWeek : '[geçen] dddd [saat] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s sonra', - past : '%s önce', - s : 'birkaç saniye', - ss : '%d saniye', - m : 'bir dakika', - mm : '%d dakika', - h : 'bir saat', - hh : '%d saat', - d : 'bir gün', - dd : '%d gün', - M : 'bir ay', - MM : '%d ay', - y : 'bir yıl', - yy : '%d yıl' - }, - ordinal: function (number, period) { - switch (period) { - case 'd': - case 'D': - case 'Do': - case 'DD': - return number; - default: - if (number === 0) { // special case for zero - return number + '\'ıncı'; - } - var a = number % 10, - b = number % 100 - a, - c = number >= 100 ? 100 : null; - return number + (suffixes[a] || suffixes[b] || suffixes[c]); - } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - return tr; +/***/ }), +/* 183 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -}))); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AsapAction", function() { return AsapAction; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _util_Immediate__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(184); +/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(167); +/** PURE_IMPORTS_START tslib,_util_Immediate,_AsyncAction PURE_IMPORTS_END */ + + + +var AsapAction = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AsapAction, _super); + function AsapAction(scheduler, work) { + var _this = _super.call(this, scheduler, work) || this; + _this.scheduler = scheduler; + _this.work = work; + return _this; + } + AsapAction.prototype.requestAsyncId = function (scheduler, id, delay) { + if (delay === void 0) { + delay = 0; + } + if (delay !== null && delay > 0) { + return _super.prototype.requestAsyncId.call(this, scheduler, id, delay); + } + scheduler.actions.push(this); + return scheduler.scheduled || (scheduler.scheduled = _util_Immediate__WEBPACK_IMPORTED_MODULE_1__["Immediate"].setImmediate(scheduler.flush.bind(scheduler, null))); + }; + AsapAction.prototype.recycleAsyncId = function (scheduler, id, delay) { + if (delay === void 0) { + delay = 0; + } + if ((delay !== null && delay > 0) || (delay === null && this.delay > 0)) { + return _super.prototype.recycleAsyncId.call(this, scheduler, id, delay); + } + if (scheduler.actions.length === 0) { + _util_Immediate__WEBPACK_IMPORTED_MODULE_1__["Immediate"].clearImmediate(id); + scheduler.scheduled = undefined; + } + return undefined; + }; + return AsapAction; +}(_AsyncAction__WEBPACK_IMPORTED_MODULE_2__["AsyncAction"])); + +//# sourceMappingURL=AsapAction.js.map /***/ }), -/* 155 */ -/***/ (function(module, exports, __webpack_require__) { +/* 184 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Immediate", function() { return Immediate; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var nextHandle = 1; +var tasksByHandle = {}; +function runIfPresent(handle) { + var cb = tasksByHandle[handle]; + if (cb) { + cb(); + } +} +var Immediate = { + setImmediate: function (cb) { + var handle = nextHandle++; + tasksByHandle[handle] = cb; + Promise.resolve().then(function () { return runIfPresent(handle); }); + return handle; + }, + clearImmediate: function (handle) { + delete tasksByHandle[handle]; + }, +}; +//# sourceMappingURL=Immediate.js.map -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/***/ }), +/* 185 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AsapScheduler", function() { return AsapScheduler; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(170); +/** PURE_IMPORTS_START tslib,_AsyncScheduler PURE_IMPORTS_END */ - // After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals. - // This is currently too difficult (maybe even impossible) to add. - var tzl = moment.defineLocale('tzl', { - months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'), - monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'), - weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'), - weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'), - weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'), - longDateFormat : { - LT : 'HH.mm', - LTS : 'HH.mm.ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM [dallas] YYYY', - LLL : 'D. MMMM [dallas] YYYY HH.mm', - LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm' - }, - meridiemParse: /d\'o|d\'a/i, - isPM : function (input) { - return 'd\'o' === input.toLowerCase(); - }, - meridiem : function (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'd\'o' : 'D\'O'; - } else { - return isLower ? 'd\'a' : 'D\'A'; + +var AsapScheduler = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AsapScheduler, _super); + function AsapScheduler() { + return _super !== null && _super.apply(this, arguments) || this; + } + AsapScheduler.prototype.flush = function (action) { + this.active = true; + this.scheduled = undefined; + var actions = this.actions; + var error; + var index = -1; + var count = actions.length; + action = action || actions.shift(); + do { + if (error = action.execute(action.state, action.delay)) { + break; } - }, - calendar : { - sameDay : '[oxhi à] LT', - nextDay : '[demà à] LT', - nextWeek : 'dddd [à] LT', - lastDay : '[ieiri à] LT', - lastWeek : '[sür el] dddd [lasteu à] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'osprei %s', - past : 'ja%s', - s : processRelativeTime, - ss : processRelativeTime, - m : processRelativeTime, - mm : processRelativeTime, - h : processRelativeTime, - hh : processRelativeTime, - d : processRelativeTime, - dd : processRelativeTime, - M : processRelativeTime, - MM : processRelativeTime, - y : processRelativeTime, - yy : processRelativeTime - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + } while (++index < count && (action = actions.shift())); + this.active = false; + if (error) { + while (++index < count && (action = actions.shift())) { + action.unsubscribe(); + } + throw error; } - }); + }; + return AsapScheduler; +}(_AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__["AsyncScheduler"])); - function processRelativeTime(number, withoutSuffix, key, isFuture) { - var format = { - 's': ['viensas secunds', '\'iensas secunds'], - 'ss': [number + ' secunds', '' + number + ' secunds'], - 'm': ['\'n míut', '\'iens míut'], - 'mm': [number + ' míuts', '' + number + ' míuts'], - 'h': ['\'n þora', '\'iensa þora'], - 'hh': [number + ' þoras', '' + number + ' þoras'], - 'd': ['\'n ziua', '\'iensa ziua'], - 'dd': [number + ' ziuas', '' + number + ' ziuas'], - 'M': ['\'n mes', '\'iens mes'], - 'MM': [number + ' mesen', '' + number + ' mesen'], - 'y': ['\'n ar', '\'iens ar'], - 'yy': [number + ' ars', '' + number + ' ars'] - }; - return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]); - } +//# sourceMappingURL=AsapScheduler.js.map - return tzl; -}))); +/***/ }), +/* 186 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "async", function() { return async; }); +/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(167); +/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(170); +/** PURE_IMPORTS_START _AsyncAction,_AsyncScheduler PURE_IMPORTS_END */ -/***/ }), -/* 156 */ -/***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration +var async = /*@__PURE__*/ new _AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__["AsyncScheduler"](_AsyncAction__WEBPACK_IMPORTED_MODULE_0__["AsyncAction"]); +//# sourceMappingURL=async.js.map -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/***/ }), +/* 187 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - var tzm = moment.defineLocale('tzm', { - months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), - monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), - weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), - weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), - weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS: 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[ⴰⵙⴷⵅ ⴴ] LT', - nextDay: '[ⴰⵙⴽⴰ ⴴ] LT', - nextWeek: 'dddd [ⴴ] LT', - lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT', - lastWeek: 'dddd [ⴴ] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s', - past : 'ⵢⴰⵏ %s', - s : 'ⵉⵎⵉⴽ', - ss : '%d ⵉⵎⵉⴽ', - m : 'ⵎⵉⵏⵓⴺ', - mm : '%d ⵎⵉⵏⵓⴺ', - h : 'ⵙⴰⵄⴰ', - hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ', - d : 'ⴰⵙⵙ', - dd : '%d oⵙⵙⴰⵏ', - M : 'ⴰⵢoⵓⵔ', - MM : '%d ⵉⵢⵢⵉⵔⵏ', - y : 'ⴰⵙⴳⴰⵙ', - yy : '%d ⵉⵙⴳⴰⵙⵏ' - }, - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. - } - }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "animationFrame", function() { return animationFrame; }); +/* harmony import */ var _AnimationFrameAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(188); +/* harmony import */ var _AnimationFrameScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(189); +/** PURE_IMPORTS_START _AnimationFrameAction,_AnimationFrameScheduler PURE_IMPORTS_END */ - return tzm; -}))); +var animationFrame = /*@__PURE__*/ new _AnimationFrameScheduler__WEBPACK_IMPORTED_MODULE_1__["AnimationFrameScheduler"](_AnimationFrameAction__WEBPACK_IMPORTED_MODULE_0__["AnimationFrameAction"]); +//# sourceMappingURL=animationFrame.js.map /***/ }), -/* 157 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration +/* 188 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnimationFrameAction", function() { return AnimationFrameAction; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(167); +/** PURE_IMPORTS_START tslib,_AsyncAction PURE_IMPORTS_END */ - var tzmLatn = moment.defineLocale('tzm-latn', { - months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), - monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), - weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), - weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), - weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[asdkh g] LT', - nextDay: '[aska g] LT', - nextWeek: 'dddd [g] LT', - lastDay: '[assant g] LT', - lastWeek: 'dddd [g] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'dadkh s yan %s', - past : 'yan %s', - s : 'imik', - ss : '%d imik', - m : 'minuḍ', - mm : '%d minuḍ', - h : 'saɛa', - hh : '%d tassaɛin', - d : 'ass', - dd : '%d ossan', - M : 'ayowr', - MM : '%d iyyirn', - y : 'asgas', - yy : '%d isgasn' - }, - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. +var AnimationFrameAction = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AnimationFrameAction, _super); + function AnimationFrameAction(scheduler, work) { + var _this = _super.call(this, scheduler, work) || this; + _this.scheduler = scheduler; + _this.work = work; + return _this; + } + AnimationFrameAction.prototype.requestAsyncId = function (scheduler, id, delay) { + if (delay === void 0) { + delay = 0; } - }); - - return tzmLatn; + if (delay !== null && delay > 0) { + return _super.prototype.requestAsyncId.call(this, scheduler, id, delay); + } + scheduler.actions.push(this); + return scheduler.scheduled || (scheduler.scheduled = requestAnimationFrame(function () { return scheduler.flush(null); })); + }; + AnimationFrameAction.prototype.recycleAsyncId = function (scheduler, id, delay) { + if (delay === void 0) { + delay = 0; + } + if ((delay !== null && delay > 0) || (delay === null && this.delay > 0)) { + return _super.prototype.recycleAsyncId.call(this, scheduler, id, delay); + } + if (scheduler.actions.length === 0) { + cancelAnimationFrame(id); + scheduler.scheduled = undefined; + } + return undefined; + }; + return AnimationFrameAction; +}(_AsyncAction__WEBPACK_IMPORTED_MODULE_1__["AsyncAction"])); -}))); +//# sourceMappingURL=AnimationFrameAction.js.map /***/ }), -/* 158 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js language configuration +/* 189 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnimationFrameScheduler", function() { return AnimationFrameScheduler; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(170); +/** PURE_IMPORTS_START tslib,_AsyncScheduler PURE_IMPORTS_END */ - var ugCn = moment.defineLocale('ug-cn', { - months: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split( - '_' - ), - monthsShort: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split( - '_' - ), - weekdays: 'يەكشەنبە_دۈشەنبە_سەيشەنبە_چارشەنبە_پەيشەنبە_جۈمە_شەنبە'.split( - '_' - ), - weekdaysShort: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'), - weekdaysMin: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'), - longDateFormat: { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L: 'YYYY-MM-DD', - LL: 'YYYY-يىلىM-ئاينىڭD-كۈنى', - LLL: 'YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm', - LLLL: 'dddd، YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm' - }, - meridiemParse: /يېرىم كېچە|سەھەر|چۈشتىن بۇرۇن|چۈش|چۈشتىن كېيىن|كەچ/, - meridiemHour: function (hour, meridiem) { - if (hour === 12) { - hour = 0; +var AnimationFrameScheduler = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AnimationFrameScheduler, _super); + function AnimationFrameScheduler() { + return _super !== null && _super.apply(this, arguments) || this; + } + AnimationFrameScheduler.prototype.flush = function (action) { + this.active = true; + this.scheduled = undefined; + var actions = this.actions; + var error; + var index = -1; + var count = actions.length; + action = action || actions.shift(); + do { + if (error = action.execute(action.state, action.delay)) { + break; } - if ( - meridiem === 'يېرىم كېچە' || - meridiem === 'سەھەر' || - meridiem === 'چۈشتىن بۇرۇن' - ) { - return hour; - } else if (meridiem === 'چۈشتىن كېيىن' || meridiem === 'كەچ') { - return hour + 12; - } else { - return hour >= 11 ? hour : hour + 12; + } while (++index < count && (action = actions.shift())); + this.active = false; + if (error) { + while (++index < count && (action = actions.shift())) { + action.unsubscribe(); } - }, - meridiem: function (hour, minute, isLower) { - var hm = hour * 100 + minute; - if (hm < 600) { - return 'يېرىم كېچە'; - } else if (hm < 900) { - return 'سەھەر'; - } else if (hm < 1130) { - return 'چۈشتىن بۇرۇن'; - } else if (hm < 1230) { - return 'چۈش'; - } else if (hm < 1800) { - return 'چۈشتىن كېيىن'; - } else { - return 'كەچ'; - } - }, - calendar: { - sameDay: '[بۈگۈن سائەت] LT', - nextDay: '[ئەتە سائەت] LT', - nextWeek: '[كېلەركى] dddd [سائەت] LT', - lastDay: '[تۆنۈگۈن] LT', - lastWeek: '[ئالدىنقى] dddd [سائەت] LT', - sameElse: 'L' - }, - relativeTime: { - future: '%s كېيىن', - past: '%s بۇرۇن', - s: 'نەچچە سېكونت', - ss: '%d سېكونت', - m: 'بىر مىنۇت', - mm: '%d مىنۇت', - h: 'بىر سائەت', - hh: '%d سائەت', - d: 'بىر كۈن', - dd: '%d كۈن', - M: 'بىر ئاي', - MM: '%d ئاي', - y: 'بىر يىل', - yy: '%d يىل' - }, - - dayOfMonthOrdinalParse: /\d{1,2}(-كۈنى|-ئاي|-ھەپتە)/, - ordinal: function (number, period) { - switch (period) { - case 'd': - case 'D': - case 'DDD': - return number + '-كۈنى'; - case 'w': - case 'W': - return number + '-ھەپتە'; - default: - return number; - } - }, - preparse: function (string) { - return string.replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/,/g, '،'); - }, - week: { - // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 - dow: 1, // Monday is the first day of the week. - doy: 7 // The week that contains Jan 1st is the first week of the year. + throw error; } - }); - - return ugCn; + }; + return AnimationFrameScheduler; +}(_AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__["AsyncScheduler"])); -}))); +//# sourceMappingURL=AnimationFrameScheduler.js.map /***/ }), -/* 159 */ -/***/ (function(module, exports, __webpack_require__) { +/* 190 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -//! moment.js locale configuration +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VirtualTimeScheduler", function() { return VirtualTimeScheduler; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VirtualAction", function() { return VirtualAction; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(167); +/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(170); +/** PURE_IMPORTS_START tslib,_AsyncAction,_AsyncScheduler PURE_IMPORTS_END */ -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - function plural(word, num) { - var forms = word.split('_'); - return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); - } - function relativeTimeWithPlural(number, withoutSuffix, key) { - var format = { - 'ss': withoutSuffix ? 'секунда_секунди_секунд' : 'секунду_секунди_секунд', - 'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин', - 'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин', - 'dd': 'день_дні_днів', - 'MM': 'місяць_місяці_місяців', - 'yy': 'рік_роки_років' - }; - if (key === 'm') { - return withoutSuffix ? 'хвилина' : 'хвилину'; - } - else if (key === 'h') { - return withoutSuffix ? 'година' : 'годину'; +var VirtualTimeScheduler = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VirtualTimeScheduler, _super); + function VirtualTimeScheduler(SchedulerAction, maxFrames) { + if (SchedulerAction === void 0) { + SchedulerAction = VirtualAction; } - else { - return number + ' ' + plural(format[key], +number); + if (maxFrames === void 0) { + maxFrames = Number.POSITIVE_INFINITY; } + var _this = _super.call(this, SchedulerAction, function () { return _this.frame; }) || this; + _this.maxFrames = maxFrames; + _this.frame = 0; + _this.index = -1; + return _this; } - function weekdaysCaseReplace(m, format) { - var weekdays = { - 'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'), - 'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'), - 'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_') - }; - - if (m === true) { - return weekdays['nominative'].slice(1, 7).concat(weekdays['nominative'].slice(0, 1)); + VirtualTimeScheduler.prototype.flush = function () { + var _a = this, actions = _a.actions, maxFrames = _a.maxFrames; + var error, action; + while ((action = actions[0]) && action.delay <= maxFrames) { + actions.shift(); + this.frame = action.delay; + if (error = action.execute(action.state, action.delay)) { + break; + } } - if (!m) { - return weekdays['nominative']; + if (error) { + while (action = actions.shift()) { + action.unsubscribe(); + } + throw error; } + }; + VirtualTimeScheduler.frameTimeFactor = 10; + return VirtualTimeScheduler; +}(_AsyncScheduler__WEBPACK_IMPORTED_MODULE_2__["AsyncScheduler"])); - var nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ? - 'accusative' : - ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ? - 'genitive' : - 'nominative'); - return weekdays[nounCase][m.day()]; - } - function processHoursFunction(str) { - return function () { - return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT'; - }; +var VirtualAction = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VirtualAction, _super); + function VirtualAction(scheduler, work, index) { + if (index === void 0) { + index = scheduler.index += 1; + } + var _this = _super.call(this, scheduler, work) || this; + _this.scheduler = scheduler; + _this.work = work; + _this.index = index; + _this.active = true; + _this.index = scheduler.index = index; + return _this; } - - var uk = moment.defineLocale('uk', { - months : { - 'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'), - 'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_') - }, - monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'), - weekdays : weekdaysCaseReplace, - weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), - weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY р.', - LLL : 'D MMMM YYYY р., HH:mm', - LLLL : 'dddd, D MMMM YYYY р., HH:mm' - }, - calendar : { - sameDay: processHoursFunction('[Сьогодні '), - nextDay: processHoursFunction('[Завтра '), - lastDay: processHoursFunction('[Вчора '), - nextWeek: processHoursFunction('[У] dddd ['), - lastWeek: function () { - switch (this.day()) { - case 0: - case 3: - case 5: - case 6: - return processHoursFunction('[Минулої] dddd [').call(this); - case 1: - case 2: - case 4: - return processHoursFunction('[Минулого] dddd [').call(this); - } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'за %s', - past : '%s тому', - s : 'декілька секунд', - ss : relativeTimeWithPlural, - m : relativeTimeWithPlural, - mm : relativeTimeWithPlural, - h : 'годину', - hh : relativeTimeWithPlural, - d : 'день', - dd : relativeTimeWithPlural, - M : 'місяць', - MM : relativeTimeWithPlural, - y : 'рік', - yy : relativeTimeWithPlural - }, - // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason - meridiemParse: /ночі|ранку|дня|вечора/, - isPM: function (input) { - return /^(дня|вечора)$/.test(input); - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'ночі'; - } else if (hour < 12) { - return 'ранку'; - } else if (hour < 17) { - return 'дня'; - } else { - return 'вечора'; + VirtualAction.prototype.schedule = function (state, delay) { + if (delay === void 0) { + delay = 0; + } + if (!this.id) { + return _super.prototype.schedule.call(this, state, delay); + } + this.active = false; + var action = new VirtualAction(this.scheduler, this.work); + this.add(action); + return action.schedule(state, delay); + }; + VirtualAction.prototype.requestAsyncId = function (scheduler, id, delay) { + if (delay === void 0) { + delay = 0; + } + this.delay = scheduler.frame + delay; + var actions = scheduler.actions; + actions.push(this); + actions.sort(VirtualAction.sortActions); + return true; + }; + VirtualAction.prototype.recycleAsyncId = function (scheduler, id, delay) { + if (delay === void 0) { + delay = 0; + } + return undefined; + }; + VirtualAction.prototype._execute = function (state, delay) { + if (this.active === true) { + return _super.prototype._execute.call(this, state, delay); + } + }; + VirtualAction.sortActions = function (a, b) { + if (a.delay === b.delay) { + if (a.index === b.index) { + return 0; } - }, - dayOfMonthOrdinalParse: /\d{1,2}-(й|го)/, - ordinal: function (number, period) { - switch (period) { - case 'M': - case 'd': - case 'DDD': - case 'w': - case 'W': - return number + '-й'; - case 'D': - return number + '-го'; - default: - return number; + else if (a.index > b.index) { + return 1; + } + else { + return -1; } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. } - }); - - return uk; + else if (a.delay > b.delay) { + return 1; + } + else { + return -1; + } + }; + return VirtualAction; +}(_AsyncAction__WEBPACK_IMPORTED_MODULE_1__["AsyncAction"])); -}))); +//# sourceMappingURL=VirtualTimeScheduler.js.map /***/ }), -/* 160 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration - -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/* 191 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "identity", function() { return identity; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function identity(x) { + return x; +} +//# sourceMappingURL=identity.js.map - var months = [ - 'جنوری', - 'فروری', - 'مارچ', - 'اپریل', - 'مئی', - 'جون', - 'جولائی', - 'اگست', - 'ستمبر', - 'اکتوبر', - 'نومبر', - 'دسمبر' - ]; - var days = [ - 'اتوار', - 'پیر', - 'منگل', - 'بدھ', - 'جمعرات', - 'جمعہ', - 'ہفتہ' - ]; - var ur = moment.defineLocale('ur', { - months : months, - monthsShort : months, - weekdays : days, - weekdaysShort : days, - weekdaysMin : days, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd، D MMMM YYYY HH:mm' - }, - meridiemParse: /صبح|شام/, - isPM : function (input) { - return 'شام' === input; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'صبح'; - } - return 'شام'; - }, - calendar : { - sameDay : '[آج بوقت] LT', - nextDay : '[کل بوقت] LT', - nextWeek : 'dddd [بوقت] LT', - lastDay : '[گذشتہ روز بوقت] LT', - lastWeek : '[گذشتہ] dddd [بوقت] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s بعد', - past : '%s قبل', - s : 'چند سیکنڈ', - ss : '%d سیکنڈ', - m : 'ایک منٹ', - mm : '%d منٹ', - h : 'ایک گھنٹہ', - hh : '%d گھنٹے', - d : 'ایک دن', - dd : '%d دن', - M : 'ایک ماہ', - MM : '%d ماہ', - y : 'ایک سال', - yy : '%d سال' - }, - preparse: function (string) { - return string.replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/,/g, '،'); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); +/***/ }), +/* 192 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - return ur; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isObservable", function() { return isObservable; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ -}))); +function isObservable(obj) { + return !!obj && (obj instanceof _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"] || (typeof obj.lift === 'function' && typeof obj.subscribe === 'function')); +} +//# sourceMappingURL=isObservable.js.map /***/ }), -/* 161 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration - -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/* 193 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ArgumentOutOfRangeError", function() { return ArgumentOutOfRangeError; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var ArgumentOutOfRangeErrorImpl = /*@__PURE__*/ (function () { + function ArgumentOutOfRangeErrorImpl() { + Error.call(this); + this.message = 'argument out of range'; + this.name = 'ArgumentOutOfRangeError'; + return this; + } + ArgumentOutOfRangeErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); + return ArgumentOutOfRangeErrorImpl; +})(); +var ArgumentOutOfRangeError = ArgumentOutOfRangeErrorImpl; +//# sourceMappingURL=ArgumentOutOfRangeError.js.map - var uz = moment.defineLocale('uz', { - months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'), - monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'), - weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'), - weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'), - weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'D MMMM YYYY, dddd HH:mm' - }, - calendar : { - sameDay : '[Бугун соат] LT [да]', - nextDay : '[Эртага] LT [да]', - nextWeek : 'dddd [куни соат] LT [да]', - lastDay : '[Кеча соат] LT [да]', - lastWeek : '[Утган] dddd [куни соат] LT [да]', - sameElse : 'L' - }, - relativeTime : { - future : 'Якин %s ичида', - past : 'Бир неча %s олдин', - s : 'фурсат', - ss : '%d фурсат', - m : 'бир дакика', - mm : '%d дакика', - h : 'бир соат', - hh : '%d соат', - d : 'бир кун', - dd : '%d кун', - M : 'бир ой', - MM : '%d ой', - y : 'бир йил', - yy : '%d йил' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 4th is the first week of the year. - } - }); - return uz; +/***/ }), +/* 194 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -}))); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EmptyError", function() { return EmptyError; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var EmptyErrorImpl = /*@__PURE__*/ (function () { + function EmptyErrorImpl() { + Error.call(this); + this.message = 'no elements in sequence'; + this.name = 'EmptyError'; + return this; + } + EmptyErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); + return EmptyErrorImpl; +})(); +var EmptyError = EmptyErrorImpl; +//# sourceMappingURL=EmptyError.js.map /***/ }), -/* 162 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration - -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +/* 195 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TimeoutError", function() { return TimeoutError; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var TimeoutErrorImpl = /*@__PURE__*/ (function () { + function TimeoutErrorImpl() { + Error.call(this); + this.message = 'Timeout has occurred'; + this.name = 'TimeoutError'; + return this; + } + TimeoutErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); + return TimeoutErrorImpl; +})(); +var TimeoutError = TimeoutErrorImpl; +//# sourceMappingURL=TimeoutError.js.map - var uzLatn = moment.defineLocale('uz-latn', { - months : 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split('_'), - monthsShort : 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'), - weekdays : 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split('_'), - weekdaysShort : 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'), - weekdaysMin : 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'D MMMM YYYY, dddd HH:mm' - }, - calendar : { - sameDay : '[Bugun soat] LT [da]', - nextDay : '[Ertaga] LT [da]', - nextWeek : 'dddd [kuni soat] LT [da]', - lastDay : '[Kecha soat] LT [da]', - lastWeek : '[O\'tgan] dddd [kuni soat] LT [da]', - sameElse : 'L' - }, - relativeTime : { - future : 'Yaqin %s ichida', - past : 'Bir necha %s oldin', - s : 'soniya', - ss : '%d soniya', - m : 'bir daqiqa', - mm : '%d daqiqa', - h : 'bir soat', - hh : '%d soat', - d : 'bir kun', - dd : '%d kun', - M : 'bir oy', - MM : '%d oy', - y : 'bir yil', - yy : '%d yil' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - return uzLatn; +/***/ }), +/* 196 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -}))); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bindCallback", function() { return bindCallback; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _AsyncSubject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(181); +/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(197); +/* harmony import */ var _util_canReportError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(142); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(149); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(176); +/** PURE_IMPORTS_START _Observable,_AsyncSubject,_operators_map,_util_canReportError,_util_isArray,_util_isScheduler PURE_IMPORTS_END */ -/***/ }), -/* 163 */ -/***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var vi = moment.defineLocale('vi', { - months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'), - monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'), - monthsParseExact : true, - weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'), - weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), - weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), - weekdaysParseExact : true, - meridiemParse: /sa|ch/i, - isPM : function (input) { - return /^ch$/i.test(input); - }, - meridiem : function (hours, minutes, isLower) { - if (hours < 12) { - return isLower ? 'sa' : 'SA'; - } else { - return isLower ? 'ch' : 'CH'; +function bindCallback(callbackFunc, resultSelector, scheduler) { + if (resultSelector) { + if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_5__["isScheduler"])(resultSelector)) { + scheduler = resultSelector; + } + else { + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return bindCallback(callbackFunc, scheduler).apply(void 0, args).pipe(Object(_operators_map__WEBPACK_IMPORTED_MODULE_2__["map"])(function (args) { return Object(_util_isArray__WEBPACK_IMPORTED_MODULE_4__["isArray"])(args) ? resultSelector.apply(void 0, args) : resultSelector(args); })); + }; + } + } + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var context = this; + var subject; + var params = { + context: context, + subject: subject, + callbackFunc: callbackFunc, + scheduler: scheduler, + }; + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + if (!scheduler) { + if (!subject) { + subject = new _AsyncSubject__WEBPACK_IMPORTED_MODULE_1__["AsyncSubject"](); + var handler = function () { + var innerArgs = []; + for (var _i = 0; _i < arguments.length; _i++) { + innerArgs[_i] = arguments[_i]; + } + subject.next(innerArgs.length <= 1 ? innerArgs[0] : innerArgs); + subject.complete(); + }; + try { + callbackFunc.apply(context, args.concat([handler])); + } + catch (err) { + if (Object(_util_canReportError__WEBPACK_IMPORTED_MODULE_3__["canReportError"])(subject)) { + subject.error(err); + } + else { + console.warn(err); + } + } + } + return subject.subscribe(subscriber); } - }, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM [năm] YYYY', - LLL : 'D MMMM [năm] YYYY HH:mm', - LLLL : 'dddd, D MMMM [năm] YYYY HH:mm', - l : 'DD/M/YYYY', - ll : 'D MMM YYYY', - lll : 'D MMM YYYY HH:mm', - llll : 'ddd, D MMM YYYY HH:mm' - }, - calendar : { - sameDay: '[Hôm nay lúc] LT', - nextDay: '[Ngày mai lúc] LT', - nextWeek: 'dddd [tuần tới lúc] LT', - lastDay: '[Hôm qua lúc] LT', - lastWeek: 'dddd [tuần rồi lúc] LT', - sameElse: 'L' - }, - relativeTime : { - future : '%s tới', - past : '%s trước', - s : 'vài giây', - ss : '%d giây' , - m : 'một phút', - mm : '%d phút', - h : 'một giờ', - hh : '%d giờ', - d : 'một ngày', - dd : '%d ngày', - M : 'một tháng', - MM : '%d tháng', - y : 'một năm', - yy : '%d năm' - }, - dayOfMonthOrdinalParse: /\d{1,2}/, - ordinal : function (number) { - return number; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + else { + var state = { + args: args, subscriber: subscriber, params: params, + }; + return scheduler.schedule(dispatch, 0, state); + } + }); + }; +} +function dispatch(state) { + var _this = this; + var self = this; + var args = state.args, subscriber = state.subscriber, params = state.params; + var callbackFunc = params.callbackFunc, context = params.context, scheduler = params.scheduler; + var subject = params.subject; + if (!subject) { + subject = params.subject = new _AsyncSubject__WEBPACK_IMPORTED_MODULE_1__["AsyncSubject"](); + var handler = function () { + var innerArgs = []; + for (var _i = 0; _i < arguments.length; _i++) { + innerArgs[_i] = arguments[_i]; + } + var value = innerArgs.length <= 1 ? innerArgs[0] : innerArgs; + _this.add(scheduler.schedule(dispatchNext, 0, { value: value, subject: subject })); + }; + try { + callbackFunc.apply(context, args.concat([handler])); } - }); - - return vi; - -}))); + catch (err) { + subject.error(err); + } + } + this.add(subject.subscribe(subscriber)); +} +function dispatchNext(state) { + var value = state.value, subject = state.subject; + subject.next(value); + subject.complete(); +} +function dispatchError(state) { + var err = state.err, subject = state.subject; + subject.error(err); +} +//# sourceMappingURL=bindCallback.js.map /***/ }), -/* 164 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration +/* 197 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "map", function() { return map; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MapOperator", function() { return MapOperator; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ - var xPseudo = moment.defineLocale('x-pseudo', { - months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'), - monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'), - monthsParseExact : true, - weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'), - weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'), - weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[T~ódá~ý át] LT', - nextDay : '[T~ómó~rró~w át] LT', - nextWeek : 'dddd [át] LT', - lastDay : '[Ý~ést~érdá~ý át] LT', - lastWeek : '[L~ást] dddd [át] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'í~ñ %s', - past : '%s á~gó', - s : 'á ~féw ~sécó~ñds', - ss : '%d s~écóñ~ds', - m : 'á ~míñ~úté', - mm : '%d m~íñú~tés', - h : 'á~ñ hó~úr', - hh : '%d h~óúrs', - d : 'á ~dáý', - dd : '%d d~áýs', - M : 'á ~móñ~th', - MM : '%d m~óñt~hs', - y : 'á ~ýéár', - yy : '%d ý~éárs' - }, - dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. +function map(project, thisArg) { + return function mapOperation(source) { + if (typeof project !== 'function') { + throw new TypeError('argument is not a function. Are you looking for `mapTo()`?'); } - }); - - return xPseudo; + return source.lift(new MapOperator(project, thisArg)); + }; +} +var MapOperator = /*@__PURE__*/ (function () { + function MapOperator(project, thisArg) { + this.project = project; + this.thisArg = thisArg; + } + MapOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new MapSubscriber(subscriber, this.project, this.thisArg)); + }; + return MapOperator; +}()); -}))); +var MapSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MapSubscriber, _super); + function MapSubscriber(destination, project, thisArg) { + var _this = _super.call(this, destination) || this; + _this.project = project; + _this.count = 0; + _this.thisArg = thisArg || _this; + return _this; + } + MapSubscriber.prototype._next = function (value) { + var result; + try { + result = this.project.call(this.thisArg, value, this.count++); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.next(result); + }; + return MapSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=map.js.map /***/ }), -/* 165 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration - -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - - - var yo = moment.defineLocale('yo', { - months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'), - monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'), - weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'), - weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'), - weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'), - longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY h:mm A', - LLLL : 'dddd, D MMMM YYYY h:mm A' - }, - calendar : { - sameDay : '[Ònì ni] LT', - nextDay : '[Ọ̀la ni] LT', - nextWeek : 'dddd [Ọsẹ̀ tón\'bọ] [ni] LT', - lastDay : '[Àna ni] LT', - lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'ní %s', - past : '%s kọjá', - s : 'ìsẹjú aayá die', - ss :'aayá %d', - m : 'ìsẹjú kan', - mm : 'ìsẹjú %d', - h : 'wákati kan', - hh : 'wákati %d', - d : 'ọjọ́ kan', - dd : 'ọjọ́ %d', - M : 'osù kan', - MM : 'osù %d', - y : 'ọdún kan', - yy : 'ọdún %d' - }, - dayOfMonthOrdinalParse : /ọjọ́\s\d{1,2}/, - ordinal : 'ọjọ́ %d', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - return yo; +/* 198 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -}))); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bindNodeCallback", function() { return bindNodeCallback; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _AsyncSubject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(181); +/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(197); +/* harmony import */ var _util_canReportError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(142); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(176); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(149); +/** PURE_IMPORTS_START _Observable,_AsyncSubject,_operators_map,_util_canReportError,_util_isScheduler,_util_isArray PURE_IMPORTS_END */ -/***/ }), -/* 166 */ -/***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - var zhCn = moment.defineLocale('zh-cn', { - months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), - monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), - weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), - weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'), - weekdaysMin : '日_一_二_三_四_五_六'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY/MM/DD', - LL : 'YYYY年M月D日', - LLL : 'YYYY年M月D日Ah点mm分', - LLLL : 'YYYY年M月D日ddddAh点mm分', - l : 'YYYY/M/D', - ll : 'YYYY年M月D日', - lll : 'YYYY年M月D日 HH:mm', - llll : 'YYYY年M月D日dddd HH:mm' - }, - meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, - meridiemHour: function (hour, meridiem) { - if (hour === 12) { - hour = 0; +function bindNodeCallback(callbackFunc, resultSelector, scheduler) { + if (resultSelector) { + if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_4__["isScheduler"])(resultSelector)) { + scheduler = resultSelector; + } + else { + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return bindNodeCallback(callbackFunc, scheduler).apply(void 0, args).pipe(Object(_operators_map__WEBPACK_IMPORTED_MODULE_2__["map"])(function (args) { return Object(_util_isArray__WEBPACK_IMPORTED_MODULE_5__["isArray"])(args) ? resultSelector.apply(void 0, args) : resultSelector(args); })); + }; + } + } + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var params = { + subject: undefined, + args: args, + callbackFunc: callbackFunc, + scheduler: scheduler, + context: this, + }; + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + var context = params.context; + var subject = params.subject; + if (!scheduler) { + if (!subject) { + subject = params.subject = new _AsyncSubject__WEBPACK_IMPORTED_MODULE_1__["AsyncSubject"](); + var handler = function () { + var innerArgs = []; + for (var _i = 0; _i < arguments.length; _i++) { + innerArgs[_i] = arguments[_i]; + } + var err = innerArgs.shift(); + if (err) { + subject.error(err); + return; + } + subject.next(innerArgs.length <= 1 ? innerArgs[0] : innerArgs); + subject.complete(); + }; + try { + callbackFunc.apply(context, args.concat([handler])); + } + catch (err) { + if (Object(_util_canReportError__WEBPACK_IMPORTED_MODULE_3__["canReportError"])(subject)) { + subject.error(err); + } + else { + console.warn(err); + } + } + } + return subject.subscribe(subscriber); } - if (meridiem === '凌晨' || meridiem === '早上' || - meridiem === '上午') { - return hour; - } else if (meridiem === '下午' || meridiem === '晚上') { - return hour + 12; - } else { - // '中午' - return hour >= 11 ? hour : hour + 12; + else { + return scheduler.schedule(dispatch, 0, { params: params, subscriber: subscriber, context: context }); } - }, - meridiem : function (hour, minute, isLower) { - var hm = hour * 100 + minute; - if (hm < 600) { - return '凌晨'; - } else if (hm < 900) { - return '早上'; - } else if (hm < 1130) { - return '上午'; - } else if (hm < 1230) { - return '中午'; - } else if (hm < 1800) { - return '下午'; - } else { - return '晚上'; + }); + }; +} +function dispatch(state) { + var _this = this; + var params = state.params, subscriber = state.subscriber, context = state.context; + var callbackFunc = params.callbackFunc, args = params.args, scheduler = params.scheduler; + var subject = params.subject; + if (!subject) { + subject = params.subject = new _AsyncSubject__WEBPACK_IMPORTED_MODULE_1__["AsyncSubject"](); + var handler = function () { + var innerArgs = []; + for (var _i = 0; _i < arguments.length; _i++) { + innerArgs[_i] = arguments[_i]; } - }, - calendar : { - sameDay : '[今天]LT', - nextDay : '[明天]LT', - nextWeek : '[下]ddddLT', - lastDay : '[昨天]LT', - lastWeek : '[上]ddddLT', - sameElse : 'L' - }, - dayOfMonthOrdinalParse: /\d{1,2}(日|月|周)/, - ordinal : function (number, period) { - switch (period) { - case 'd': - case 'D': - case 'DDD': - return number + '日'; - case 'M': - return number + '月'; - case 'w': - case 'W': - return number + '周'; - default: - return number; + var err = innerArgs.shift(); + if (err) { + _this.add(scheduler.schedule(dispatchError, 0, { err: err, subject: subject })); } - }, - relativeTime : { - future : '%s内', - past : '%s前', - s : '几秒', - ss : '%d 秒', - m : '1 分钟', - mm : '%d 分钟', - h : '1 小时', - hh : '%d 小时', - d : '1 天', - dd : '%d 天', - M : '1 个月', - MM : '%d 个月', - y : '1 年', - yy : '%d 年' - }, - week : { - // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. + else { + var value = innerArgs.length <= 1 ? innerArgs[0] : innerArgs; + _this.add(scheduler.schedule(dispatchNext, 0, { value: value, subject: subject })); + } + }; + try { + callbackFunc.apply(context, args.concat([handler])); } - }); - - return zhCn; - -}))); + catch (err) { + this.add(scheduler.schedule(dispatchError, 0, { err: err, subject: subject })); + } + } + this.add(subject.subscribe(subscriber)); +} +function dispatchNext(arg) { + var value = arg.value, subject = arg.subject; + subject.next(value); + subject.complete(); +} +function dispatchError(arg) { + var err = arg.err, subject = arg.subject; + subject.error(err); +} +//# sourceMappingURL=bindNodeCallback.js.map /***/ }), -/* 167 */ -/***/ (function(module, exports, __webpack_require__) { - -//! moment.js locale configuration - -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; - - - var zhHk = moment.defineLocale('zh-hk', { - months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), - monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), - weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), - weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'), - weekdaysMin : '日_一_二_三_四_五_六'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY/MM/DD', - LL : 'YYYY年M月D日', - LLL : 'YYYY年M月D日 HH:mm', - LLLL : 'YYYY年M月D日dddd HH:mm', - l : 'YYYY/M/D', - ll : 'YYYY年M月D日', - lll : 'YYYY年M月D日 HH:mm', - llll : 'YYYY年M月D日dddd HH:mm' - }, - meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') { - return hour; - } else if (meridiem === '中午') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === '下午' || meridiem === '晚上') { - return hour + 12; - } - }, - meridiem : function (hour, minute, isLower) { - var hm = hour * 100 + minute; - if (hm < 600) { - return '凌晨'; - } else if (hm < 900) { - return '早上'; - } else if (hm < 1130) { - return '上午'; - } else if (hm < 1230) { - return '中午'; - } else if (hm < 1800) { - return '下午'; - } else { - return '晚上'; - } - }, - calendar : { - sameDay : '[今天]LT', - nextDay : '[明天]LT', - nextWeek : '[下]ddddLT', - lastDay : '[昨天]LT', - lastWeek : '[上]ddddLT', - sameElse : 'L' - }, - dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/, - ordinal : function (number, period) { - switch (period) { - case 'd' : - case 'D' : - case 'DDD' : - return number + '日'; - case 'M' : - return number + '月'; - case 'w' : - case 'W' : - return number + '週'; - default : - return number; - } - }, - relativeTime : { - future : '%s內', - past : '%s前', - s : '幾秒', - ss : '%d 秒', - m : '1 分鐘', - mm : '%d 分鐘', - h : '1 小時', - hh : '%d 小時', - d : '1 天', - dd : '%d 天', - M : '1 個月', - MM : '%d 個月', - y : '1 年', - yy : '%d 年' - } - }); +/* 199 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - return zhHk; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return combineLatest; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CombineLatestOperator", function() { return CombineLatestOperator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CombineLatestSubscriber", function() { return CombineLatestSubscriber; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(176); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(149); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(201); +/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(177); +/** PURE_IMPORTS_START tslib,_util_isScheduler,_util_isArray,_OuterSubscriber,_util_subscribeToResult,_fromArray PURE_IMPORTS_END */ -}))); -/***/ }), -/* 168 */ -/***/ (function(module, exports, __webpack_require__) { -//! moment.js locale configuration -;(function (global, factory) { - true ? factory(__webpack_require__(40)) : - undefined -}(this, (function (moment) { 'use strict'; +var NONE = {}; +function combineLatest() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + var resultSelector = null; + var scheduler = null; + if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_1__["isScheduler"])(observables[observables.length - 1])) { + scheduler = observables.pop(); + } + if (typeof observables[observables.length - 1] === 'function') { + resultSelector = observables.pop(); + } + if (observables.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_2__["isArray"])(observables[0])) { + observables = observables[0]; + } + return Object(_fromArray__WEBPACK_IMPORTED_MODULE_5__["fromArray"])(observables, scheduler).lift(new CombineLatestOperator(resultSelector)); +} +var CombineLatestOperator = /*@__PURE__*/ (function () { + function CombineLatestOperator(resultSelector) { + this.resultSelector = resultSelector; + } + CombineLatestOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new CombineLatestSubscriber(subscriber, this.resultSelector)); + }; + return CombineLatestOperator; +}()); - var zhTw = moment.defineLocale('zh-tw', { - months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), - monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), - weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), - weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'), - weekdaysMin : '日_一_二_三_四_五_六'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY/MM/DD', - LL : 'YYYY年M月D日', - LLL : 'YYYY年M月D日 HH:mm', - LLLL : 'YYYY年M月D日dddd HH:mm', - l : 'YYYY/M/D', - ll : 'YYYY年M月D日', - lll : 'YYYY年M月D日 HH:mm', - llll : 'YYYY年M月D日dddd HH:mm' - }, - meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') { - return hour; - } else if (meridiem === '中午') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === '下午' || meridiem === '晚上') { - return hour + 12; +var CombineLatestSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CombineLatestSubscriber, _super); + function CombineLatestSubscriber(destination, resultSelector) { + var _this = _super.call(this, destination) || this; + _this.resultSelector = resultSelector; + _this.active = 0; + _this.values = []; + _this.observables = []; + return _this; + } + CombineLatestSubscriber.prototype._next = function (observable) { + this.values.push(NONE); + this.observables.push(observable); + }; + CombineLatestSubscriber.prototype._complete = function () { + var observables = this.observables; + var len = observables.length; + if (len === 0) { + this.destination.complete(); + } + else { + this.active = len; + this.toRespond = len; + for (var i = 0; i < len; i++) { + var observable = observables[i]; + this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, observable, observable, i)); } - }, - meridiem : function (hour, minute, isLower) { - var hm = hour * 100 + minute; - if (hm < 600) { - return '凌晨'; - } else if (hm < 900) { - return '早上'; - } else if (hm < 1130) { - return '上午'; - } else if (hm < 1230) { - return '中午'; - } else if (hm < 1800) { - return '下午'; - } else { - return '晚上'; + } + }; + CombineLatestSubscriber.prototype.notifyComplete = function (unused) { + if ((this.active -= 1) === 0) { + this.destination.complete(); + } + }; + CombineLatestSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + var values = this.values; + var oldVal = values[outerIndex]; + var toRespond = !this.toRespond + ? 0 + : oldVal === NONE ? --this.toRespond : this.toRespond; + values[outerIndex] = innerValue; + if (toRespond === 0) { + if (this.resultSelector) { + this._tryResultSelector(values); } - }, - calendar : { - sameDay : '[今天] LT', - nextDay : '[明天] LT', - nextWeek : '[下]dddd LT', - lastDay : '[昨天] LT', - lastWeek : '[上]dddd LT', - sameElse : 'L' - }, - dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/, - ordinal : function (number, period) { - switch (period) { - case 'd' : - case 'D' : - case 'DDD' : - return number + '日'; - case 'M' : - return number + '月'; - case 'w' : - case 'W' : - return number + '週'; - default : - return number; + else { + this.destination.next(values.slice()); } - }, - relativeTime : { - future : '%s內', - past : '%s前', - s : '幾秒', - ss : '%d 秒', - m : '1 分鐘', - mm : '%d 分鐘', - h : '1 小時', - hh : '%d 小時', - d : '1 天', - dd : '%d 天', - M : '1 個月', - MM : '%d 個月', - y : '1 年', - yy : '%d 年' } - }); - - return zhTw; + }; + CombineLatestSubscriber.prototype._tryResultSelector = function (values) { + var result; + try { + result = this.resultSelector.apply(this, values); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.next(result); + }; + return CombineLatestSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); -}))); +//# sourceMappingURL=combineLatest.js.map /***/ }), -/* 169 */ +/* 200 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var _internal_Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Observable", function() { return _internal_Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]; }); - -/* harmony import */ var _internal_observable_ConnectableObservable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(186); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ConnectableObservable", function() { return _internal_observable_ConnectableObservable__WEBPACK_IMPORTED_MODULE_1__["ConnectableObservable"]; }); - -/* harmony import */ var _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(191); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GroupedObservable", function() { return _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_2__["GroupedObservable"]; }); - -/* harmony import */ var _internal_symbol_observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(183); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "observable", function() { return _internal_symbol_observable__WEBPACK_IMPORTED_MODULE_3__["observable"]; }); - -/* harmony import */ var _internal_Subject__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(187); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Subject", function() { return _internal_Subject__WEBPACK_IMPORTED_MODULE_4__["Subject"]; }); - -/* harmony import */ var _internal_BehaviorSubject__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(192); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BehaviorSubject", function() { return _internal_BehaviorSubject__WEBPACK_IMPORTED_MODULE_5__["BehaviorSubject"]; }); - -/* harmony import */ var _internal_ReplaySubject__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(193); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ReplaySubject", function() { return _internal_ReplaySubject__WEBPACK_IMPORTED_MODULE_6__["ReplaySubject"]; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OuterSubscriber", function() { return OuterSubscriber; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -/* harmony import */ var _internal_AsyncSubject__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(210); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AsyncSubject", function() { return _internal_AsyncSubject__WEBPACK_IMPORTED_MODULE_7__["AsyncSubject"]; }); -/* harmony import */ var _internal_scheduler_asap__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(211); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "asapScheduler", function() { return _internal_scheduler_asap__WEBPACK_IMPORTED_MODULE_8__["asap"]; }); +var OuterSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](OuterSubscriber, _super); + function OuterSubscriber() { + return _super !== null && _super.apply(this, arguments) || this; + } + OuterSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.destination.next(innerValue); + }; + OuterSubscriber.prototype.notifyError = function (error, innerSub) { + this.destination.error(error); + }; + OuterSubscriber.prototype.notifyComplete = function (innerSub) { + this.destination.complete(); + }; + return OuterSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -/* harmony import */ var _internal_scheduler_async__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(215); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "asyncScheduler", function() { return _internal_scheduler_async__WEBPACK_IMPORTED_MODULE_9__["async"]; }); +//# sourceMappingURL=OuterSubscriber.js.map -/* harmony import */ var _internal_scheduler_queue__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(194); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "queueScheduler", function() { return _internal_scheduler_queue__WEBPACK_IMPORTED_MODULE_10__["queue"]; }); -/* harmony import */ var _internal_scheduler_animationFrame__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(216); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "animationFrameScheduler", function() { return _internal_scheduler_animationFrame__WEBPACK_IMPORTED_MODULE_11__["animationFrame"]; }); +/***/ }), +/* 201 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -/* harmony import */ var _internal_scheduler_VirtualTimeScheduler__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(219); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VirtualTimeScheduler", function() { return _internal_scheduler_VirtualTimeScheduler__WEBPACK_IMPORTED_MODULE_12__["VirtualTimeScheduler"]; }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeToResult", function() { return subscribeToResult; }); +/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(202); +/* harmony import */ var _subscribeTo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(203); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(141); +/** PURE_IMPORTS_START _InnerSubscriber,_subscribeTo,_Observable PURE_IMPORTS_END */ -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VirtualAction", function() { return _internal_scheduler_VirtualTimeScheduler__WEBPACK_IMPORTED_MODULE_12__["VirtualAction"]; }); -/* harmony import */ var _internal_Scheduler__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(200); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Scheduler", function() { return _internal_Scheduler__WEBPACK_IMPORTED_MODULE_13__["Scheduler"]; }); -/* harmony import */ var _internal_Subscription__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(177); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Subscription", function() { return _internal_Subscription__WEBPACK_IMPORTED_MODULE_14__["Subscription"]; }); +function subscribeToResult(outerSubscriber, result, outerValue, outerIndex, destination) { + if (destination === void 0) { + destination = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_0__["InnerSubscriber"](outerSubscriber, outerValue, outerIndex); + } + if (destination.closed) { + return undefined; + } + if (result instanceof _Observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]) { + return result.subscribe(destination); + } + return Object(_subscribeTo__WEBPACK_IMPORTED_MODULE_1__["subscribeTo"])(result)(destination); +} +//# sourceMappingURL=subscribeToResult.js.map -/* harmony import */ var _internal_Subscriber__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(172); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Subscriber", function() { return _internal_Subscriber__WEBPACK_IMPORTED_MODULE_15__["Subscriber"]; }); -/* harmony import */ var _internal_Notification__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(202); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Notification", function() { return _internal_Notification__WEBPACK_IMPORTED_MODULE_16__["Notification"]; }); +/***/ }), +/* 202 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NotificationKind", function() { return _internal_Notification__WEBPACK_IMPORTED_MODULE_16__["NotificationKind"]; }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InnerSubscriber", function() { return InnerSubscriber; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -/* harmony import */ var _internal_util_pipe__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(184); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pipe", function() { return _internal_util_pipe__WEBPACK_IMPORTED_MODULE_17__["pipe"]; }); -/* harmony import */ var _internal_util_noop__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(185); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "noop", function() { return _internal_util_noop__WEBPACK_IMPORTED_MODULE_18__["noop"]; }); +var InnerSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](InnerSubscriber, _super); + function InnerSubscriber(parent, outerValue, outerIndex) { + var _this = _super.call(this) || this; + _this.parent = parent; + _this.outerValue = outerValue; + _this.outerIndex = outerIndex; + _this.index = 0; + return _this; + } + InnerSubscriber.prototype._next = function (value) { + this.parent.notifyNext(this.outerValue, value, this.outerIndex, this.index++, this); + }; + InnerSubscriber.prototype._error = function (error) { + this.parent.notifyError(error, this); + this.unsubscribe(); + }; + InnerSubscriber.prototype._complete = function () { + this.parent.notifyComplete(this); + this.unsubscribe(); + }; + return InnerSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -/* harmony import */ var _internal_util_identity__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(220); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "identity", function() { return _internal_util_identity__WEBPACK_IMPORTED_MODULE_19__["identity"]; }); +//# sourceMappingURL=InnerSubscriber.js.map -/* harmony import */ var _internal_util_isObservable__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(221); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "isObservable", function() { return _internal_util_isObservable__WEBPACK_IMPORTED_MODULE_20__["isObservable"]; }); -/* harmony import */ var _internal_util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(222); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArgumentOutOfRangeError", function() { return _internal_util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_21__["ArgumentOutOfRangeError"]; }); +/***/ }), +/* 203 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -/* harmony import */ var _internal_util_EmptyError__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(223); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EmptyError", function() { return _internal_util_EmptyError__WEBPACK_IMPORTED_MODULE_22__["EmptyError"]; }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeTo", function() { return subscribeTo; }); +/* harmony import */ var _subscribeToArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(178); +/* harmony import */ var _subscribeToPromise__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(204); +/* harmony import */ var _subscribeToIterable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(205); +/* harmony import */ var _subscribeToObservable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(207); +/* harmony import */ var _isArrayLike__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(208); +/* harmony import */ var _isPromise__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(209); +/* harmony import */ var _isObject__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(150); +/* harmony import */ var _symbol_iterator__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(206); +/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(154); +/** PURE_IMPORTS_START _subscribeToArray,_subscribeToPromise,_subscribeToIterable,_subscribeToObservable,_isArrayLike,_isPromise,_isObject,_symbol_iterator,_symbol_observable PURE_IMPORTS_END */ -/* harmony import */ var _internal_util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(188); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ObjectUnsubscribedError", function() { return _internal_util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_23__["ObjectUnsubscribedError"]; }); -/* harmony import */ var _internal_util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(180); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "UnsubscriptionError", function() { return _internal_util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_24__["UnsubscriptionError"]; }); -/* harmony import */ var _internal_util_TimeoutError__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(224); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TimeoutError", function() { return _internal_util_TimeoutError__WEBPACK_IMPORTED_MODULE_25__["TimeoutError"]; }); -/* harmony import */ var _internal_observable_bindCallback__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(225); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bindCallback", function() { return _internal_observable_bindCallback__WEBPACK_IMPORTED_MODULE_26__["bindCallback"]; }); -/* harmony import */ var _internal_observable_bindNodeCallback__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(227); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bindNodeCallback", function() { return _internal_observable_bindNodeCallback__WEBPACK_IMPORTED_MODULE_27__["bindNodeCallback"]; }); -/* harmony import */ var _internal_observable_combineLatest__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(228); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return _internal_observable_combineLatest__WEBPACK_IMPORTED_MODULE_28__["combineLatest"]; }); -/* harmony import */ var _internal_observable_concat__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(239); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return _internal_observable_concat__WEBPACK_IMPORTED_MODULE_29__["concat"]; }); -/* harmony import */ var _internal_observable_defer__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(250); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "defer", function() { return _internal_observable_defer__WEBPACK_IMPORTED_MODULE_30__["defer"]; }); -/* harmony import */ var _internal_observable_empty__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(203); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "empty", function() { return _internal_observable_empty__WEBPACK_IMPORTED_MODULE_31__["empty"]; }); - -/* harmony import */ var _internal_observable_forkJoin__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(251); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "forkJoin", function() { return _internal_observable_forkJoin__WEBPACK_IMPORTED_MODULE_32__["forkJoin"]; }); - -/* harmony import */ var _internal_observable_from__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(243); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "from", function() { return _internal_observable_from__WEBPACK_IMPORTED_MODULE_33__["from"]; }); - -/* harmony import */ var _internal_observable_fromEvent__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(252); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "fromEvent", function() { return _internal_observable_fromEvent__WEBPACK_IMPORTED_MODULE_34__["fromEvent"]; }); - -/* harmony import */ var _internal_observable_fromEventPattern__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(253); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "fromEventPattern", function() { return _internal_observable_fromEventPattern__WEBPACK_IMPORTED_MODULE_35__["fromEventPattern"]; }); - -/* harmony import */ var _internal_observable_generate__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(254); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "generate", function() { return _internal_observable_generate__WEBPACK_IMPORTED_MODULE_36__["generate"]; }); - -/* harmony import */ var _internal_observable_iif__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(255); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "iif", function() { return _internal_observable_iif__WEBPACK_IMPORTED_MODULE_37__["iif"]; }); - -/* harmony import */ var _internal_observable_interval__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(256); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "interval", function() { return _internal_observable_interval__WEBPACK_IMPORTED_MODULE_38__["interval"]; }); - -/* harmony import */ var _internal_observable_merge__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(258); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return _internal_observable_merge__WEBPACK_IMPORTED_MODULE_39__["merge"]; }); - -/* harmony import */ var _internal_observable_never__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(259); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "never", function() { return _internal_observable_never__WEBPACK_IMPORTED_MODULE_40__["never"]; }); - -/* harmony import */ var _internal_observable_of__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(204); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "of", function() { return _internal_observable_of__WEBPACK_IMPORTED_MODULE_41__["of"]; }); - -/* harmony import */ var _internal_observable_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(260); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return _internal_observable_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_42__["onErrorResumeNext"]; }); - -/* harmony import */ var _internal_observable_pairs__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(261); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pairs", function() { return _internal_observable_pairs__WEBPACK_IMPORTED_MODULE_43__["pairs"]; }); - -/* harmony import */ var _internal_observable_partition__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(262); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return _internal_observable_partition__WEBPACK_IMPORTED_MODULE_44__["partition"]; }); +var subscribeTo = function (result) { + if (!!result && typeof result[_symbol_observable__WEBPACK_IMPORTED_MODULE_8__["observable"]] === 'function') { + return Object(_subscribeToObservable__WEBPACK_IMPORTED_MODULE_3__["subscribeToObservable"])(result); + } + else if (Object(_isArrayLike__WEBPACK_IMPORTED_MODULE_4__["isArrayLike"])(result)) { + return Object(_subscribeToArray__WEBPACK_IMPORTED_MODULE_0__["subscribeToArray"])(result); + } + else if (Object(_isPromise__WEBPACK_IMPORTED_MODULE_5__["isPromise"])(result)) { + return Object(_subscribeToPromise__WEBPACK_IMPORTED_MODULE_1__["subscribeToPromise"])(result); + } + else if (!!result && typeof result[_symbol_iterator__WEBPACK_IMPORTED_MODULE_7__["iterator"]] === 'function') { + return Object(_subscribeToIterable__WEBPACK_IMPORTED_MODULE_2__["subscribeToIterable"])(result); + } + else { + var value = Object(_isObject__WEBPACK_IMPORTED_MODULE_6__["isObject"])(result) ? 'an invalid object' : "'" + result + "'"; + var msg = "You provided " + value + " where a stream was expected." + + ' You can provide an Observable, Promise, Array, or Iterable.'; + throw new TypeError(msg); + } +}; +//# sourceMappingURL=subscribeTo.js.map -/* harmony import */ var _internal_observable_race__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(265); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "race", function() { return _internal_observable_race__WEBPACK_IMPORTED_MODULE_45__["race"]; }); -/* harmony import */ var _internal_observable_range__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(266); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "range", function() { return _internal_observable_range__WEBPACK_IMPORTED_MODULE_46__["range"]; }); +/***/ }), +/* 204 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -/* harmony import */ var _internal_observable_throwError__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(209); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throwError", function() { return _internal_observable_throwError__WEBPACK_IMPORTED_MODULE_47__["throwError"]; }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeToPromise", function() { return subscribeToPromise; }); +/* harmony import */ var _hostReportError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(147); +/** PURE_IMPORTS_START _hostReportError PURE_IMPORTS_END */ -/* harmony import */ var _internal_observable_timer__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(267); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timer", function() { return _internal_observable_timer__WEBPACK_IMPORTED_MODULE_48__["timer"]; }); +var subscribeToPromise = function (promise) { + return function (subscriber) { + promise.then(function (value) { + if (!subscriber.closed) { + subscriber.next(value); + subscriber.complete(); + } + }, function (err) { return subscriber.error(err); }) + .then(null, _hostReportError__WEBPACK_IMPORTED_MODULE_0__["hostReportError"]); + return subscriber; + }; +}; +//# sourceMappingURL=subscribeToPromise.js.map -/* harmony import */ var _internal_observable_using__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(268); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "using", function() { return _internal_observable_using__WEBPACK_IMPORTED_MODULE_49__["using"]; }); -/* harmony import */ var _internal_observable_zip__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(269); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return _internal_observable_zip__WEBPACK_IMPORTED_MODULE_50__["zip"]; }); +/***/ }), +/* 205 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -/* harmony import */ var _internal_scheduled_scheduled__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(244); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "scheduled", function() { return _internal_scheduled_scheduled__WEBPACK_IMPORTED_MODULE_51__["scheduled"]; }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeToIterable", function() { return subscribeToIterable; }); +/* harmony import */ var _symbol_iterator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(206); +/** PURE_IMPORTS_START _symbol_iterator PURE_IMPORTS_END */ -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EMPTY", function() { return _internal_observable_empty__WEBPACK_IMPORTED_MODULE_31__["EMPTY"]; }); +var subscribeToIterable = function (iterable) { + return function (subscriber) { + var iterator = iterable[_symbol_iterator__WEBPACK_IMPORTED_MODULE_0__["iterator"]](); + do { + var item = iterator.next(); + if (item.done) { + subscriber.complete(); + break; + } + subscriber.next(item.value); + if (subscriber.closed) { + break; + } + } while (true); + if (typeof iterator.return === 'function') { + subscriber.add(function () { + if (iterator.return) { + iterator.return(); + } + }); + } + return subscriber; + }; +}; +//# sourceMappingURL=subscribeToIterable.js.map -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NEVER", function() { return _internal_observable_never__WEBPACK_IMPORTED_MODULE_40__["NEVER"]; }); -/* harmony import */ var _internal_config__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(175); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "config", function() { return _internal_config__WEBPACK_IMPORTED_MODULE_52__["config"]; }); +/***/ }), +/* 206 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getSymbolIterator", function() { return getSymbolIterator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "iterator", function() { return iterator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "$$iterator", function() { return $$iterator; }); /** PURE_IMPORTS_START PURE_IMPORTS_END */ +function getSymbolIterator() { + if (typeof Symbol !== 'function' || !Symbol.iterator) { + return '@@iterator'; + } + return Symbol.iterator; +} +var iterator = /*@__PURE__*/ getSymbolIterator(); +var $$iterator = iterator; +//# sourceMappingURL=iterator.js.map +/***/ }), +/* 207 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeToObservable", function() { return subscribeToObservable; }); +/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(154); +/** PURE_IMPORTS_START _symbol_observable PURE_IMPORTS_END */ +var subscribeToObservable = function (obj) { + return function (subscriber) { + var obs = obj[_symbol_observable__WEBPACK_IMPORTED_MODULE_0__["observable"]](); + if (typeof obs.subscribe !== 'function') { + throw new TypeError('Provided object does not correctly implement Symbol.observable'); + } + else { + return obs.subscribe(subscriber); + } + }; +}; +//# sourceMappingURL=subscribeToObservable.js.map +/***/ }), +/* 208 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isArrayLike", function() { return isArrayLike; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var isArrayLike = (function (x) { return x && typeof x.length === 'number' && typeof x !== 'function'; }); +//# sourceMappingURL=isArrayLike.js.map +/***/ }), +/* 209 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isPromise", function() { return isPromise; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function isPromise(value) { + return !!value && typeof value.subscribe !== 'function' && typeof value.then === 'function'; +} +//# sourceMappingURL=isPromise.js.map +/***/ }), +/* 210 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return concat; }); +/* harmony import */ var _of__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(175); +/* harmony import */ var _operators_concatAll__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(211); +/** PURE_IMPORTS_START _of,_operators_concatAll PURE_IMPORTS_END */ +function concat() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + return Object(_operators_concatAll__WEBPACK_IMPORTED_MODULE_1__["concatAll"])()(_of__WEBPACK_IMPORTED_MODULE_0__["of"].apply(void 0, observables)); +} +//# sourceMappingURL=concat.js.map +/***/ }), +/* 211 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concatAll", function() { return concatAll; }); +/* harmony import */ var _mergeAll__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(212); +/** PURE_IMPORTS_START _mergeAll PURE_IMPORTS_END */ +function concatAll() { + return Object(_mergeAll__WEBPACK_IMPORTED_MODULE_0__["mergeAll"])(1); +} +//# sourceMappingURL=concatAll.js.map +/***/ }), +/* 212 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeAll", function() { return mergeAll; }); +/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(213); +/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(191); +/** PURE_IMPORTS_START _mergeMap,_util_identity PURE_IMPORTS_END */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//# sourceMappingURL=index.js.map +function mergeAll(concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; + } + return Object(_mergeMap__WEBPACK_IMPORTED_MODULE_0__["mergeMap"])(_util_identity__WEBPACK_IMPORTED_MODULE_1__["identity"], concurrent); +} +//# sourceMappingURL=mergeAll.js.map /***/ }), -/* 170 */ +/* 213 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Observable", function() { return Observable; }); -/* harmony import */ var _util_canReportError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(171); -/* harmony import */ var _util_toSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(182); -/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(183); -/* harmony import */ var _util_pipe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(184); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(175); -/** PURE_IMPORTS_START _util_canReportError,_util_toSubscriber,_symbol_observable,_util_pipe,_config PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeMap", function() { return mergeMap; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MergeMapOperator", function() { return MergeMapOperator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MergeMapSubscriber", function() { return MergeMapSubscriber; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(201); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(200); +/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(202); +/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(197); +/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(214); +/** PURE_IMPORTS_START tslib,_util_subscribeToResult,_OuterSubscriber,_InnerSubscriber,_map,_observable_from PURE_IMPORTS_END */ -var Observable = /*@__PURE__*/ (function () { - function Observable(subscribe) { - this._isScalar = false; - if (subscribe) { - this._subscribe = subscribe; + +function mergeMap(project, resultSelector, concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; + } + if (typeof resultSelector === 'function') { + return function (source) { return source.pipe(mergeMap(function (a, i) { return Object(_observable_from__WEBPACK_IMPORTED_MODULE_5__["from"])(project(a, i)).pipe(Object(_map__WEBPACK_IMPORTED_MODULE_4__["map"])(function (b, ii) { return resultSelector(a, b, i, ii); })); }, concurrent)); }; + } + else if (typeof resultSelector === 'number') { + concurrent = resultSelector; + } + return function (source) { return source.lift(new MergeMapOperator(project, concurrent)); }; +} +var MergeMapOperator = /*@__PURE__*/ (function () { + function MergeMapOperator(project, concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; } + this.project = project; + this.concurrent = concurrent; } - Observable.prototype.lift = function (operator) { - var observable = new Observable(); - observable.source = this; - observable.operator = operator; - return observable; + MergeMapOperator.prototype.call = function (observer, source) { + return source.subscribe(new MergeMapSubscriber(observer, this.project, this.concurrent)); }; - Observable.prototype.subscribe = function (observerOrNext, error, complete) { - var operator = this.operator; - var sink = Object(_util_toSubscriber__WEBPACK_IMPORTED_MODULE_1__["toSubscriber"])(observerOrNext, error, complete); - if (operator) { - sink.add(operator.call(sink, this.source)); + return MergeMapOperator; +}()); + +var MergeMapSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MergeMapSubscriber, _super); + function MergeMapSubscriber(destination, project, concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; } - else { - sink.add(this.source || (_config__WEBPACK_IMPORTED_MODULE_4__["config"].useDeprecatedSynchronousErrorHandling && !sink.syncErrorThrowable) ? - this._subscribe(sink) : - this._trySubscribe(sink)); + var _this = _super.call(this, destination) || this; + _this.project = project; + _this.concurrent = concurrent; + _this.hasCompleted = false; + _this.buffer = []; + _this.active = 0; + _this.index = 0; + return _this; + } + MergeMapSubscriber.prototype._next = function (value) { + if (this.active < this.concurrent) { + this._tryNext(value); } - if (_config__WEBPACK_IMPORTED_MODULE_4__["config"].useDeprecatedSynchronousErrorHandling) { - if (sink.syncErrorThrowable) { - sink.syncErrorThrowable = false; - if (sink.syncErrorThrown) { - throw sink.syncErrorValue; - } - } + else { + this.buffer.push(value); } - return sink; }; - Observable.prototype._trySubscribe = function (sink) { + MergeMapSubscriber.prototype._tryNext = function (value) { + var result; + var index = this.index++; try { - return this._subscribe(sink); + result = this.project(value, index); } catch (err) { - if (_config__WEBPACK_IMPORTED_MODULE_4__["config"].useDeprecatedSynchronousErrorHandling) { - sink.syncErrorThrown = true; - sink.syncErrorValue = err; - } - if (Object(_util_canReportError__WEBPACK_IMPORTED_MODULE_0__["canReportError"])(sink)) { - sink.error(err); - } - else { - console.warn(err); - } + this.destination.error(err); + return; } + this.active++; + this._innerSub(result, value, index); }; - Observable.prototype.forEach = function (next, promiseCtor) { - var _this = this; - promiseCtor = getPromiseCtor(promiseCtor); - return new promiseCtor(function (resolve, reject) { - var subscription; - subscription = _this.subscribe(function (value) { - try { - next(value); - } - catch (err) { - reject(err); - if (subscription) { - subscription.unsubscribe(); - } - } - }, reject, resolve); - }); + MergeMapSubscriber.prototype._innerSub = function (ish, value, index) { + var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_3__["InnerSubscriber"](this, undefined, undefined); + var destination = this.destination; + destination.add(innerSubscriber); + Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_1__["subscribeToResult"])(this, ish, value, index, innerSubscriber); }; - Observable.prototype._subscribe = function (subscriber) { - var source = this.source; - return source && source.subscribe(subscriber); + MergeMapSubscriber.prototype._complete = function () { + this.hasCompleted = true; + if (this.active === 0 && this.buffer.length === 0) { + this.destination.complete(); + } + this.unsubscribe(); }; - Observable.prototype[_symbol_observable__WEBPACK_IMPORTED_MODULE_2__["observable"]] = function () { - return this; + MergeMapSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.destination.next(innerValue); }; - Observable.prototype.pipe = function () { - var operations = []; - for (var _i = 0; _i < arguments.length; _i++) { - operations[_i] = arguments[_i]; + MergeMapSubscriber.prototype.notifyComplete = function (innerSub) { + var buffer = this.buffer; + this.remove(innerSub); + this.active--; + if (buffer.length > 0) { + this._next(buffer.shift()); } - if (operations.length === 0) { - return this; + else if (this.active === 0 && this.hasCompleted) { + this.destination.complete(); } - return Object(_util_pipe__WEBPACK_IMPORTED_MODULE_3__["pipeFromArray"])(operations)(this); - }; - Observable.prototype.toPromise = function (promiseCtor) { - var _this = this; - promiseCtor = getPromiseCtor(promiseCtor); - return new promiseCtor(function (resolve, reject) { - var value; - _this.subscribe(function (x) { return value = x; }, function (err) { return reject(err); }, function () { return resolve(value); }); - }); - }; - Observable.create = function (subscribe) { - return new Observable(subscribe); }; - return Observable; -}()); + return MergeMapSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); -function getPromiseCtor(promiseCtor) { - if (!promiseCtor) { - promiseCtor = _config__WEBPACK_IMPORTED_MODULE_4__["config"].Promise || Promise; +//# sourceMappingURL=mergeMap.js.map + + +/***/ }), +/* 214 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "from", function() { return from; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _util_subscribeTo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(203); +/* harmony import */ var _scheduled_scheduled__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(215); +/** PURE_IMPORTS_START _Observable,_util_subscribeTo,_scheduled_scheduled PURE_IMPORTS_END */ + + + +function from(input, scheduler) { + if (!scheduler) { + if (input instanceof _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]) { + return input; + } + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](Object(_util_subscribeTo__WEBPACK_IMPORTED_MODULE_1__["subscribeTo"])(input)); } - if (!promiseCtor) { - throw new Error('no Promise impl found'); + else { + return Object(_scheduled_scheduled__WEBPACK_IMPORTED_MODULE_2__["scheduled"])(input, scheduler); } - return promiseCtor; } -//# sourceMappingURL=Observable.js.map +//# sourceMappingURL=from.js.map /***/ }), -/* 171 */ +/* 215 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "canReportError", function() { return canReportError; }); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(172); -/** PURE_IMPORTS_START _Subscriber PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scheduled", function() { return scheduled; }); +/* harmony import */ var _scheduleObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(216); +/* harmony import */ var _schedulePromise__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(217); +/* harmony import */ var _scheduleArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(179); +/* harmony import */ var _scheduleIterable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(218); +/* harmony import */ var _util_isInteropObservable__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(219); +/* harmony import */ var _util_isPromise__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(209); +/* harmony import */ var _util_isArrayLike__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(208); +/* harmony import */ var _util_isIterable__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(220); +/** PURE_IMPORTS_START _scheduleObservable,_schedulePromise,_scheduleArray,_scheduleIterable,_util_isInteropObservable,_util_isPromise,_util_isArrayLike,_util_isIterable PURE_IMPORTS_END */ -function canReportError(observer) { - while (observer) { - var _a = observer, closed_1 = _a.closed, destination = _a.destination, isStopped = _a.isStopped; - if (closed_1 || isStopped) { - return false; + + + + + + + +function scheduled(input, scheduler) { + if (input != null) { + if (Object(_util_isInteropObservable__WEBPACK_IMPORTED_MODULE_4__["isInteropObservable"])(input)) { + return Object(_scheduleObservable__WEBPACK_IMPORTED_MODULE_0__["scheduleObservable"])(input, scheduler); } - else if (destination && destination instanceof _Subscriber__WEBPACK_IMPORTED_MODULE_0__["Subscriber"]) { - observer = destination; + else if (Object(_util_isPromise__WEBPACK_IMPORTED_MODULE_5__["isPromise"])(input)) { + return Object(_schedulePromise__WEBPACK_IMPORTED_MODULE_1__["schedulePromise"])(input, scheduler); } - else { - observer = null; + else if (Object(_util_isArrayLike__WEBPACK_IMPORTED_MODULE_6__["isArrayLike"])(input)) { + return Object(_scheduleArray__WEBPACK_IMPORTED_MODULE_2__["scheduleArray"])(input, scheduler); + } + else if (Object(_util_isIterable__WEBPACK_IMPORTED_MODULE_7__["isIterable"])(input) || typeof input === 'string') { + return Object(_scheduleIterable__WEBPACK_IMPORTED_MODULE_3__["scheduleIterable"])(input, scheduler); } } - return true; + throw new TypeError((input !== null && typeof input || input) + ' is not observable'); } -//# sourceMappingURL=canReportError.js.map +//# sourceMappingURL=scheduled.js.map /***/ }), -/* 172 */ +/* 216 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Subscriber", function() { return Subscriber; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SafeSubscriber", function() { return SafeSubscriber; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(173); -/* harmony import */ var _Observer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(174); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(177); -/* harmony import */ var _internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(181); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(175); -/* harmony import */ var _util_hostReportError__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(176); -/** PURE_IMPORTS_START tslib,_util_isFunction,_Observer,_Subscription,_internal_symbol_rxSubscriber,_config,_util_hostReportError PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scheduleObservable", function() { return scheduleObservable; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(148); +/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(154); +/** PURE_IMPORTS_START _Observable,_Subscription,_symbol_observable PURE_IMPORTS_END */ +function scheduleObservable(input, scheduler) { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + var sub = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); + sub.add(scheduler.schedule(function () { + var observable = input[_symbol_observable__WEBPACK_IMPORTED_MODULE_2__["observable"]](); + sub.add(observable.subscribe({ + next: function (value) { sub.add(scheduler.schedule(function () { return subscriber.next(value); })); }, + error: function (err) { sub.add(scheduler.schedule(function () { return subscriber.error(err); })); }, + complete: function () { sub.add(scheduler.schedule(function () { return subscriber.complete(); })); }, + })); + })); + return sub; + }); +} +//# sourceMappingURL=scheduleObservable.js.map +/***/ }), +/* 217 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "schedulePromise", function() { return schedulePromise; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(148); +/** PURE_IMPORTS_START _Observable,_Subscription PURE_IMPORTS_END */ -var Subscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](Subscriber, _super); - function Subscriber(destinationOrNext, error, complete) { - var _this = _super.call(this) || this; - _this.syncErrorValue = null; - _this.syncErrorThrown = false; - _this.syncErrorThrowable = false; - _this.isStopped = false; - switch (arguments.length) { - case 0: - _this.destination = _Observer__WEBPACK_IMPORTED_MODULE_2__["empty"]; - break; - case 1: - if (!destinationOrNext) { - _this.destination = _Observer__WEBPACK_IMPORTED_MODULE_2__["empty"]; - break; - } - if (typeof destinationOrNext === 'object') { - if (destinationOrNext instanceof Subscriber) { - _this.syncErrorThrowable = destinationOrNext.syncErrorThrowable; - _this.destination = destinationOrNext; - destinationOrNext.add(_this); - } - else { - _this.syncErrorThrowable = true; - _this.destination = new SafeSubscriber(_this, destinationOrNext); - } - break; - } - default: - _this.syncErrorThrowable = true; - _this.destination = new SafeSubscriber(_this, destinationOrNext, error, complete); - break; - } - return _this; - } - Subscriber.prototype[_internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_4__["rxSubscriber"]] = function () { return this; }; - Subscriber.create = function (next, error, complete) { - var subscriber = new Subscriber(next, error, complete); - subscriber.syncErrorThrowable = false; - return subscriber; - }; - Subscriber.prototype.next = function (value) { - if (!this.isStopped) { - this._next(value); - } - }; - Subscriber.prototype.error = function (err) { - if (!this.isStopped) { - this.isStopped = true; - this._error(err); - } - }; - Subscriber.prototype.complete = function () { - if (!this.isStopped) { - this.isStopped = true; - this._complete(); - } - }; - Subscriber.prototype.unsubscribe = function () { - if (this.closed) { - return; - } - this.isStopped = true; - _super.prototype.unsubscribe.call(this); - }; - Subscriber.prototype._next = function (value) { - this.destination.next(value); - }; - Subscriber.prototype._error = function (err) { - this.destination.error(err); - this.unsubscribe(); - }; - Subscriber.prototype._complete = function () { - this.destination.complete(); - this.unsubscribe(); - }; - Subscriber.prototype._unsubscribeAndRecycle = function () { - var _parentOrParents = this._parentOrParents; - this._parentOrParents = null; - this.unsubscribe(); - this.closed = false; - this.isStopped = false; - this._parentOrParents = _parentOrParents; - return this; - }; - return Subscriber; -}(_Subscription__WEBPACK_IMPORTED_MODULE_3__["Subscription"])); -var SafeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SafeSubscriber, _super); - function SafeSubscriber(_parentSubscriber, observerOrNext, error, complete) { - var _this = _super.call(this) || this; - _this._parentSubscriber = _parentSubscriber; - var next; - var context = _this; - if (Object(_util_isFunction__WEBPACK_IMPORTED_MODULE_1__["isFunction"])(observerOrNext)) { - next = observerOrNext; - } - else if (observerOrNext) { - next = observerOrNext.next; - error = observerOrNext.error; - complete = observerOrNext.complete; - if (observerOrNext !== _Observer__WEBPACK_IMPORTED_MODULE_2__["empty"]) { - context = Object.create(observerOrNext); - if (Object(_util_isFunction__WEBPACK_IMPORTED_MODULE_1__["isFunction"])(context.unsubscribe)) { - _this.add(context.unsubscribe.bind(context)); - } - context.unsubscribe = _this.unsubscribe.bind(_this); - } - } - _this._context = context; - _this._next = next; - _this._error = error; - _this._complete = complete; - return _this; +function schedulePromise(input, scheduler) { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + var sub = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); + sub.add(scheduler.schedule(function () { + return input.then(function (value) { + sub.add(scheduler.schedule(function () { + subscriber.next(value); + sub.add(scheduler.schedule(function () { return subscriber.complete(); })); + })); + }, function (err) { + sub.add(scheduler.schedule(function () { return subscriber.error(err); })); + }); + })); + return sub; + }); +} +//# sourceMappingURL=schedulePromise.js.map + + +/***/ }), +/* 218 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scheduleIterable", function() { return scheduleIterable; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(148); +/* harmony import */ var _symbol_iterator__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(206); +/** PURE_IMPORTS_START _Observable,_Subscription,_symbol_iterator PURE_IMPORTS_END */ + + + +function scheduleIterable(input, scheduler) { + if (!input) { + throw new Error('Iterable cannot be null'); } - SafeSubscriber.prototype.next = function (value) { - if (!this.isStopped && this._next) { - var _parentSubscriber = this._parentSubscriber; - if (!_config__WEBPACK_IMPORTED_MODULE_5__["config"].useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { - this.__tryOrUnsub(this._next, value); - } - else if (this.__tryOrSetError(_parentSubscriber, this._next, value)) { - this.unsubscribe(); - } - } - }; - SafeSubscriber.prototype.error = function (err) { - if (!this.isStopped) { - var _parentSubscriber = this._parentSubscriber; - var useDeprecatedSynchronousErrorHandling = _config__WEBPACK_IMPORTED_MODULE_5__["config"].useDeprecatedSynchronousErrorHandling; - if (this._error) { - if (!useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { - this.__tryOrUnsub(this._error, err); - this.unsubscribe(); - } - else { - this.__tryOrSetError(_parentSubscriber, this._error, err); - this.unsubscribe(); - } + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + var sub = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); + var iterator; + sub.add(function () { + if (iterator && typeof iterator.return === 'function') { + iterator.return(); } - else if (!_parentSubscriber.syncErrorThrowable) { - this.unsubscribe(); - if (useDeprecatedSynchronousErrorHandling) { - throw err; + }); + sub.add(scheduler.schedule(function () { + iterator = input[_symbol_iterator__WEBPACK_IMPORTED_MODULE_2__["iterator"]](); + sub.add(scheduler.schedule(function () { + if (subscriber.closed) { + return; } - Object(_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__["hostReportError"])(err); - } - else { - if (useDeprecatedSynchronousErrorHandling) { - _parentSubscriber.syncErrorValue = err; - _parentSubscriber.syncErrorThrown = true; + var value; + var done; + try { + var result = iterator.next(); + value = result.value; + done = result.done; } - else { - Object(_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__["hostReportError"])(err); + catch (err) { + subscriber.error(err); + return; } - this.unsubscribe(); - } - } - }; - SafeSubscriber.prototype.complete = function () { - var _this = this; - if (!this.isStopped) { - var _parentSubscriber = this._parentSubscriber; - if (this._complete) { - var wrappedComplete = function () { return _this._complete.call(_this._context); }; - if (!_config__WEBPACK_IMPORTED_MODULE_5__["config"].useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { - this.__tryOrUnsub(wrappedComplete); - this.unsubscribe(); + if (done) { + subscriber.complete(); } else { - this.__tryOrSetError(_parentSubscriber, wrappedComplete); - this.unsubscribe(); + subscriber.next(value); + this.schedule(); } - } - else { - this.unsubscribe(); - } - } - }; - SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) { - try { - fn.call(this._context, value); - } - catch (err) { - this.unsubscribe(); - if (_config__WEBPACK_IMPORTED_MODULE_5__["config"].useDeprecatedSynchronousErrorHandling) { - throw err; - } - else { - Object(_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__["hostReportError"])(err); - } - } - }; - SafeSubscriber.prototype.__tryOrSetError = function (parent, fn, value) { - if (!_config__WEBPACK_IMPORTED_MODULE_5__["config"].useDeprecatedSynchronousErrorHandling) { - throw new Error('bad call'); - } - try { - fn.call(this._context, value); - } - catch (err) { - if (_config__WEBPACK_IMPORTED_MODULE_5__["config"].useDeprecatedSynchronousErrorHandling) { - parent.syncErrorValue = err; - parent.syncErrorThrown = true; - return true; - } - else { - Object(_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__["hostReportError"])(err); - return true; - } - } - return false; - }; - SafeSubscriber.prototype._unsubscribe = function () { - var _parentSubscriber = this._parentSubscriber; - this._context = null; - this._parentSubscriber = null; - _parentSubscriber.unsubscribe(); - }; - return SafeSubscriber; -}(Subscriber)); + })); + })); + return sub; + }); +} +//# sourceMappingURL=scheduleIterable.js.map -//# sourceMappingURL=Subscriber.js.map + +/***/ }), +/* 219 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isInteropObservable", function() { return isInteropObservable; }); +/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(154); +/** PURE_IMPORTS_START _symbol_observable PURE_IMPORTS_END */ + +function isInteropObservable(input) { + return input && typeof input[_symbol_observable__WEBPACK_IMPORTED_MODULE_0__["observable"]] === 'function'; +} +//# sourceMappingURL=isInteropObservable.js.map /***/ }), -/* 173 */ +/* 220 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isFunction", function() { return isFunction; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function isFunction(x) { - return typeof x === 'function'; +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isIterable", function() { return isIterable; }); +/* harmony import */ var _symbol_iterator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(206); +/** PURE_IMPORTS_START _symbol_iterator PURE_IMPORTS_END */ + +function isIterable(input) { + return input && typeof input[_symbol_iterator__WEBPACK_IMPORTED_MODULE_0__["iterator"]] === 'function'; } -//# sourceMappingURL=isFunction.js.map +//# sourceMappingURL=isIterable.js.map /***/ }), -/* 174 */ +/* 221 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "empty", function() { return empty; }); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(175); -/* harmony import */ var _util_hostReportError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(176); -/** PURE_IMPORTS_START _config,_util_hostReportError PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defer", function() { return defer; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(214); +/* harmony import */ var _empty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(174); +/** PURE_IMPORTS_START _Observable,_from,_empty PURE_IMPORTS_END */ -var empty = { - closed: true, - next: function (value) { }, - error: function (err) { - if (_config__WEBPACK_IMPORTED_MODULE_0__["config"].useDeprecatedSynchronousErrorHandling) { - throw err; + +function defer(observableFactory) { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + var input; + try { + input = observableFactory(); } - else { - Object(_util_hostReportError__WEBPACK_IMPORTED_MODULE_1__["hostReportError"])(err); + catch (err) { + subscriber.error(err); + return undefined; } - }, - complete: function () { } -}; -//# sourceMappingURL=Observer.js.map + var source = input ? Object(_from__WEBPACK_IMPORTED_MODULE_1__["from"])(input) : Object(_empty__WEBPACK_IMPORTED_MODULE_2__["empty"])(); + return source.subscribe(subscriber); + }); +} +//# sourceMappingURL=defer.js.map /***/ }), -/* 175 */ +/* 222 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "config", function() { return config; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var _enable_super_gross_mode_that_will_cause_bad_things = false; -var config = { - Promise: undefined, - set useDeprecatedSynchronousErrorHandling(value) { - if (value) { - var error = /*@__PURE__*/ new Error(); - /*@__PURE__*/ console.warn('DEPRECATED! RxJS was set to use deprecated synchronous error handling behavior by code at: \n' + error.stack); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "forkJoin", function() { return forkJoin; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(149); +/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(197); +/* harmony import */ var _util_isObject__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(150); +/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(214); +/** PURE_IMPORTS_START _Observable,_util_isArray,_operators_map,_util_isObject,_from PURE_IMPORTS_END */ + + + + + +function forkJoin() { + var sources = []; + for (var _i = 0; _i < arguments.length; _i++) { + sources[_i] = arguments[_i]; + } + if (sources.length === 1) { + var first_1 = sources[0]; + if (Object(_util_isArray__WEBPACK_IMPORTED_MODULE_1__["isArray"])(first_1)) { + return forkJoinInternal(first_1, null); } - else if (_enable_super_gross_mode_that_will_cause_bad_things) { - /*@__PURE__*/ console.log('RxJS: Back to a better error behavior. Thank you. <3'); + if (Object(_util_isObject__WEBPACK_IMPORTED_MODULE_3__["isObject"])(first_1) && Object.getPrototypeOf(first_1) === Object.prototype) { + var keys = Object.keys(first_1); + return forkJoinInternal(keys.map(function (key) { return first_1[key]; }), keys); } - _enable_super_gross_mode_that_will_cause_bad_things = value; - }, - get useDeprecatedSynchronousErrorHandling() { - return _enable_super_gross_mode_that_will_cause_bad_things; - }, -}; -//# sourceMappingURL=config.js.map + } + if (typeof sources[sources.length - 1] === 'function') { + var resultSelector_1 = sources.pop(); + sources = (sources.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_1__["isArray"])(sources[0])) ? sources[0] : sources; + return forkJoinInternal(sources, null).pipe(Object(_operators_map__WEBPACK_IMPORTED_MODULE_2__["map"])(function (args) { return resultSelector_1.apply(void 0, args); })); + } + return forkJoinInternal(sources, null); +} +function forkJoinInternal(sources, keys) { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + var len = sources.length; + if (len === 0) { + subscriber.complete(); + return; + } + var values = new Array(len); + var completed = 0; + var emitted = 0; + var _loop_1 = function (i) { + var source = Object(_from__WEBPACK_IMPORTED_MODULE_4__["from"])(sources[i]); + var hasValue = false; + subscriber.add(source.subscribe({ + next: function (value) { + if (!hasValue) { + hasValue = true; + emitted++; + } + values[i] = value; + }, + error: function (err) { return subscriber.error(err); }, + complete: function () { + completed++; + if (completed === len || !hasValue) { + if (emitted === len) { + subscriber.next(keys ? + keys.reduce(function (result, key, i) { return (result[key] = values[i], result); }, {}) : + values); + } + subscriber.complete(); + } + } + })); + }; + for (var i = 0; i < len; i++) { + _loop_1(i); + } + }); +} +//# sourceMappingURL=forkJoin.js.map /***/ }), -/* 176 */ +/* 223 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hostReportError", function() { return hostReportError; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function hostReportError(err) { - setTimeout(function () { throw err; }, 0); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fromEvent", function() { return fromEvent; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(149); +/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); +/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(197); +/** PURE_IMPORTS_START _Observable,_util_isArray,_util_isFunction,_operators_map PURE_IMPORTS_END */ + + + + +var toString = /*@__PURE__*/ (function () { return Object.prototype.toString; })(); +function fromEvent(target, eventName, options, resultSelector) { + if (Object(_util_isFunction__WEBPACK_IMPORTED_MODULE_2__["isFunction"])(options)) { + resultSelector = options; + options = undefined; + } + if (resultSelector) { + return fromEvent(target, eventName, options).pipe(Object(_operators_map__WEBPACK_IMPORTED_MODULE_3__["map"])(function (args) { return Object(_util_isArray__WEBPACK_IMPORTED_MODULE_1__["isArray"])(args) ? resultSelector.apply(void 0, args) : resultSelector(args); })); + } + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + function handler(e) { + if (arguments.length > 1) { + subscriber.next(Array.prototype.slice.call(arguments)); + } + else { + subscriber.next(e); + } + } + setupSubscription(target, eventName, handler, subscriber, options); + }); } -//# sourceMappingURL=hostReportError.js.map +function setupSubscription(sourceObj, eventName, handler, subscriber, options) { + var unsubscribe; + if (isEventTarget(sourceObj)) { + var source_1 = sourceObj; + sourceObj.addEventListener(eventName, handler, options); + unsubscribe = function () { return source_1.removeEventListener(eventName, handler, options); }; + } + else if (isJQueryStyleEventEmitter(sourceObj)) { + var source_2 = sourceObj; + sourceObj.on(eventName, handler); + unsubscribe = function () { return source_2.off(eventName, handler); }; + } + else if (isNodeStyleEventEmitter(sourceObj)) { + var source_3 = sourceObj; + sourceObj.addListener(eventName, handler); + unsubscribe = function () { return source_3.removeListener(eventName, handler); }; + } + else if (sourceObj && sourceObj.length) { + for (var i = 0, len = sourceObj.length; i < len; i++) { + setupSubscription(sourceObj[i], eventName, handler, subscriber, options); + } + } + else { + throw new TypeError('Invalid event target'); + } + subscriber.add(unsubscribe); +} +function isNodeStyleEventEmitter(sourceObj) { + return sourceObj && typeof sourceObj.addListener === 'function' && typeof sourceObj.removeListener === 'function'; +} +function isJQueryStyleEventEmitter(sourceObj) { + return sourceObj && typeof sourceObj.on === 'function' && typeof sourceObj.off === 'function'; +} +function isEventTarget(sourceObj) { + return sourceObj && typeof sourceObj.addEventListener === 'function' && typeof sourceObj.removeEventListener === 'function'; +} +//# sourceMappingURL=fromEvent.js.map /***/ }), -/* 177 */ +/* 224 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Subscription", function() { return Subscription; }); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(178); -/* harmony import */ var _util_isObject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(179); -/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(173); -/* harmony import */ var _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(180); -/** PURE_IMPORTS_START _util_isArray,_util_isObject,_util_isFunction,_util_UnsubscriptionError PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fromEventPattern", function() { return fromEventPattern; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(149); +/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); +/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(197); +/** PURE_IMPORTS_START _Observable,_util_isArray,_util_isFunction,_operators_map PURE_IMPORTS_END */ -var Subscription = /*@__PURE__*/ (function () { - function Subscription(unsubscribe) { - this.closed = false; - this._parentOrParents = null; - this._subscriptions = null; - if (unsubscribe) { - this._unsubscribe = unsubscribe; - } +function fromEventPattern(addHandler, removeHandler, resultSelector) { + if (resultSelector) { + return fromEventPattern(addHandler, removeHandler).pipe(Object(_operators_map__WEBPACK_IMPORTED_MODULE_3__["map"])(function (args) { return Object(_util_isArray__WEBPACK_IMPORTED_MODULE_1__["isArray"])(args) ? resultSelector.apply(void 0, args) : resultSelector(args); })); } - Subscription.prototype.unsubscribe = function () { - var errors; - if (this.closed) { - return; + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + var handler = function () { + var e = []; + for (var _i = 0; _i < arguments.length; _i++) { + e[_i] = arguments[_i]; + } + return subscriber.next(e.length === 1 ? e[0] : e); + }; + var retValue; + try { + retValue = addHandler(handler); } - var _a = this, _parentOrParents = _a._parentOrParents, _unsubscribe = _a._unsubscribe, _subscriptions = _a._subscriptions; - this.closed = true; - this._parentOrParents = null; - this._subscriptions = null; - if (_parentOrParents instanceof Subscription) { - _parentOrParents.remove(this); - } - else if (_parentOrParents !== null) { - for (var index = 0; index < _parentOrParents.length; ++index) { - var parent_1 = _parentOrParents[index]; - parent_1.remove(this); - } - } - if (Object(_util_isFunction__WEBPACK_IMPORTED_MODULE_2__["isFunction"])(_unsubscribe)) { - try { - _unsubscribe.call(this); - } - catch (e) { - errors = e instanceof _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_3__["UnsubscriptionError"] ? flattenUnsubscriptionErrors(e.errors) : [e]; - } - } - if (Object(_util_isArray__WEBPACK_IMPORTED_MODULE_0__["isArray"])(_subscriptions)) { - var index = -1; - var len = _subscriptions.length; - while (++index < len) { - var sub = _subscriptions[index]; - if (Object(_util_isObject__WEBPACK_IMPORTED_MODULE_1__["isObject"])(sub)) { - try { - sub.unsubscribe(); - } - catch (e) { - errors = errors || []; - if (e instanceof _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_3__["UnsubscriptionError"]) { - errors = errors.concat(flattenUnsubscriptionErrors(e.errors)); - } - else { - errors.push(e); - } - } - } - } + catch (err) { + subscriber.error(err); + return undefined; } - if (errors) { - throw new _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_3__["UnsubscriptionError"](errors); + if (!Object(_util_isFunction__WEBPACK_IMPORTED_MODULE_2__["isFunction"])(removeHandler)) { + return undefined; } - }; - Subscription.prototype.add = function (teardown) { - var subscription = teardown; - if (!teardown) { - return Subscription.EMPTY; + return function () { return removeHandler(handler, retValue); }; + }); +} +//# sourceMappingURL=fromEventPattern.js.map + + +/***/ }), +/* 225 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "generate", function() { return generate; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(191); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(176); +/** PURE_IMPORTS_START _Observable,_util_identity,_util_isScheduler PURE_IMPORTS_END */ + + + +function generate(initialStateOrOptions, condition, iterate, resultSelectorOrObservable, scheduler) { + var resultSelector; + var initialState; + if (arguments.length == 1) { + var options = initialStateOrOptions; + initialState = options.initialState; + condition = options.condition; + iterate = options.iterate; + resultSelector = options.resultSelector || _util_identity__WEBPACK_IMPORTED_MODULE_1__["identity"]; + scheduler = options.scheduler; + } + else if (resultSelectorOrObservable === undefined || Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_2__["isScheduler"])(resultSelectorOrObservable)) { + initialState = initialStateOrOptions; + resultSelector = _util_identity__WEBPACK_IMPORTED_MODULE_1__["identity"]; + scheduler = resultSelectorOrObservable; + } + else { + initialState = initialStateOrOptions; + resultSelector = resultSelectorOrObservable; + } + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + var state = initialState; + if (scheduler) { + return scheduler.schedule(dispatch, 0, { + subscriber: subscriber, + iterate: iterate, + condition: condition, + resultSelector: resultSelector, + state: state + }); } - switch (typeof teardown) { - case 'function': - subscription = new Subscription(teardown); - case 'object': - if (subscription === this || subscription.closed || typeof subscription.unsubscribe !== 'function') { - return subscription; + do { + if (condition) { + var conditionResult = void 0; + try { + conditionResult = condition(state); } - else if (this.closed) { - subscription.unsubscribe(); - return subscription; + catch (err) { + subscriber.error(err); + return undefined; } - else if (!(subscription instanceof Subscription)) { - var tmp = subscription; - subscription = new Subscription(); - subscription._subscriptions = [tmp]; + if (!conditionResult) { + subscriber.complete(); + break; } + } + var value = void 0; + try { + value = resultSelector(state); + } + catch (err) { + subscriber.error(err); + return undefined; + } + subscriber.next(value); + if (subscriber.closed) { break; - default: { - throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.'); } - } - var _parentOrParents = subscription._parentOrParents; - if (_parentOrParents === null) { - subscription._parentOrParents = this; - } - else if (_parentOrParents instanceof Subscription) { - if (_parentOrParents === this) { - return subscription; + try { + state = iterate(state); } - subscription._parentOrParents = [_parentOrParents, this]; + catch (err) { + subscriber.error(err); + return undefined; + } + } while (true); + return undefined; + }); +} +function dispatch(state) { + var subscriber = state.subscriber, condition = state.condition; + if (subscriber.closed) { + return undefined; + } + if (state.needIterate) { + try { + state.state = state.iterate(state.state); } - else if (_parentOrParents.indexOf(this) === -1) { - _parentOrParents.push(this); + catch (err) { + subscriber.error(err); + return undefined; } - else { - return subscription; + } + else { + state.needIterate = true; + } + if (condition) { + var conditionResult = void 0; + try { + conditionResult = condition(state.state); } - var subscriptions = this._subscriptions; - if (subscriptions === null) { - this._subscriptions = [subscription]; + catch (err) { + subscriber.error(err); + return undefined; } - else { - subscriptions.push(subscription); + if (!conditionResult) { + subscriber.complete(); + return undefined; } - return subscription; - }; - Subscription.prototype.remove = function (subscription) { - var subscriptions = this._subscriptions; - if (subscriptions) { - var subscriptionIndex = subscriptions.indexOf(subscription); - if (subscriptionIndex !== -1) { - subscriptions.splice(subscriptionIndex, 1); - } + if (subscriber.closed) { + return undefined; } - }; - Subscription.EMPTY = (function (empty) { - empty.closed = true; - return empty; - }(new Subscription())); - return Subscription; -}()); - -function flattenUnsubscriptionErrors(errors) { - return errors.reduce(function (errs, err) { return errs.concat((err instanceof _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_3__["UnsubscriptionError"]) ? err.errors : err); }, []); + } + var value; + try { + value = state.resultSelector(state.state); + } + catch (err) { + subscriber.error(err); + return undefined; + } + if (subscriber.closed) { + return undefined; + } + subscriber.next(value); + if (subscriber.closed) { + return undefined; + } + return this.schedule(state); } -//# sourceMappingURL=Subscription.js.map +//# sourceMappingURL=generate.js.map /***/ }), -/* 178 */ +/* 226 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isArray", function() { return isArray; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var isArray = /*@__PURE__*/ (function () { return Array.isArray || (function (x) { return x && typeof x.length === 'number'; }); })(); -//# sourceMappingURL=isArray.js.map - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "iif", function() { return iif; }); +/* harmony import */ var _defer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(221); +/* harmony import */ var _empty__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(174); +/** PURE_IMPORTS_START _defer,_empty PURE_IMPORTS_END */ -/***/ }), -/* 179 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isObject", function() { return isObject; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function isObject(x) { - return x !== null && typeof x === 'object'; +function iif(condition, trueResult, falseResult) { + if (trueResult === void 0) { + trueResult = _empty__WEBPACK_IMPORTED_MODULE_1__["EMPTY"]; + } + if (falseResult === void 0) { + falseResult = _empty__WEBPACK_IMPORTED_MODULE_1__["EMPTY"]; + } + return Object(_defer__WEBPACK_IMPORTED_MODULE_0__["defer"])(function () { return condition() ? trueResult : falseResult; }); } -//# sourceMappingURL=isObject.js.map +//# sourceMappingURL=iif.js.map /***/ }), -/* 180 */ +/* 227 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UnsubscriptionError", function() { return UnsubscriptionError; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var UnsubscriptionErrorImpl = /*@__PURE__*/ (function () { - function UnsubscriptionErrorImpl(errors) { - Error.call(this); - this.message = errors ? - errors.length + " errors occurred during unsubscription:\n" + errors.map(function (err, i) { return i + 1 + ") " + err.toString(); }).join('\n ') : ''; - this.name = 'UnsubscriptionError'; - this.errors = errors; - return this; +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "interval", function() { return interval; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(186); +/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(228); +/** PURE_IMPORTS_START _Observable,_scheduler_async,_util_isNumeric PURE_IMPORTS_END */ + + + +function interval(period, scheduler) { + if (period === void 0) { + period = 0; } - UnsubscriptionErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); - return UnsubscriptionErrorImpl; -})(); -var UnsubscriptionError = UnsubscriptionErrorImpl; -//# sourceMappingURL=UnsubscriptionError.js.map + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; + } + if (!Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_2__["isNumeric"])(period) || period < 0) { + period = 0; + } + if (!scheduler || typeof scheduler.schedule !== 'function') { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; + } + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + subscriber.add(scheduler.schedule(dispatch, period, { subscriber: subscriber, counter: 0, period: period })); + return subscriber; + }); +} +function dispatch(state) { + var subscriber = state.subscriber, counter = state.counter, period = state.period; + subscriber.next(counter); + this.schedule({ subscriber: subscriber, counter: counter + 1, period: period }, period); +} +//# sourceMappingURL=interval.js.map /***/ }), -/* 181 */ +/* 228 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rxSubscriber", function() { return rxSubscriber; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "$$rxSubscriber", function() { return $$rxSubscriber; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var rxSubscriber = /*@__PURE__*/ (function () { - return typeof Symbol === 'function' - ? /*@__PURE__*/ Symbol('rxSubscriber') - : '@@rxSubscriber_' + /*@__PURE__*/ Math.random(); -})(); -var $$rxSubscriber = rxSubscriber; -//# sourceMappingURL=rxSubscriber.js.map +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isNumeric", function() { return isNumeric; }); +/* harmony import */ var _isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(149); +/** PURE_IMPORTS_START _isArray PURE_IMPORTS_END */ + +function isNumeric(val) { + return !Object(_isArray__WEBPACK_IMPORTED_MODULE_0__["isArray"])(val) && (val - parseFloat(val) + 1) >= 0; +} +//# sourceMappingURL=isNumeric.js.map /***/ }), -/* 182 */ +/* 229 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toSubscriber", function() { return toSubscriber; }); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(172); -/* harmony import */ var _symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(181); -/* harmony import */ var _Observer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(174); -/** PURE_IMPORTS_START _Subscriber,_symbol_rxSubscriber,_Observer PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return merge; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(176); +/* harmony import */ var _operators_mergeAll__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(212); +/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(177); +/** PURE_IMPORTS_START _Observable,_util_isScheduler,_operators_mergeAll,_fromArray PURE_IMPORTS_END */ -function toSubscriber(nextOrObserver, error, complete) { - if (nextOrObserver) { - if (nextOrObserver instanceof _Subscriber__WEBPACK_IMPORTED_MODULE_0__["Subscriber"]) { - return nextOrObserver; - } - if (nextOrObserver[_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_1__["rxSubscriber"]]) { - return nextOrObserver[_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_1__["rxSubscriber"]](); + +function merge() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + var concurrent = Number.POSITIVE_INFINITY; + var scheduler = null; + var last = observables[observables.length - 1]; + if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_1__["isScheduler"])(last)) { + scheduler = observables.pop(); + if (observables.length > 1 && typeof observables[observables.length - 1] === 'number') { + concurrent = observables.pop(); } } - if (!nextOrObserver && !error && !complete) { - return new _Subscriber__WEBPACK_IMPORTED_MODULE_0__["Subscriber"](_Observer__WEBPACK_IMPORTED_MODULE_2__["empty"]); + else if (typeof last === 'number') { + concurrent = observables.pop(); } - return new _Subscriber__WEBPACK_IMPORTED_MODULE_0__["Subscriber"](nextOrObserver, error, complete); + if (scheduler === null && observables.length === 1 && observables[0] instanceof _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]) { + return observables[0]; + } + return Object(_operators_mergeAll__WEBPACK_IMPORTED_MODULE_2__["mergeAll"])(concurrent)(Object(_fromArray__WEBPACK_IMPORTED_MODULE_3__["fromArray"])(observables, scheduler)); } -//# sourceMappingURL=toSubscriber.js.map +//# sourceMappingURL=merge.js.map /***/ }), -/* 183 */ +/* 230 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "observable", function() { return observable; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var observable = /*@__PURE__*/ (function () { return typeof Symbol === 'function' && Symbol.observable || '@@observable'; })(); -//# sourceMappingURL=observable.js.map +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NEVER", function() { return NEVER; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "never", function() { return never; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(156); +/** PURE_IMPORTS_START _Observable,_util_noop PURE_IMPORTS_END */ + + +var NEVER = /*@__PURE__*/ new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](_util_noop__WEBPACK_IMPORTED_MODULE_1__["noop"]); +function never() { + return NEVER; +} +//# sourceMappingURL=never.js.map /***/ }), -/* 184 */ +/* 231 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pipe", function() { return pipe; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pipeFromArray", function() { return pipeFromArray; }); -/* harmony import */ var _noop__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(185); -/** PURE_IMPORTS_START _noop PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return onErrorResumeNext; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(214); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(149); +/* harmony import */ var _empty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(174); +/** PURE_IMPORTS_START _Observable,_from,_util_isArray,_empty PURE_IMPORTS_END */ -function pipe() { - var fns = []; + + + +function onErrorResumeNext() { + var sources = []; for (var _i = 0; _i < arguments.length; _i++) { - fns[_i] = arguments[_i]; + sources[_i] = arguments[_i]; } - return pipeFromArray(fns); -} -function pipeFromArray(fns) { - if (!fns) { - return _noop__WEBPACK_IMPORTED_MODULE_0__["noop"]; + if (sources.length === 0) { + return _empty__WEBPACK_IMPORTED_MODULE_3__["EMPTY"]; } - if (fns.length === 1) { - return fns[0]; + var first = sources[0], remainder = sources.slice(1); + if (sources.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_2__["isArray"])(first)) { + return onErrorResumeNext.apply(void 0, first); } - return function piped(input) { - return fns.reduce(function (prev, fn) { return fn(prev); }, input); - }; + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + var subNext = function () { return subscriber.add(onErrorResumeNext.apply(void 0, remainder).subscribe(subscriber)); }; + return Object(_from__WEBPACK_IMPORTED_MODULE_1__["from"])(first).subscribe({ + next: function (value) { subscriber.next(value); }, + error: subNext, + complete: subNext, + }); + }); } -//# sourceMappingURL=pipe.js.map +//# sourceMappingURL=onErrorResumeNext.js.map /***/ }), -/* 185 */ +/* 232 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "noop", function() { return noop; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function noop() { } -//# sourceMappingURL=noop.js.map +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pairs", function() { return pairs; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dispatch", function() { return dispatch; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(148); +/** PURE_IMPORTS_START _Observable,_Subscription PURE_IMPORTS_END */ + + +function pairs(obj, scheduler) { + if (!scheduler) { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + var keys = Object.keys(obj); + for (var i = 0; i < keys.length && !subscriber.closed; i++) { + var key = keys[i]; + if (obj.hasOwnProperty(key)) { + subscriber.next([key, obj[key]]); + } + } + subscriber.complete(); + }); + } + else { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + var keys = Object.keys(obj); + var subscription = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); + subscription.add(scheduler.schedule(dispatch, 0, { keys: keys, index: 0, subscriber: subscriber, subscription: subscription, obj: obj })); + return subscription; + }); + } +} +function dispatch(state) { + var keys = state.keys, index = state.index, subscriber = state.subscriber, subscription = state.subscription, obj = state.obj; + if (!subscriber.closed) { + if (index < keys.length) { + var key = keys[index]; + subscriber.next([key, obj[key]]); + subscription.add(this.schedule({ keys: keys, index: index + 1, subscriber: subscriber, subscription: subscription, obj: obj })); + } + else { + subscriber.complete(); + } + } +} +//# sourceMappingURL=pairs.js.map /***/ }), -/* 186 */ +/* 233 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ConnectableObservable", function() { return ConnectableObservable; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "connectableObservableDescriptor", function() { return connectableObservableDescriptor; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(187); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(170); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(172); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(177); -/* harmony import */ var _operators_refCount__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(190); -/** PURE_IMPORTS_START tslib,_Subject,_Observable,_Subscriber,_Subscription,_operators_refCount PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return partition; }); +/* harmony import */ var _util_not__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(234); +/* harmony import */ var _util_subscribeTo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(203); +/* harmony import */ var _operators_filter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(235); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(141); +/** PURE_IMPORTS_START _util_not,_util_subscribeTo,_operators_filter,_Observable PURE_IMPORTS_END */ +function partition(source, predicate, thisArg) { + return [ + Object(_operators_filter__WEBPACK_IMPORTED_MODULE_2__["filter"])(predicate, thisArg)(new _Observable__WEBPACK_IMPORTED_MODULE_3__["Observable"](Object(_util_subscribeTo__WEBPACK_IMPORTED_MODULE_1__["subscribeTo"])(source))), + Object(_operators_filter__WEBPACK_IMPORTED_MODULE_2__["filter"])(Object(_util_not__WEBPACK_IMPORTED_MODULE_0__["not"])(predicate, thisArg))(new _Observable__WEBPACK_IMPORTED_MODULE_3__["Observable"](Object(_util_subscribeTo__WEBPACK_IMPORTED_MODULE_1__["subscribeTo"])(source))) + ]; +} +//# sourceMappingURL=partition.js.map -var ConnectableObservable = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ConnectableObservable, _super); - function ConnectableObservable(source, subjectFactory) { - var _this = _super.call(this) || this; - _this.source = source; - _this.subjectFactory = subjectFactory; - _this._refCount = 0; - _this._isComplete = false; - return _this; +/***/ }), +/* 234 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "not", function() { return not; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function not(pred, thisArg) { + function notPred() { + return !(notPred.pred.apply(notPred.thisArg, arguments)); } - ConnectableObservable.prototype._subscribe = function (subscriber) { - return this.getSubject().subscribe(subscriber); - }; - ConnectableObservable.prototype.getSubject = function () { - var subject = this._subject; - if (!subject || subject.isStopped) { - this._subject = this.subjectFactory(); - } - return this._subject; - }; - ConnectableObservable.prototype.connect = function () { - var connection = this._connection; - if (!connection) { - this._isComplete = false; - connection = this._connection = new _Subscription__WEBPACK_IMPORTED_MODULE_4__["Subscription"](); - connection.add(this.source - .subscribe(new ConnectableSubscriber(this.getSubject(), this))); - if (connection.closed) { - this._connection = null; - connection = _Subscription__WEBPACK_IMPORTED_MODULE_4__["Subscription"].EMPTY; - } - } - return connection; - }; - ConnectableObservable.prototype.refCount = function () { - return Object(_operators_refCount__WEBPACK_IMPORTED_MODULE_5__["refCount"])()(this); - }; - return ConnectableObservable; -}(_Observable__WEBPACK_IMPORTED_MODULE_2__["Observable"])); + notPred.pred = pred; + notPred.thisArg = thisArg; + return notPred; +} +//# sourceMappingURL=not.js.map -var connectableObservableDescriptor = /*@__PURE__*/ (function () { - var connectableProto = ConnectableObservable.prototype; - return { - operator: { value: null }, - _refCount: { value: 0, writable: true }, - _subject: { value: null, writable: true }, - _connection: { value: null, writable: true }, - _subscribe: { value: connectableProto._subscribe }, - _isComplete: { value: connectableProto._isComplete, writable: true }, - getSubject: { value: connectableProto.getSubject }, - connect: { value: connectableProto.connect }, - refCount: { value: connectableProto.refCount } - }; -})(); -var ConnectableSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ConnectableSubscriber, _super); - function ConnectableSubscriber(destination, connectable) { - var _this = _super.call(this, destination) || this; - _this.connectable = connectable; - return _this; - } - ConnectableSubscriber.prototype._error = function (err) { - this._unsubscribe(); - _super.prototype._error.call(this, err); - }; - ConnectableSubscriber.prototype._complete = function () { - this.connectable._isComplete = true; - this._unsubscribe(); - _super.prototype._complete.call(this); - }; - ConnectableSubscriber.prototype._unsubscribe = function () { - var connectable = this.connectable; - if (connectable) { - this.connectable = null; - var connection = connectable._connection; - connectable._refCount = 0; - connectable._subject = null; - connectable._connection = null; - if (connection) { - connection.unsubscribe(); - } - } + +/***/ }), +/* 235 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "filter", function() { return filter; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function filter(predicate, thisArg) { + return function filterOperatorFunction(source) { + return source.lift(new FilterOperator(predicate, thisArg)); }; - return ConnectableSubscriber; -}(_Subject__WEBPACK_IMPORTED_MODULE_1__["SubjectSubscriber"])); -var RefCountOperator = /*@__PURE__*/ (function () { - function RefCountOperator(connectable) { - this.connectable = connectable; +} +var FilterOperator = /*@__PURE__*/ (function () { + function FilterOperator(predicate, thisArg) { + this.predicate = predicate; + this.thisArg = thisArg; } - RefCountOperator.prototype.call = function (subscriber, source) { - var connectable = this.connectable; - connectable._refCount++; - var refCounter = new RefCountSubscriber(subscriber, connectable); - var subscription = source.subscribe(refCounter); - if (!refCounter.closed) { - refCounter.connection = connectable.connect(); - } - return subscription; + FilterOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new FilterSubscriber(subscriber, this.predicate, this.thisArg)); }; - return RefCountOperator; + return FilterOperator; }()); -var RefCountSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RefCountSubscriber, _super); - function RefCountSubscriber(destination, connectable) { +var FilterSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FilterSubscriber, _super); + function FilterSubscriber(destination, predicate, thisArg) { var _this = _super.call(this, destination) || this; - _this.connectable = connectable; + _this.predicate = predicate; + _this.thisArg = thisArg; + _this.count = 0; return _this; } - RefCountSubscriber.prototype._unsubscribe = function () { - var connectable = this.connectable; - if (!connectable) { - this.connection = null; - return; - } - this.connectable = null; - var refCount = connectable._refCount; - if (refCount <= 0) { - this.connection = null; - return; + FilterSubscriber.prototype._next = function (value) { + var result; + try { + result = this.predicate.call(this.thisArg, value, this.count++); } - connectable._refCount = refCount - 1; - if (refCount > 1) { - this.connection = null; + catch (err) { + this.destination.error(err); return; } - var connection = this.connection; - var sharedConnection = connectable._connection; - this.connection = null; - if (sharedConnection && (!connection || sharedConnection === connection)) { - sharedConnection.unsubscribe(); + if (result) { + this.destination.next(value); } }; - return RefCountSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__["Subscriber"])); -//# sourceMappingURL=ConnectableObservable.js.map + return FilterSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=filter.js.map /***/ }), -/* 187 */ +/* 236 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubjectSubscriber", function() { return SubjectSubscriber; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Subject", function() { return Subject; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnonymousSubject", function() { return AnonymousSubject; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(170); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(172); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(177); -/* harmony import */ var _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(188); -/* harmony import */ var _SubjectSubscription__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(189); -/* harmony import */ var _internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(181); -/** PURE_IMPORTS_START tslib,_Observable,_Subscriber,_Subscription,_util_ObjectUnsubscribedError,_SubjectSubscription,_internal_symbol_rxSubscriber PURE_IMPORTS_END */ - - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "race", function() { return race; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RaceOperator", function() { return RaceOperator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RaceSubscriber", function() { return RaceSubscriber; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(149); +/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(177); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_util_isArray,_fromArray,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -var SubjectSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubjectSubscriber, _super); - function SubjectSubscriber(destination) { - var _this = _super.call(this, destination) || this; - _this.destination = destination; - return _this; - } - return SubjectSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_2__["Subscriber"])); -var Subject = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](Subject, _super); - function Subject() { - var _this = _super.call(this) || this; - _this.observers = []; - _this.closed = false; - _this.isStopped = false; - _this.hasError = false; - _this.thrownError = null; - return _this; +function race() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; } - Subject.prototype[_internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_6__["rxSubscriber"]] = function () { - return new SubjectSubscriber(this); - }; - Subject.prototype.lift = function (operator) { - var subject = new AnonymousSubject(this, this); - subject.operator = operator; - return subject; - }; - Subject.prototype.next = function (value) { - if (this.closed) { - throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_4__["ObjectUnsubscribedError"](); - } - if (!this.isStopped) { - var observers = this.observers; - var len = observers.length; - var copy = observers.slice(); - for (var i = 0; i < len; i++) { - copy[i].next(value); - } - } - }; - Subject.prototype.error = function (err) { - if (this.closed) { - throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_4__["ObjectUnsubscribedError"](); - } - this.hasError = true; - this.thrownError = err; - this.isStopped = true; - var observers = this.observers; - var len = observers.length; - var copy = observers.slice(); - for (var i = 0; i < len; i++) { - copy[i].error(err); - } - this.observers.length = 0; - }; - Subject.prototype.complete = function () { - if (this.closed) { - throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_4__["ObjectUnsubscribedError"](); - } - this.isStopped = true; - var observers = this.observers; - var len = observers.length; - var copy = observers.slice(); - for (var i = 0; i < len; i++) { - copy[i].complete(); - } - this.observers.length = 0; - }; - Subject.prototype.unsubscribe = function () { - this.isStopped = true; - this.closed = true; - this.observers = null; - }; - Subject.prototype._trySubscribe = function (subscriber) { - if (this.closed) { - throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_4__["ObjectUnsubscribedError"](); - } - else { - return _super.prototype._trySubscribe.call(this, subscriber); - } - }; - Subject.prototype._subscribe = function (subscriber) { - if (this.closed) { - throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_4__["ObjectUnsubscribedError"](); - } - else if (this.hasError) { - subscriber.error(this.thrownError); - return _Subscription__WEBPACK_IMPORTED_MODULE_3__["Subscription"].EMPTY; - } - else if (this.isStopped) { - subscriber.complete(); - return _Subscription__WEBPACK_IMPORTED_MODULE_3__["Subscription"].EMPTY; + if (observables.length === 1) { + if (Object(_util_isArray__WEBPACK_IMPORTED_MODULE_1__["isArray"])(observables[0])) { + observables = observables[0]; } else { - this.observers.push(subscriber); - return new _SubjectSubscription__WEBPACK_IMPORTED_MODULE_5__["SubjectSubscription"](this, subscriber); + return observables[0]; } + } + return Object(_fromArray__WEBPACK_IMPORTED_MODULE_2__["fromArray"])(observables, undefined).lift(new RaceOperator()); +} +var RaceOperator = /*@__PURE__*/ (function () { + function RaceOperator() { + } + RaceOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new RaceSubscriber(subscriber)); }; - Subject.prototype.asObservable = function () { - var observable = new _Observable__WEBPACK_IMPORTED_MODULE_1__["Observable"](); - observable.source = this; - return observable; - }; - Subject.create = function (destination, source) { - return new AnonymousSubject(destination, source); - }; - return Subject; -}(_Observable__WEBPACK_IMPORTED_MODULE_1__["Observable"])); + return RaceOperator; +}()); -var AnonymousSubject = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AnonymousSubject, _super); - function AnonymousSubject(destination, source) { - var _this = _super.call(this) || this; - _this.destination = destination; - _this.source = source; +var RaceSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RaceSubscriber, _super); + function RaceSubscriber(destination) { + var _this = _super.call(this, destination) || this; + _this.hasFirst = false; + _this.observables = []; + _this.subscriptions = []; return _this; } - AnonymousSubject.prototype.next = function (value) { - var destination = this.destination; - if (destination && destination.next) { - destination.next(value); - } - }; - AnonymousSubject.prototype.error = function (err) { - var destination = this.destination; - if (destination && destination.error) { - this.destination.error(err); - } + RaceSubscriber.prototype._next = function (observable) { + this.observables.push(observable); }; - AnonymousSubject.prototype.complete = function () { - var destination = this.destination; - if (destination && destination.complete) { + RaceSubscriber.prototype._complete = function () { + var observables = this.observables; + var len = observables.length; + if (len === 0) { this.destination.complete(); } - }; - AnonymousSubject.prototype._subscribe = function (subscriber) { - var source = this.source; - if (source) { - return this.source.subscribe(subscriber); - } else { - return _Subscription__WEBPACK_IMPORTED_MODULE_3__["Subscription"].EMPTY; + for (var i = 0; i < len && !this.hasFirst; i++) { + var observable = observables[i]; + var subscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, observable, observable, i); + if (this.subscriptions) { + this.subscriptions.push(subscription); + } + this.add(subscription); + } + this.observables = null; } }; - return AnonymousSubject; -}(Subject)); + RaceSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + if (!this.hasFirst) { + this.hasFirst = true; + for (var i = 0; i < this.subscriptions.length; i++) { + if (i !== outerIndex) { + var subscription = this.subscriptions[i]; + subscription.unsubscribe(); + this.remove(subscription); + } + } + this.subscriptions = null; + } + this.destination.next(innerValue); + }; + return RaceSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); -//# sourceMappingURL=Subject.js.map +//# sourceMappingURL=race.js.map /***/ }), -/* 188 */ +/* 237 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ObjectUnsubscribedError", function() { return ObjectUnsubscribedError; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var ObjectUnsubscribedErrorImpl = /*@__PURE__*/ (function () { - function ObjectUnsubscribedErrorImpl() { - Error.call(this); - this.message = 'object unsubscribed'; - this.name = 'ObjectUnsubscribedError'; - return this; +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "range", function() { return range; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dispatch", function() { return dispatch; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ + +function range(start, count, scheduler) { + if (start === void 0) { + start = 0; } - ObjectUnsubscribedErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); - return ObjectUnsubscribedErrorImpl; -})(); -var ObjectUnsubscribedError = ObjectUnsubscribedErrorImpl; -//# sourceMappingURL=ObjectUnsubscribedError.js.map + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + if (count === undefined) { + count = start; + start = 0; + } + var index = 0; + var current = start; + if (scheduler) { + return scheduler.schedule(dispatch, 0, { + index: index, count: count, start: start, subscriber: subscriber + }); + } + else { + do { + if (index++ >= count) { + subscriber.complete(); + break; + } + subscriber.next(current++); + if (subscriber.closed) { + break; + } + } while (true); + } + return undefined; + }); +} +function dispatch(state) { + var start = state.start, index = state.index, count = state.count, subscriber = state.subscriber; + if (index >= count) { + subscriber.complete(); + return; + } + subscriber.next(start); + if (subscriber.closed) { + return; + } + state.index = index + 1; + state.start = start + 1; + this.schedule(state); +} +//# sourceMappingURL=range.js.map /***/ }), -/* 189 */ +/* 238 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubjectSubscription", function() { return SubjectSubscription; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(177); -/** PURE_IMPORTS_START tslib,_Subscription PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timer", function() { return timer; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(186); +/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(228); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(176); +/** PURE_IMPORTS_START _Observable,_scheduler_async,_util_isNumeric,_util_isScheduler PURE_IMPORTS_END */ -var SubjectSubscription = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubjectSubscription, _super); - function SubjectSubscription(subject, subscriber) { - var _this = _super.call(this) || this; - _this.subject = subject; - _this.subscriber = subscriber; - _this.closed = false; - return _this; - } - SubjectSubscription.prototype.unsubscribe = function () { - if (this.closed) { - return; - } - this.closed = true; - var subject = this.subject; - var observers = subject.observers; - this.subject = null; - if (!observers || observers.length === 0 || subject.isStopped || subject.closed) { - return; - } - var subscriberIndex = observers.indexOf(this.subscriber); - if (subscriberIndex !== -1) { - observers.splice(subscriberIndex, 1); - } - }; - return SubjectSubscription; -}(_Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"])); -//# sourceMappingURL=SubjectSubscription.js.map + +function timer(dueTime, periodOrScheduler, scheduler) { + if (dueTime === void 0) { + dueTime = 0; + } + var period = -1; + if (Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_2__["isNumeric"])(periodOrScheduler)) { + period = Number(periodOrScheduler) < 1 && 1 || Number(periodOrScheduler); + } + else if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_3__["isScheduler"])(periodOrScheduler)) { + scheduler = periodOrScheduler; + } + if (!Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_3__["isScheduler"])(scheduler)) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; + } + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + var due = Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_2__["isNumeric"])(dueTime) + ? dueTime + : (+dueTime - scheduler.now()); + return scheduler.schedule(dispatch, due, { + index: 0, period: period, subscriber: subscriber + }); + }); +} +function dispatch(state) { + var index = state.index, period = state.period, subscriber = state.subscriber; + subscriber.next(index); + if (subscriber.closed) { + return; + } + else if (period === -1) { + return subscriber.complete(); + } + state.index = index + 1; + this.schedule(state, period); +} +//# sourceMappingURL=timer.js.map /***/ }), -/* 190 */ +/* 239 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "refCount", function() { return refCount; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "using", function() { return using; }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(141); +/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(214); +/* harmony import */ var _empty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(174); +/** PURE_IMPORTS_START _Observable,_from,_empty PURE_IMPORTS_END */ -function refCount() { - return function refCountOperatorFunction(source) { - return source.lift(new RefCountOperator(source)); - }; -} -var RefCountOperator = /*@__PURE__*/ (function () { - function RefCountOperator(connectable) { - this.connectable = connectable; - } - RefCountOperator.prototype.call = function (subscriber, source) { - var connectable = this.connectable; - connectable._refCount++; - var refCounter = new RefCountSubscriber(subscriber, connectable); - var subscription = source.subscribe(refCounter); - if (!refCounter.closed) { - refCounter.connection = connectable.connect(); + +function using(resourceFactory, observableFactory) { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { + var resource; + try { + resource = resourceFactory(); } - return subscription; - }; - return RefCountOperator; -}()); -var RefCountSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RefCountSubscriber, _super); - function RefCountSubscriber(destination, connectable) { - var _this = _super.call(this, destination) || this; - _this.connectable = connectable; - return _this; - } - RefCountSubscriber.prototype._unsubscribe = function () { - var connectable = this.connectable; - if (!connectable) { - this.connection = null; - return; - } - this.connectable = null; - var refCount = connectable._refCount; - if (refCount <= 0) { - this.connection = null; - return; + catch (err) { + subscriber.error(err); + return undefined; } - connectable._refCount = refCount - 1; - if (refCount > 1) { - this.connection = null; - return; + var result; + try { + result = observableFactory(resource); } - var connection = this.connection; - var sharedConnection = connectable._connection; - this.connection = null; - if (sharedConnection && (!connection || sharedConnection === connection)) { - sharedConnection.unsubscribe(); + catch (err) { + subscriber.error(err); + return undefined; } - }; - return RefCountSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=refCount.js.map + var source = result ? Object(_from__WEBPACK_IMPORTED_MODULE_1__["from"])(result) : _empty__WEBPACK_IMPORTED_MODULE_2__["EMPTY"]; + var subscription = source.subscribe(subscriber); + return function () { + subscription.unsubscribe(); + if (resource) { + resource.unsubscribe(); + } + }; + }); +} +//# sourceMappingURL=using.js.map /***/ }), -/* 191 */ +/* 240 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "groupBy", function() { return groupBy; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GroupedObservable", function() { return GroupedObservable; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(177); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(170); -/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(187); -/** PURE_IMPORTS_START tslib,_Subscriber,_Subscription,_Observable,_Subject PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return zip; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ZipOperator", function() { return ZipOperator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ZipSubscriber", function() { return ZipSubscriber; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(177); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(149); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(143); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(201); +/* harmony import */ var _internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(206); +/** PURE_IMPORTS_START tslib,_fromArray,_util_isArray,_Subscriber,_OuterSubscriber,_util_subscribeToResult,_.._internal_symbol_iterator PURE_IMPORTS_END */ -function groupBy(keySelector, elementSelector, durationSelector, subjectSelector) { - return function (source) { - return source.lift(new GroupByOperator(keySelector, elementSelector, durationSelector, subjectSelector)); - }; + + +function zip() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + var resultSelector = observables[observables.length - 1]; + if (typeof resultSelector === 'function') { + observables.pop(); + } + return Object(_fromArray__WEBPACK_IMPORTED_MODULE_1__["fromArray"])(observables, undefined).lift(new ZipOperator(resultSelector)); } -var GroupByOperator = /*@__PURE__*/ (function () { - function GroupByOperator(keySelector, elementSelector, durationSelector, subjectSelector) { - this.keySelector = keySelector; - this.elementSelector = elementSelector; - this.durationSelector = durationSelector; - this.subjectSelector = subjectSelector; +var ZipOperator = /*@__PURE__*/ (function () { + function ZipOperator(resultSelector) { + this.resultSelector = resultSelector; } - GroupByOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new GroupBySubscriber(subscriber, this.keySelector, this.elementSelector, this.durationSelector, this.subjectSelector)); + ZipOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ZipSubscriber(subscriber, this.resultSelector)); }; - return GroupByOperator; + return ZipOperator; }()); -var GroupBySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](GroupBySubscriber, _super); - function GroupBySubscriber(destination, keySelector, elementSelector, durationSelector, subjectSelector) { + +var ZipSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ZipSubscriber, _super); + function ZipSubscriber(destination, resultSelector, values) { + if (values === void 0) { + values = Object.create(null); + } var _this = _super.call(this, destination) || this; - _this.keySelector = keySelector; - _this.elementSelector = elementSelector; - _this.durationSelector = durationSelector; - _this.subjectSelector = subjectSelector; - _this.groups = null; - _this.attemptedToUnsubscribe = false; - _this.count = 0; + _this.iterators = []; + _this.active = 0; + _this.resultSelector = (typeof resultSelector === 'function') ? resultSelector : null; + _this.values = values; return _this; } - GroupBySubscriber.prototype._next = function (value) { - var key; - try { - key = this.keySelector(value); + ZipSubscriber.prototype._next = function (value) { + var iterators = this.iterators; + if (Object(_util_isArray__WEBPACK_IMPORTED_MODULE_2__["isArray"])(value)) { + iterators.push(new StaticArrayIterator(value)); } - catch (err) { - this.error(err); - return; + else if (typeof value[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__["iterator"]] === 'function') { + iterators.push(new StaticIterator(value[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__["iterator"]]())); + } + else { + iterators.push(new ZipBufferIterator(this.destination, this, value)); } - this._group(value, key); }; - GroupBySubscriber.prototype._group = function (value, key) { - var groups = this.groups; - if (!groups) { - groups = this.groups = new Map(); + ZipSubscriber.prototype._complete = function () { + var iterators = this.iterators; + var len = iterators.length; + this.unsubscribe(); + if (len === 0) { + this.destination.complete(); + return; } - var group = groups.get(key); - var element; - if (this.elementSelector) { - try { - element = this.elementSelector(value); + this.active = len; + for (var i = 0; i < len; i++) { + var iterator = iterators[i]; + if (iterator.stillUnsubscribed) { + var destination = this.destination; + destination.add(iterator.subscribe(iterator, i)); } - catch (err) { - this.error(err); + else { + this.active--; } } - else { - element = value; + }; + ZipSubscriber.prototype.notifyInactive = function () { + this.active--; + if (this.active === 0) { + this.destination.complete(); } - if (!group) { - group = (this.subjectSelector ? this.subjectSelector() : new _Subject__WEBPACK_IMPORTED_MODULE_4__["Subject"]()); - groups.set(key, group); - var groupedObservable = new GroupedObservable(key, group, this); - this.destination.next(groupedObservable); - if (this.durationSelector) { - var duration = void 0; - try { - duration = this.durationSelector(new GroupedObservable(key, group)); - } - catch (err) { - this.error(err); - return; - } - this.add(duration.subscribe(new GroupDurationSubscriber(key, group, this))); + }; + ZipSubscriber.prototype.checkIterators = function () { + var iterators = this.iterators; + var len = iterators.length; + var destination = this.destination; + for (var i = 0; i < len; i++) { + var iterator = iterators[i]; + if (typeof iterator.hasValue === 'function' && !iterator.hasValue()) { + return; } } - if (!group.closed) { - group.next(element); + var shouldComplete = false; + var args = []; + for (var i = 0; i < len; i++) { + var iterator = iterators[i]; + var result = iterator.next(); + if (iterator.hasCompleted()) { + shouldComplete = true; + } + if (result.done) { + destination.complete(); + return; + } + args.push(result.value); } - }; - GroupBySubscriber.prototype._error = function (err) { - var groups = this.groups; - if (groups) { - groups.forEach(function (group, key) { - group.error(err); - }); - groups.clear(); + if (this.resultSelector) { + this._tryresultSelector(args); } - this.destination.error(err); - }; - GroupBySubscriber.prototype._complete = function () { - var groups = this.groups; - if (groups) { - groups.forEach(function (group, key) { - group.complete(); - }); - groups.clear(); + else { + destination.next(args); + } + if (shouldComplete) { + destination.complete(); } - this.destination.complete(); - }; - GroupBySubscriber.prototype.removeGroup = function (key) { - this.groups.delete(key); }; - GroupBySubscriber.prototype.unsubscribe = function () { - if (!this.closed) { - this.attemptedToUnsubscribe = true; - if (this.count === 0) { - _super.prototype.unsubscribe.call(this); - } + ZipSubscriber.prototype._tryresultSelector = function (args) { + var result; + try { + result = this.resultSelector.apply(this, args); + } + catch (err) { + this.destination.error(err); + return; } + this.destination.next(result); }; - return GroupBySubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -var GroupDurationSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](GroupDurationSubscriber, _super); - function GroupDurationSubscriber(key, group, parent) { - var _this = _super.call(this, group) || this; - _this.key = key; - _this.group = group; - _this.parent = parent; - return _this; + return ZipSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__["Subscriber"])); + +var StaticIterator = /*@__PURE__*/ (function () { + function StaticIterator(iterator) { + this.iterator = iterator; + this.nextResult = iterator.next(); } - GroupDurationSubscriber.prototype._next = function (value) { - this.complete(); + StaticIterator.prototype.hasValue = function () { + return true; }; - GroupDurationSubscriber.prototype._unsubscribe = function () { - var _a = this, parent = _a.parent, key = _a.key; - this.key = this.parent = null; - if (parent) { - parent.removeGroup(key); - } + StaticIterator.prototype.next = function () { + var result = this.nextResult; + this.nextResult = this.iterator.next(); + return result; }; - return GroupDurationSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -var GroupedObservable = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](GroupedObservable, _super); - function GroupedObservable(key, groupSubject, refCountSubscription) { - var _this = _super.call(this) || this; - _this.key = key; - _this.groupSubject = groupSubject; - _this.refCountSubscription = refCountSubscription; - return _this; + StaticIterator.prototype.hasCompleted = function () { + var nextResult = this.nextResult; + return nextResult && nextResult.done; + }; + return StaticIterator; +}()); +var StaticArrayIterator = /*@__PURE__*/ (function () { + function StaticArrayIterator(array) { + this.array = array; + this.index = 0; + this.length = 0; + this.length = array.length; } - GroupedObservable.prototype._subscribe = function (subscriber) { - var subscription = new _Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"](); - var _a = this, refCountSubscription = _a.refCountSubscription, groupSubject = _a.groupSubject; - if (refCountSubscription && !refCountSubscription.closed) { - subscription.add(new InnerRefCountSubscription(refCountSubscription)); - } - subscription.add(groupSubject.subscribe(subscriber)); - return subscription; + StaticArrayIterator.prototype[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__["iterator"]] = function () { + return this; }; - return GroupedObservable; -}(_Observable__WEBPACK_IMPORTED_MODULE_3__["Observable"])); - -var InnerRefCountSubscription = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](InnerRefCountSubscription, _super); - function InnerRefCountSubscription(parent) { - var _this = _super.call(this) || this; + StaticArrayIterator.prototype.next = function (value) { + var i = this.index++; + var array = this.array; + return i < this.length ? { value: array[i], done: false } : { value: null, done: true }; + }; + StaticArrayIterator.prototype.hasValue = function () { + return this.array.length > this.index; + }; + StaticArrayIterator.prototype.hasCompleted = function () { + return this.array.length === this.index; + }; + return StaticArrayIterator; +}()); +var ZipBufferIterator = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ZipBufferIterator, _super); + function ZipBufferIterator(destination, parent, observable) { + var _this = _super.call(this, destination) || this; _this.parent = parent; - parent.count++; + _this.observable = observable; + _this.stillUnsubscribed = true; + _this.buffer = []; + _this.isComplete = false; return _this; } - InnerRefCountSubscription.prototype.unsubscribe = function () { - var parent = this.parent; - if (!parent.closed && !this.closed) { - _super.prototype.unsubscribe.call(this); - parent.count -= 1; - if (parent.count === 0 && parent.attemptedToUnsubscribe) { - parent.unsubscribe(); - } + ZipBufferIterator.prototype[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__["iterator"]] = function () { + return this; + }; + ZipBufferIterator.prototype.next = function () { + var buffer = this.buffer; + if (buffer.length === 0 && this.isComplete) { + return { value: null, done: true }; + } + else { + return { value: buffer.shift(), done: false }; } }; - return InnerRefCountSubscription; -}(_Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"])); -//# sourceMappingURL=groupBy.js.map + ZipBufferIterator.prototype.hasValue = function () { + return this.buffer.length > 0; + }; + ZipBufferIterator.prototype.hasCompleted = function () { + return this.buffer.length === 0 && this.isComplete; + }; + ZipBufferIterator.prototype.notifyComplete = function () { + if (this.buffer.length > 0) { + this.isComplete = true; + this.parent.notifyInactive(); + } + else { + this.destination.complete(); + } + }; + ZipBufferIterator.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.buffer.push(innerValue); + this.parent.checkIterators(); + }; + ZipBufferIterator.prototype.subscribe = function (value, index) { + return Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_5__["subscribeToResult"])(this, this.observable, this, index); + }; + return ZipBufferIterator; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_4__["OuterSubscriber"])); +//# sourceMappingURL=zip.js.map /***/ }), -/* 192 */ +/* 241 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BehaviorSubject", function() { return BehaviorSubject; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(187); -/* harmony import */ var _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(188); -/** PURE_IMPORTS_START tslib,_Subject,_util_ObjectUnsubscribedError PURE_IMPORTS_END */ +/* harmony import */ var _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(242); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "audit", function() { return _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__["audit"]; }); +/* harmony import */ var _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(243); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "auditTime", function() { return _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__["auditTime"]; }); +/* harmony import */ var _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(244); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buffer", function() { return _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__["buffer"]; }); -var BehaviorSubject = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BehaviorSubject, _super); - function BehaviorSubject(_value) { - var _this = _super.call(this) || this; - _this._value = _value; - return _this; - } - Object.defineProperty(BehaviorSubject.prototype, "value", { - get: function () { - return this.getValue(); - }, - enumerable: true, - configurable: true - }); - BehaviorSubject.prototype._subscribe = function (subscriber) { - var subscription = _super.prototype._subscribe.call(this, subscriber); - if (subscription && !subscription.closed) { - subscriber.next(this._value); - } - return subscription; - }; - BehaviorSubject.prototype.getValue = function () { - if (this.hasError) { - throw this.thrownError; - } - else if (this.closed) { - throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_2__["ObjectUnsubscribedError"](); - } - else { - return this._value; - } - }; - BehaviorSubject.prototype.next = function (value) { - _super.prototype.next.call(this, this._value = value); - }; - return BehaviorSubject; -}(_Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"])); +/* harmony import */ var _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(245); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferCount", function() { return _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__["bufferCount"]; }); -//# sourceMappingURL=BehaviorSubject.js.map +/* harmony import */ var _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(246); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferTime", function() { return _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__["bufferTime"]; }); +/* harmony import */ var _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(247); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferToggle", function() { return _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__["bufferToggle"]; }); -/***/ }), -/* 193 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony import */ var _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(248); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferWhen", function() { return _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__["bufferWhen"]; }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ReplaySubject", function() { return ReplaySubject; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(187); -/* harmony import */ var _scheduler_queue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(194); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(177); -/* harmony import */ var _operators_observeOn__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(201); -/* harmony import */ var _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(188); -/* harmony import */ var _SubjectSubscription__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(189); -/** PURE_IMPORTS_START tslib,_Subject,_scheduler_queue,_Subscription,_operators_observeOn,_util_ObjectUnsubscribedError,_SubjectSubscription PURE_IMPORTS_END */ +/* harmony import */ var _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(249); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "catchError", function() { return _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__["catchError"]; }); +/* harmony import */ var _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(250); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineAll", function() { return _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__["combineAll"]; }); +/* harmony import */ var _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(251); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__["combineLatest"]; }); +/* harmony import */ var _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(252); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__["concat"]; }); +/* harmony import */ var _internal_operators_concatAll__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(211); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatAll", function() { return _internal_operators_concatAll__WEBPACK_IMPORTED_MODULE_11__["concatAll"]; }); +/* harmony import */ var _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(253); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMap", function() { return _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__["concatMap"]; }); +/* harmony import */ var _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(254); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMapTo", function() { return _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__["concatMapTo"]; }); -var ReplaySubject = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ReplaySubject, _super); - function ReplaySubject(bufferSize, windowTime, scheduler) { - if (bufferSize === void 0) { - bufferSize = Number.POSITIVE_INFINITY; - } - if (windowTime === void 0) { - windowTime = Number.POSITIVE_INFINITY; - } - var _this = _super.call(this) || this; - _this.scheduler = scheduler; - _this._events = []; - _this._infiniteTimeWindow = false; - _this._bufferSize = bufferSize < 1 ? 1 : bufferSize; - _this._windowTime = windowTime < 1 ? 1 : windowTime; - if (windowTime === Number.POSITIVE_INFINITY) { - _this._infiniteTimeWindow = true; - _this.next = _this.nextInfiniteTimeWindow; - } - else { - _this.next = _this.nextTimeWindow; - } - return _this; - } - ReplaySubject.prototype.nextInfiniteTimeWindow = function (value) { - var _events = this._events; - _events.push(value); - if (_events.length > this._bufferSize) { - _events.shift(); - } - _super.prototype.next.call(this, value); - }; - ReplaySubject.prototype.nextTimeWindow = function (value) { - this._events.push(new ReplayEvent(this._getNow(), value)); - this._trimBufferThenGetEvents(); - _super.prototype.next.call(this, value); - }; - ReplaySubject.prototype._subscribe = function (subscriber) { - var _infiniteTimeWindow = this._infiniteTimeWindow; - var _events = _infiniteTimeWindow ? this._events : this._trimBufferThenGetEvents(); - var scheduler = this.scheduler; - var len = _events.length; - var subscription; - if (this.closed) { - throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_5__["ObjectUnsubscribedError"](); - } - else if (this.isStopped || this.hasError) { - subscription = _Subscription__WEBPACK_IMPORTED_MODULE_3__["Subscription"].EMPTY; - } - else { - this.observers.push(subscriber); - subscription = new _SubjectSubscription__WEBPACK_IMPORTED_MODULE_6__["SubjectSubscription"](this, subscriber); - } - if (scheduler) { - subscriber.add(subscriber = new _operators_observeOn__WEBPACK_IMPORTED_MODULE_4__["ObserveOnSubscriber"](subscriber, scheduler)); - } - if (_infiniteTimeWindow) { - for (var i = 0; i < len && !subscriber.closed; i++) { - subscriber.next(_events[i]); - } - } - else { - for (var i = 0; i < len && !subscriber.closed; i++) { - subscriber.next(_events[i].value); - } - } - if (this.hasError) { - subscriber.error(this.thrownError); - } - else if (this.isStopped) { - subscriber.complete(); - } - return subscription; - }; - ReplaySubject.prototype._getNow = function () { - return (this.scheduler || _scheduler_queue__WEBPACK_IMPORTED_MODULE_2__["queue"]).now(); - }; - ReplaySubject.prototype._trimBufferThenGetEvents = function () { - var now = this._getNow(); - var _bufferSize = this._bufferSize; - var _windowTime = this._windowTime; - var _events = this._events; - var eventsCount = _events.length; - var spliceCount = 0; - while (spliceCount < eventsCount) { - if ((now - _events[spliceCount].time) < _windowTime) { - break; - } - spliceCount++; - } - if (eventsCount > _bufferSize) { - spliceCount = Math.max(spliceCount, eventsCount - _bufferSize); - } - if (spliceCount > 0) { - _events.splice(0, spliceCount); - } - return _events; - }; - return ReplaySubject; -}(_Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"])); +/* harmony import */ var _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(255); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "count", function() { return _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__["count"]; }); -var ReplayEvent = /*@__PURE__*/ (function () { - function ReplayEvent(time, value) { - this.time = time; - this.value = value; - } - return ReplayEvent; -}()); -//# sourceMappingURL=ReplaySubject.js.map +/* harmony import */ var _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(256); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "debounce", function() { return _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__["debounce"]; }); +/* harmony import */ var _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(257); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "debounceTime", function() { return _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__["debounceTime"]; }); -/***/ }), -/* 194 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony import */ var _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(258); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "defaultIfEmpty", function() { return _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__["defaultIfEmpty"]; }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "queue", function() { return queue; }); -/* harmony import */ var _QueueAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(195); -/* harmony import */ var _QueueScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(198); -/** PURE_IMPORTS_START _QueueAction,_QueueScheduler PURE_IMPORTS_END */ +/* harmony import */ var _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(259); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delay", function() { return _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__["delay"]; }); +/* harmony import */ var _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(261); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delayWhen", function() { return _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__["delayWhen"]; }); -var queue = /*@__PURE__*/ new _QueueScheduler__WEBPACK_IMPORTED_MODULE_1__["QueueScheduler"](_QueueAction__WEBPACK_IMPORTED_MODULE_0__["QueueAction"]); -//# sourceMappingURL=queue.js.map +/* harmony import */ var _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(262); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "dematerialize", function() { return _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__["dematerialize"]; }); +/* harmony import */ var _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(263); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinct", function() { return _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__["distinct"]; }); -/***/ }), -/* 195 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony import */ var _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(264); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilChanged", function() { return _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__["distinctUntilChanged"]; }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "QueueAction", function() { return QueueAction; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(196); -/** PURE_IMPORTS_START tslib,_AsyncAction PURE_IMPORTS_END */ +/* harmony import */ var _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(265); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilKeyChanged", function() { return _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__["distinctUntilKeyChanged"]; }); +/* harmony import */ var _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(266); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "elementAt", function() { return _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__["elementAt"]; }); -var QueueAction = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](QueueAction, _super); - function QueueAction(scheduler, work) { - var _this = _super.call(this, scheduler, work) || this; - _this.scheduler = scheduler; - _this.work = work; - return _this; - } - QueueAction.prototype.schedule = function (state, delay) { - if (delay === void 0) { - delay = 0; - } - if (delay > 0) { - return _super.prototype.schedule.call(this, state, delay); - } - this.delay = delay; - this.state = state; - this.scheduler.flush(this); - return this; - }; - QueueAction.prototype.execute = function (state, delay) { - return (delay > 0 || this.closed) ? - _super.prototype.execute.call(this, state, delay) : - this._execute(state, delay); - }; - QueueAction.prototype.requestAsyncId = function (scheduler, id, delay) { - if (delay === void 0) { - delay = 0; - } - if ((delay !== null && delay > 0) || (delay === null && this.delay > 0)) { - return _super.prototype.requestAsyncId.call(this, scheduler, id, delay); - } - return scheduler.flush(this); - }; - return QueueAction; -}(_AsyncAction__WEBPACK_IMPORTED_MODULE_1__["AsyncAction"])); +/* harmony import */ var _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(269); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "endWith", function() { return _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__["endWith"]; }); -//# sourceMappingURL=QueueAction.js.map +/* harmony import */ var _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(270); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "every", function() { return _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__["every"]; }); +/* harmony import */ var _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(271); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaust", function() { return _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__["exhaust"]; }); -/***/ }), -/* 196 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony import */ var _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(272); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaustMap", function() { return _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__["exhaustMap"]; }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AsyncAction", function() { return AsyncAction; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Action__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(197); -/** PURE_IMPORTS_START tslib,_Action PURE_IMPORTS_END */ +/* harmony import */ var _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(273); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "expand", function() { return _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__["expand"]; }); +/* harmony import */ var _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(235); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "filter", function() { return _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__["filter"]; }); -var AsyncAction = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AsyncAction, _super); - function AsyncAction(scheduler, work) { - var _this = _super.call(this, scheduler, work) || this; - _this.scheduler = scheduler; - _this.work = work; - _this.pending = false; - return _this; - } - AsyncAction.prototype.schedule = function (state, delay) { - if (delay === void 0) { - delay = 0; - } - if (this.closed) { - return this; - } - this.state = state; - var id = this.id; - var scheduler = this.scheduler; - if (id != null) { - this.id = this.recycleAsyncId(scheduler, id, delay); - } - this.pending = true; - this.delay = delay; - this.id = this.id || this.requestAsyncId(scheduler, this.id, delay); - return this; - }; - AsyncAction.prototype.requestAsyncId = function (scheduler, id, delay) { - if (delay === void 0) { - delay = 0; - } - return setInterval(scheduler.flush.bind(scheduler, this), delay); - }; - AsyncAction.prototype.recycleAsyncId = function (scheduler, id, delay) { - if (delay === void 0) { - delay = 0; - } - if (delay !== null && this.delay === delay && this.pending === false) { - return id; - } - clearInterval(id); - return undefined; - }; - AsyncAction.prototype.execute = function (state, delay) { - if (this.closed) { - return new Error('executing a cancelled action'); - } - this.pending = false; - var error = this._execute(state, delay); - if (error) { - return error; - } - else if (this.pending === false && this.id != null) { - this.id = this.recycleAsyncId(this.scheduler, this.id, null); - } - }; - AsyncAction.prototype._execute = function (state, delay) { - var errored = false; - var errorValue = undefined; - try { - this.work(state); - } - catch (e) { - errored = true; - errorValue = !!e && e || new Error(e); - } - if (errored) { - this.unsubscribe(); - return errorValue; - } - }; - AsyncAction.prototype._unsubscribe = function () { - var id = this.id; - var scheduler = this.scheduler; - var actions = scheduler.actions; - var index = actions.indexOf(this); - this.work = null; - this.state = null; - this.pending = false; - this.scheduler = null; - if (index !== -1) { - actions.splice(index, 1); - } - if (id != null) { - this.id = this.recycleAsyncId(scheduler, id, null); - } - this.delay = null; - }; - return AsyncAction; -}(_Action__WEBPACK_IMPORTED_MODULE_1__["Action"])); +/* harmony import */ var _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(274); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "finalize", function() { return _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__["finalize"]; }); -//# sourceMappingURL=AsyncAction.js.map +/* harmony import */ var _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(275); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "find", function() { return _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__["find"]; }); +/* harmony import */ var _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(276); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "findIndex", function() { return _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__["findIndex"]; }); -/***/ }), -/* 197 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony import */ var _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(277); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "first", function() { return _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__["first"]; }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Action", function() { return Action; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(177); -/** PURE_IMPORTS_START tslib,_Subscription PURE_IMPORTS_END */ +/* harmony import */ var _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(162); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "groupBy", function() { return _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_35__["groupBy"]; }); +/* harmony import */ var _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(278); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ignoreElements", function() { return _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__["ignoreElements"]; }); -var Action = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](Action, _super); - function Action(scheduler, work) { - return _super.call(this) || this; - } - Action.prototype.schedule = function (state, delay) { - if (delay === void 0) { - delay = 0; - } - return this; - }; - return Action; -}(_Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"])); +/* harmony import */ var _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(279); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "isEmpty", function() { return _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__["isEmpty"]; }); -//# sourceMappingURL=Action.js.map +/* harmony import */ var _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(280); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "last", function() { return _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__["last"]; }); +/* harmony import */ var _internal_operators_map__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(197); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "map", function() { return _internal_operators_map__WEBPACK_IMPORTED_MODULE_39__["map"]; }); -/***/ }), -/* 198 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony import */ var _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(282); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mapTo", function() { return _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__["mapTo"]; }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "QueueScheduler", function() { return QueueScheduler; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(199); -/** PURE_IMPORTS_START tslib,_AsyncScheduler PURE_IMPORTS_END */ +/* harmony import */ var _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(283); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "materialize", function() { return _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__["materialize"]; }); +/* harmony import */ var _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(284); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "max", function() { return _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__["max"]; }); -var QueueScheduler = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](QueueScheduler, _super); - function QueueScheduler() { - return _super !== null && _super.apply(this, arguments) || this; - } - return QueueScheduler; -}(_AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__["AsyncScheduler"])); +/* harmony import */ var _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(287); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__["merge"]; }); -//# sourceMappingURL=QueueScheduler.js.map +/* harmony import */ var _internal_operators_mergeAll__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(212); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeAll", function() { return _internal_operators_mergeAll__WEBPACK_IMPORTED_MODULE_44__["mergeAll"]; }); +/* harmony import */ var _internal_operators_mergeMap__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(213); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeMap", function() { return _internal_operators_mergeMap__WEBPACK_IMPORTED_MODULE_45__["mergeMap"]; }); -/***/ }), -/* 199 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "flatMap", function() { return _internal_operators_mergeMap__WEBPACK_IMPORTED_MODULE_45__["mergeMap"]; }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AsyncScheduler", function() { return AsyncScheduler; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Scheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(200); -/** PURE_IMPORTS_START tslib,_Scheduler PURE_IMPORTS_END */ +/* harmony import */ var _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(288); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeMapTo", function() { return _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__["mergeMapTo"]; }); +/* harmony import */ var _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(289); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeScan", function() { return _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__["mergeScan"]; }); -var AsyncScheduler = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AsyncScheduler, _super); - function AsyncScheduler(SchedulerAction, now) { - if (now === void 0) { - now = _Scheduler__WEBPACK_IMPORTED_MODULE_1__["Scheduler"].now; - } - var _this = _super.call(this, SchedulerAction, function () { - if (AsyncScheduler.delegate && AsyncScheduler.delegate !== _this) { - return AsyncScheduler.delegate.now(); - } - else { - return now(); - } - }) || this; - _this.actions = []; - _this.active = false; - _this.scheduled = undefined; - return _this; - } - AsyncScheduler.prototype.schedule = function (work, delay, state) { - if (delay === void 0) { - delay = 0; - } - if (AsyncScheduler.delegate && AsyncScheduler.delegate !== this) { - return AsyncScheduler.delegate.schedule(work, delay, state); - } - else { - return _super.prototype.schedule.call(this, work, delay, state); - } - }; - AsyncScheduler.prototype.flush = function (action) { - var actions = this.actions; - if (this.active) { - actions.push(action); - return; - } - var error; - this.active = true; - do { - if (error = action.execute(action.state, action.delay)) { - break; - } - } while (action = actions.shift()); - this.active = false; - if (error) { - while (action = actions.shift()) { - action.unsubscribe(); - } - throw error; - } - }; - return AsyncScheduler; -}(_Scheduler__WEBPACK_IMPORTED_MODULE_1__["Scheduler"])); +/* harmony import */ var _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(290); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "min", function() { return _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__["min"]; }); -//# sourceMappingURL=AsyncScheduler.js.map +/* harmony import */ var _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(291); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "multicast", function() { return _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__["multicast"]; }); +/* harmony import */ var _internal_operators_observeOn__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(172); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "observeOn", function() { return _internal_operators_observeOn__WEBPACK_IMPORTED_MODULE_50__["observeOn"]; }); -/***/ }), -/* 200 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony import */ var _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(292); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__["onErrorResumeNext"]; }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Scheduler", function() { return Scheduler; }); -var Scheduler = /*@__PURE__*/ (function () { - function Scheduler(SchedulerAction, now) { - if (now === void 0) { - now = Scheduler.now; - } - this.SchedulerAction = SchedulerAction; - this.now = now; - } - Scheduler.prototype.schedule = function (work, delay, state) { - if (delay === void 0) { - delay = 0; - } - return new this.SchedulerAction(this, work).schedule(state, delay); - }; - Scheduler.now = function () { return Date.now(); }; - return Scheduler; -}()); +/* harmony import */ var _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(293); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pairwise", function() { return _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__["pairwise"]; }); -//# sourceMappingURL=Scheduler.js.map +/* harmony import */ var _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(294); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__["partition"]; }); +/* harmony import */ var _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(295); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pluck", function() { return _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__["pluck"]; }); -/***/ }), -/* 201 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony import */ var _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(296); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publish", function() { return _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__["publish"]; }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "observeOn", function() { return observeOn; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ObserveOnOperator", function() { return ObserveOnOperator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ObserveOnSubscriber", function() { return ObserveOnSubscriber; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ObserveOnMessage", function() { return ObserveOnMessage; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/* harmony import */ var _Notification__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(202); -/** PURE_IMPORTS_START tslib,_Subscriber,_Notification PURE_IMPORTS_END */ +/* harmony import */ var _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(297); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishBehavior", function() { return _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__["publishBehavior"]; }); +/* harmony import */ var _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(298); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishLast", function() { return _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__["publishLast"]; }); +/* harmony import */ var _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(299); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishReplay", function() { return _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__["publishReplay"]; }); -function observeOn(scheduler, delay) { - if (delay === void 0) { - delay = 0; - } - return function observeOnOperatorFunction(source) { - return source.lift(new ObserveOnOperator(scheduler, delay)); - }; -} -var ObserveOnOperator = /*@__PURE__*/ (function () { - function ObserveOnOperator(scheduler, delay) { - if (delay === void 0) { - delay = 0; - } - this.scheduler = scheduler; - this.delay = delay; - } - ObserveOnOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ObserveOnSubscriber(subscriber, this.scheduler, this.delay)); - }; - return ObserveOnOperator; -}()); +/* harmony import */ var _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(300); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "race", function() { return _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__["race"]; }); -var ObserveOnSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ObserveOnSubscriber, _super); - function ObserveOnSubscriber(destination, scheduler, delay) { - if (delay === void 0) { - delay = 0; - } - var _this = _super.call(this, destination) || this; - _this.scheduler = scheduler; - _this.delay = delay; - return _this; - } - ObserveOnSubscriber.dispatch = function (arg) { - var notification = arg.notification, destination = arg.destination; - notification.observe(destination); - this.unsubscribe(); - }; - ObserveOnSubscriber.prototype.scheduleMessage = function (notification) { - var destination = this.destination; - destination.add(this.scheduler.schedule(ObserveOnSubscriber.dispatch, this.delay, new ObserveOnMessage(notification, this.destination))); - }; - ObserveOnSubscriber.prototype._next = function (value) { - this.scheduleMessage(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createNext(value)); - }; - ObserveOnSubscriber.prototype._error = function (err) { - this.scheduleMessage(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createError(err)); - this.unsubscribe(); - }; - ObserveOnSubscriber.prototype._complete = function () { - this.scheduleMessage(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createComplete()); - this.unsubscribe(); - }; - return ObserveOnSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +/* harmony import */ var _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(285); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__["reduce"]; }); -var ObserveOnMessage = /*@__PURE__*/ (function () { - function ObserveOnMessage(notification, destination) { - this.notification = notification; - this.destination = destination; - } - return ObserveOnMessage; -}()); +/* harmony import */ var _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(301); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeat", function() { return _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__["repeat"]; }); -//# sourceMappingURL=observeOn.js.map +/* harmony import */ var _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(302); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeatWhen", function() { return _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__["repeatWhen"]; }); +/* harmony import */ var _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(303); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retry", function() { return _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__["retry"]; }); -/***/ }), -/* 202 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony import */ var _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(304); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retryWhen", function() { return _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__["retryWhen"]; }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NotificationKind", function() { return NotificationKind; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Notification", function() { return Notification; }); -/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(203); -/* harmony import */ var _observable_of__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(204); -/* harmony import */ var _observable_throwError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(209); -/** PURE_IMPORTS_START _observable_empty,_observable_of,_observable_throwError PURE_IMPORTS_END */ +/* harmony import */ var _internal_operators_refCount__WEBPACK_IMPORTED_MODULE_65__ = __webpack_require__(161); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "refCount", function() { return _internal_operators_refCount__WEBPACK_IMPORTED_MODULE_65__["refCount"]; }); +/* harmony import */ var _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(305); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sample", function() { return _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__["sample"]; }); +/* harmony import */ var _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(306); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sampleTime", function() { return _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__["sampleTime"]; }); -var NotificationKind; -/*@__PURE__*/ (function (NotificationKind) { - NotificationKind["NEXT"] = "N"; - NotificationKind["ERROR"] = "E"; - NotificationKind["COMPLETE"] = "C"; -})(NotificationKind || (NotificationKind = {})); -var Notification = /*@__PURE__*/ (function () { - function Notification(kind, value, error) { - this.kind = kind; - this.value = value; - this.error = error; - this.hasValue = kind === 'N'; - } - Notification.prototype.observe = function (observer) { - switch (this.kind) { - case 'N': - return observer.next && observer.next(this.value); - case 'E': - return observer.error && observer.error(this.error); - case 'C': - return observer.complete && observer.complete(); - } - }; - Notification.prototype.do = function (next, error, complete) { - var kind = this.kind; - switch (kind) { - case 'N': - return next && next(this.value); - case 'E': - return error && error(this.error); - case 'C': - return complete && complete(); - } - }; - Notification.prototype.accept = function (nextOrObserver, error, complete) { - if (nextOrObserver && typeof nextOrObserver.next === 'function') { - return this.observe(nextOrObserver); - } - else { - return this.do(nextOrObserver, error, complete); - } - }; - Notification.prototype.toObservable = function () { - var kind = this.kind; - switch (kind) { - case 'N': - return Object(_observable_of__WEBPACK_IMPORTED_MODULE_1__["of"])(this.value); - case 'E': - return Object(_observable_throwError__WEBPACK_IMPORTED_MODULE_2__["throwError"])(this.error); - case 'C': - return Object(_observable_empty__WEBPACK_IMPORTED_MODULE_0__["empty"])(); - } - throw new Error('unexpected notification kind value'); - }; - Notification.createNext = function (value) { - if (typeof value !== 'undefined') { - return new Notification('N', value); - } - return Notification.undefinedValueNotification; - }; - Notification.createError = function (err) { - return new Notification('E', undefined, err); - }; - Notification.createComplete = function () { - return Notification.completeNotification; - }; - Notification.completeNotification = new Notification('C'); - Notification.undefinedValueNotification = new Notification('N', undefined); - return Notification; -}()); +/* harmony import */ var _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(286); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "scan", function() { return _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__["scan"]; }); -//# sourceMappingURL=Notification.js.map +/* harmony import */ var _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(307); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sequenceEqual", function() { return _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__["sequenceEqual"]; }); +/* harmony import */ var _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(308); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "share", function() { return _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__["share"]; }); -/***/ }), -/* 203 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony import */ var _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(309); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "shareReplay", function() { return _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__["shareReplay"]; }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EMPTY", function() { return EMPTY; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "empty", function() { return empty; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ +/* harmony import */ var _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(310); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "single", function() { return _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__["single"]; }); -var EMPTY = /*@__PURE__*/ new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { return subscriber.complete(); }); -function empty(scheduler) { - return scheduler ? emptyScheduled(scheduler) : EMPTY; -} -function emptyScheduled(scheduler) { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { return scheduler.schedule(function () { return subscriber.complete(); }); }); -} -//# sourceMappingURL=empty.js.map +/* harmony import */ var _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__ = __webpack_require__(311); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skip", function() { return _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__["skip"]; }); +/* harmony import */ var _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__ = __webpack_require__(312); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipLast", function() { return _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__["skipLast"]; }); -/***/ }), -/* 204 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony import */ var _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__ = __webpack_require__(313); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipUntil", function() { return _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__["skipUntil"]; }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "of", function() { return of; }); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(205); -/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(206); -/* harmony import */ var _scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(208); -/** PURE_IMPORTS_START _util_isScheduler,_fromArray,_scheduled_scheduleArray PURE_IMPORTS_END */ +/* harmony import */ var _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__ = __webpack_require__(314); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipWhile", function() { return _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__["skipWhile"]; }); +/* harmony import */ var _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__ = __webpack_require__(315); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "startWith", function() { return _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__["startWith"]; }); +/* harmony import */ var _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__ = __webpack_require__(316); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__["subscribeOn"]; }); -function of() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var scheduler = args[args.length - 1]; - if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_0__["isScheduler"])(scheduler)) { - args.pop(); - return Object(_scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_2__["scheduleArray"])(args, scheduler); - } - else { - return Object(_fromArray__WEBPACK_IMPORTED_MODULE_1__["fromArray"])(args); - } -} -//# sourceMappingURL=of.js.map +/* harmony import */ var _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__ = __webpack_require__(318); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__["switchAll"]; }); +/* harmony import */ var _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__ = __webpack_require__(319); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMap", function() { return _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__["switchMap"]; }); -/***/ }), -/* 205 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony import */ var _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__ = __webpack_require__(320); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__["switchMapTo"]; }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isScheduler", function() { return isScheduler; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function isScheduler(value) { - return value && typeof value.schedule === 'function'; -} -//# sourceMappingURL=isScheduler.js.map +/* harmony import */ var _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__ = __webpack_require__(268); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "take", function() { return _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__["take"]; }); +/* harmony import */ var _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__ = __webpack_require__(281); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeLast", function() { return _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__["takeLast"]; }); -/***/ }), -/* 206 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony import */ var _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__ = __webpack_require__(321); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeUntil", function() { return _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__["takeUntil"]; }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fromArray", function() { return fromArray; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _util_subscribeToArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(207); -/* harmony import */ var _scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(208); -/** PURE_IMPORTS_START _Observable,_util_subscribeToArray,_scheduled_scheduleArray PURE_IMPORTS_END */ +/* harmony import */ var _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__ = __webpack_require__(322); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeWhile", function() { return _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__["takeWhile"]; }); +/* harmony import */ var _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__ = __webpack_require__(323); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "tap", function() { return _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__["tap"]; }); +/* harmony import */ var _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__ = __webpack_require__(324); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttle", function() { return _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__["throttle"]; }); -function fromArray(input, scheduler) { - if (!scheduler) { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](Object(_util_subscribeToArray__WEBPACK_IMPORTED_MODULE_1__["subscribeToArray"])(input)); - } - else { - return Object(_scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_2__["scheduleArray"])(input, scheduler); - } -} -//# sourceMappingURL=fromArray.js.map +/* harmony import */ var _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__ = __webpack_require__(325); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttleTime", function() { return _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__["throttleTime"]; }); +/* harmony import */ var _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__ = __webpack_require__(267); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throwIfEmpty", function() { return _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__["throwIfEmpty"]; }); -/***/ }), -/* 207 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony import */ var _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__ = __webpack_require__(326); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeInterval", function() { return _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__["timeInterval"]; }); + +/* harmony import */ var _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__ = __webpack_require__(327); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__["timeout"]; }); + +/* harmony import */ var _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__ = __webpack_require__(328); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeoutWith", function() { return _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__["timeoutWith"]; }); + +/* harmony import */ var _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__ = __webpack_require__(329); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timestamp", function() { return _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__["timestamp"]; }); + +/* harmony import */ var _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__ = __webpack_require__(330); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__["toArray"]; }); + +/* harmony import */ var _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__ = __webpack_require__(331); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "window", function() { return _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__["window"]; }); + +/* harmony import */ var _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__ = __webpack_require__(332); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowCount", function() { return _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__["windowCount"]; }); + +/* harmony import */ var _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__ = __webpack_require__(333); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowTime", function() { return _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__["windowTime"]; }); + +/* harmony import */ var _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__ = __webpack_require__(334); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowToggle", function() { return _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__["windowToggle"]; }); + +/* harmony import */ var _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__ = __webpack_require__(335); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowWhen", function() { return _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__["windowWhen"]; }); + +/* harmony import */ var _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__ = __webpack_require__(336); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "withLatestFrom", function() { return _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__["withLatestFrom"]; }); + +/* harmony import */ var _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__ = __webpack_require__(337); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__["zip"]; }); + +/* harmony import */ var _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__ = __webpack_require__(338); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zipAll", function() { return _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__["zipAll"]; }); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeToArray", function() { return subscribeToArray; }); /** PURE_IMPORTS_START PURE_IMPORTS_END */ -var subscribeToArray = function (array) { - return function (subscriber) { - for (var i = 0, len = array.length; i < len && !subscriber.closed; i++) { - subscriber.next(array[i]); - } - subscriber.complete(); - }; -}; -//# sourceMappingURL=subscribeToArray.js.map -/***/ }), -/* 208 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scheduleArray", function() { return scheduleArray; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(177); -/** PURE_IMPORTS_START _Observable,_Subscription PURE_IMPORTS_END */ -function scheduleArray(input, scheduler) { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - var sub = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); - var i = 0; - sub.add(scheduler.schedule(function () { - if (i === input.length) { - subscriber.complete(); - return; - } - subscriber.next(input[i++]); - if (!subscriber.closed) { - sub.add(this.schedule()); - } - })); - return sub; - }); -} -//# sourceMappingURL=scheduleArray.js.map -/***/ }), -/* 209 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "throwError", function() { return throwError; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ -function throwError(error, scheduler) { - if (!scheduler) { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { return subscriber.error(error); }); - } - else { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { return scheduler.schedule(dispatch, 0, { error: error, subscriber: subscriber }); }); - } -} -function dispatch(_a) { - var error = _a.error, subscriber = _a.subscriber; - subscriber.error(error); -} -//# sourceMappingURL=throwError.js.map -/***/ }), -/* 210 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AsyncSubject", function() { return AsyncSubject; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(187); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(177); -/** PURE_IMPORTS_START tslib,_Subject,_Subscription PURE_IMPORTS_END */ -var AsyncSubject = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AsyncSubject, _super); - function AsyncSubject() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.value = null; - _this.hasNext = false; - _this.hasCompleted = false; - return _this; - } - AsyncSubject.prototype._subscribe = function (subscriber) { - if (this.hasError) { - subscriber.error(this.thrownError); - return _Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"].EMPTY; - } - else if (this.hasCompleted && this.hasNext) { - subscriber.next(this.value); - subscriber.complete(); - return _Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"].EMPTY; - } - return _super.prototype._subscribe.call(this, subscriber); - }; - AsyncSubject.prototype.next = function (value) { - if (!this.hasCompleted) { - this.value = value; - this.hasNext = true; - } - }; - AsyncSubject.prototype.error = function (error) { - if (!this.hasCompleted) { - _super.prototype.error.call(this, error); - } - }; - AsyncSubject.prototype.complete = function () { - this.hasCompleted = true; - if (this.hasNext) { - _super.prototype.next.call(this, this.value); - } - _super.prototype.complete.call(this); - }; - return AsyncSubject; -}(_Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"])); -//# sourceMappingURL=AsyncSubject.js.map -/***/ }), -/* 211 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "asap", function() { return asap; }); -/* harmony import */ var _AsapAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(212); -/* harmony import */ var _AsapScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(214); -/** PURE_IMPORTS_START _AsapAction,_AsapScheduler PURE_IMPORTS_END */ -var asap = /*@__PURE__*/ new _AsapScheduler__WEBPACK_IMPORTED_MODULE_1__["AsapScheduler"](_AsapAction__WEBPACK_IMPORTED_MODULE_0__["AsapAction"]); -//# sourceMappingURL=asap.js.map -/***/ }), -/* 212 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AsapAction", function() { return AsapAction; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _util_Immediate__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(213); -/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(196); -/** PURE_IMPORTS_START tslib,_util_Immediate,_AsyncAction PURE_IMPORTS_END */ -var AsapAction = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AsapAction, _super); - function AsapAction(scheduler, work) { - var _this = _super.call(this, scheduler, work) || this; - _this.scheduler = scheduler; - _this.work = work; - return _this; - } - AsapAction.prototype.requestAsyncId = function (scheduler, id, delay) { - if (delay === void 0) { - delay = 0; - } - if (delay !== null && delay > 0) { - return _super.prototype.requestAsyncId.call(this, scheduler, id, delay); - } - scheduler.actions.push(this); - return scheduler.scheduled || (scheduler.scheduled = _util_Immediate__WEBPACK_IMPORTED_MODULE_1__["Immediate"].setImmediate(scheduler.flush.bind(scheduler, null))); - }; - AsapAction.prototype.recycleAsyncId = function (scheduler, id, delay) { - if (delay === void 0) { - delay = 0; - } - if ((delay !== null && delay > 0) || (delay === null && this.delay > 0)) { - return _super.prototype.recycleAsyncId.call(this, scheduler, id, delay); - } - if (scheduler.actions.length === 0) { - _util_Immediate__WEBPACK_IMPORTED_MODULE_1__["Immediate"].clearImmediate(id); - scheduler.scheduled = undefined; - } - return undefined; - }; - return AsapAction; -}(_AsyncAction__WEBPACK_IMPORTED_MODULE_2__["AsyncAction"])); -//# sourceMappingURL=AsapAction.js.map -/***/ }), -/* 213 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Immediate", function() { return Immediate; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var nextHandle = 1; -var tasksByHandle = {}; -function runIfPresent(handle) { - var cb = tasksByHandle[handle]; - if (cb) { - cb(); - } -} -var Immediate = { - setImmediate: function (cb) { - var handle = nextHandle++; - tasksByHandle[handle] = cb; - Promise.resolve().then(function () { return runIfPresent(handle); }); - return handle; - }, - clearImmediate: function (handle) { - delete tasksByHandle[handle]; - }, -}; -//# sourceMappingURL=Immediate.js.map -/***/ }), -/* 214 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AsapScheduler", function() { return AsapScheduler; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(199); -/** PURE_IMPORTS_START tslib,_AsyncScheduler PURE_IMPORTS_END */ -var AsapScheduler = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AsapScheduler, _super); - function AsapScheduler() { - return _super !== null && _super.apply(this, arguments) || this; - } - AsapScheduler.prototype.flush = function (action) { - this.active = true; - this.scheduled = undefined; - var actions = this.actions; - var error; - var index = -1; - var count = actions.length; - action = action || actions.shift(); - do { - if (error = action.execute(action.state, action.delay)) { - break; - } - } while (++index < count && (action = actions.shift())); - this.active = false; - if (error) { - while (++index < count && (action = actions.shift())) { - action.unsubscribe(); - } - throw error; - } - }; - return AsapScheduler; -}(_AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__["AsyncScheduler"])); -//# sourceMappingURL=AsapScheduler.js.map -/***/ }), -/* 215 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "async", function() { return async; }); -/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(196); -/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(199); -/** PURE_IMPORTS_START _AsyncAction,_AsyncScheduler PURE_IMPORTS_END */ -var async = /*@__PURE__*/ new _AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__["AsyncScheduler"](_AsyncAction__WEBPACK_IMPORTED_MODULE_0__["AsyncAction"]); -//# sourceMappingURL=async.js.map -/***/ }), -/* 216 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "animationFrame", function() { return animationFrame; }); -/* harmony import */ var _AnimationFrameAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(217); -/* harmony import */ var _AnimationFrameScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(218); -/** PURE_IMPORTS_START _AnimationFrameAction,_AnimationFrameScheduler PURE_IMPORTS_END */ -var animationFrame = /*@__PURE__*/ new _AnimationFrameScheduler__WEBPACK_IMPORTED_MODULE_1__["AnimationFrameScheduler"](_AnimationFrameAction__WEBPACK_IMPORTED_MODULE_0__["AnimationFrameAction"]); -//# sourceMappingURL=animationFrame.js.map -/***/ }), -/* 217 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnimationFrameAction", function() { return AnimationFrameAction; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(196); -/** PURE_IMPORTS_START tslib,_AsyncAction PURE_IMPORTS_END */ -var AnimationFrameAction = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AnimationFrameAction, _super); - function AnimationFrameAction(scheduler, work) { - var _this = _super.call(this, scheduler, work) || this; - _this.scheduler = scheduler; - _this.work = work; - return _this; - } - AnimationFrameAction.prototype.requestAsyncId = function (scheduler, id, delay) { - if (delay === void 0) { - delay = 0; - } - if (delay !== null && delay > 0) { - return _super.prototype.requestAsyncId.call(this, scheduler, id, delay); - } - scheduler.actions.push(this); - return scheduler.scheduled || (scheduler.scheduled = requestAnimationFrame(function () { return scheduler.flush(null); })); - }; - AnimationFrameAction.prototype.recycleAsyncId = function (scheduler, id, delay) { - if (delay === void 0) { - delay = 0; - } - if ((delay !== null && delay > 0) || (delay === null && this.delay > 0)) { - return _super.prototype.recycleAsyncId.call(this, scheduler, id, delay); - } - if (scheduler.actions.length === 0) { - cancelAnimationFrame(id); - scheduler.scheduled = undefined; - } - return undefined; - }; - return AnimationFrameAction; -}(_AsyncAction__WEBPACK_IMPORTED_MODULE_1__["AsyncAction"])); -//# sourceMappingURL=AnimationFrameAction.js.map -/***/ }), -/* 218 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnimationFrameScheduler", function() { return AnimationFrameScheduler; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(199); -/** PURE_IMPORTS_START tslib,_AsyncScheduler PURE_IMPORTS_END */ -var AnimationFrameScheduler = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AnimationFrameScheduler, _super); - function AnimationFrameScheduler() { - return _super !== null && _super.apply(this, arguments) || this; - } - AnimationFrameScheduler.prototype.flush = function (action) { - this.active = true; - this.scheduled = undefined; - var actions = this.actions; - var error; - var index = -1; - var count = actions.length; - action = action || actions.shift(); - do { - if (error = action.execute(action.state, action.delay)) { - break; - } - } while (++index < count && (action = actions.shift())); - this.active = false; - if (error) { - while (++index < count && (action = actions.shift())) { - action.unsubscribe(); - } - throw error; - } - }; - return AnimationFrameScheduler; -}(_AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__["AsyncScheduler"])); -//# sourceMappingURL=AnimationFrameScheduler.js.map + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +//# sourceMappingURL=index.js.map /***/ }), -/* 219 */ +/* 242 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VirtualTimeScheduler", function() { return VirtualTimeScheduler; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VirtualAction", function() { return VirtualAction; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(196); -/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(199); -/** PURE_IMPORTS_START tslib,_AsyncAction,_AsyncScheduler PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "audit", function() { return audit; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -var VirtualTimeScheduler = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VirtualTimeScheduler, _super); - function VirtualTimeScheduler(SchedulerAction, maxFrames) { - if (SchedulerAction === void 0) { - SchedulerAction = VirtualAction; - } - if (maxFrames === void 0) { - maxFrames = Number.POSITIVE_INFINITY; - } - var _this = _super.call(this, SchedulerAction, function () { return _this.frame; }) || this; - _this.maxFrames = maxFrames; - _this.frame = 0; - _this.index = -1; - return _this; +function audit(durationSelector) { + return function auditOperatorFunction(source) { + return source.lift(new AuditOperator(durationSelector)); + }; +} +var AuditOperator = /*@__PURE__*/ (function () { + function AuditOperator(durationSelector) { + this.durationSelector = durationSelector; } - VirtualTimeScheduler.prototype.flush = function () { - var _a = this, actions = _a.actions, maxFrames = _a.maxFrames; - var error, action; - while ((action = actions[0]) && action.delay <= maxFrames) { - actions.shift(); - this.frame = action.delay; - if (error = action.execute(action.state, action.delay)) { - break; - } - } - if (error) { - while (action = actions.shift()) { - action.unsubscribe(); - } - throw error; - } + AuditOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new AuditSubscriber(subscriber, this.durationSelector)); }; - VirtualTimeScheduler.frameTimeFactor = 10; - return VirtualTimeScheduler; -}(_AsyncScheduler__WEBPACK_IMPORTED_MODULE_2__["AsyncScheduler"])); - -var VirtualAction = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VirtualAction, _super); - function VirtualAction(scheduler, work, index) { - if (index === void 0) { - index = scheduler.index += 1; - } - var _this = _super.call(this, scheduler, work) || this; - _this.scheduler = scheduler; - _this.work = work; - _this.index = index; - _this.active = true; - _this.index = scheduler.index = index; + return AuditOperator; +}()); +var AuditSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AuditSubscriber, _super); + function AuditSubscriber(destination, durationSelector) { + var _this = _super.call(this, destination) || this; + _this.durationSelector = durationSelector; + _this.hasValue = false; return _this; } - VirtualAction.prototype.schedule = function (state, delay) { - if (delay === void 0) { - delay = 0; - } - if (!this.id) { - return _super.prototype.schedule.call(this, state, delay); - } - this.active = false; - var action = new VirtualAction(this.scheduler, this.work); - this.add(action); - return action.schedule(state, delay); - }; - VirtualAction.prototype.requestAsyncId = function (scheduler, id, delay) { - if (delay === void 0) { - delay = 0; - } - this.delay = scheduler.frame + delay; - var actions = scheduler.actions; - actions.push(this); - actions.sort(VirtualAction.sortActions); - return true; - }; - VirtualAction.prototype.recycleAsyncId = function (scheduler, id, delay) { - if (delay === void 0) { - delay = 0; - } - return undefined; - }; - VirtualAction.prototype._execute = function (state, delay) { - if (this.active === true) { - return _super.prototype._execute.call(this, state, delay); - } - }; - VirtualAction.sortActions = function (a, b) { - if (a.delay === b.delay) { - if (a.index === b.index) { - return 0; + AuditSubscriber.prototype._next = function (value) { + this.value = value; + this.hasValue = true; + if (!this.throttled) { + var duration = void 0; + try { + var durationSelector = this.durationSelector; + duration = durationSelector(value); } - else if (a.index > b.index) { - return 1; + catch (err) { + return this.destination.error(err); + } + var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, duration); + if (!innerSubscription || innerSubscription.closed) { + this.clearThrottle(); } else { - return -1; + this.add(this.throttled = innerSubscription); } } - else if (a.delay > b.delay) { - return 1; + }; + AuditSubscriber.prototype.clearThrottle = function () { + var _a = this, value = _a.value, hasValue = _a.hasValue, throttled = _a.throttled; + if (throttled) { + this.remove(throttled); + this.throttled = null; + throttled.unsubscribe(); } - else { - return -1; + if (hasValue) { + this.value = null; + this.hasValue = false; + this.destination.next(value); } }; - return VirtualAction; -}(_AsyncAction__WEBPACK_IMPORTED_MODULE_1__["AsyncAction"])); - -//# sourceMappingURL=VirtualTimeScheduler.js.map + AuditSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex) { + this.clearThrottle(); + }; + AuditSubscriber.prototype.notifyComplete = function () { + this.clearThrottle(); + }; + return AuditSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +//# sourceMappingURL=audit.js.map /***/ }), -/* 220 */ +/* 243 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "identity", function() { return identity; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function identity(x) { - return x; -} -//# sourceMappingURL=identity.js.map - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "auditTime", function() { return auditTime; }); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(186); +/* harmony import */ var _audit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(242); +/* harmony import */ var _observable_timer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(238); +/** PURE_IMPORTS_START _scheduler_async,_audit,_observable_timer PURE_IMPORTS_END */ -/***/ }), -/* 221 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isObservable", function() { return isObservable; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ -function isObservable(obj) { - return !!obj && (obj instanceof _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"] || (typeof obj.lift === 'function' && typeof obj.subscribe === 'function')); +function auditTime(duration, scheduler) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; + } + return Object(_audit__WEBPACK_IMPORTED_MODULE_1__["audit"])(function () { return Object(_observable_timer__WEBPACK_IMPORTED_MODULE_2__["timer"])(duration, scheduler); }); } -//# sourceMappingURL=isObservable.js.map +//# sourceMappingURL=auditTime.js.map /***/ }), -/* 222 */ +/* 244 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ArgumentOutOfRangeError", function() { return ArgumentOutOfRangeError; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var ArgumentOutOfRangeErrorImpl = /*@__PURE__*/ (function () { - function ArgumentOutOfRangeErrorImpl() { - Error.call(this); - this.message = 'argument out of range'; - this.name = 'ArgumentOutOfRangeError'; - return this; - } - ArgumentOutOfRangeErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); - return ArgumentOutOfRangeErrorImpl; -})(); -var ArgumentOutOfRangeError = ArgumentOutOfRangeErrorImpl; -//# sourceMappingURL=ArgumentOutOfRangeError.js.map +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buffer", function() { return buffer; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -/***/ }), -/* 223 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EmptyError", function() { return EmptyError; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var EmptyErrorImpl = /*@__PURE__*/ (function () { - function EmptyErrorImpl() { - Error.call(this); - this.message = 'no elements in sequence'; - this.name = 'EmptyError'; - return this; +function buffer(closingNotifier) { + return function bufferOperatorFunction(source) { + return source.lift(new BufferOperator(closingNotifier)); + }; +} +var BufferOperator = /*@__PURE__*/ (function () { + function BufferOperator(closingNotifier) { + this.closingNotifier = closingNotifier; } - EmptyErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); - return EmptyErrorImpl; -})(); -var EmptyError = EmptyErrorImpl; -//# sourceMappingURL=EmptyError.js.map - - -/***/ }), -/* 224 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TimeoutError", function() { return TimeoutError; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var TimeoutErrorImpl = /*@__PURE__*/ (function () { - function TimeoutErrorImpl() { - Error.call(this); - this.message = 'Timeout has occurred'; - this.name = 'TimeoutError'; - return this; + BufferOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new BufferSubscriber(subscriber, this.closingNotifier)); + }; + return BufferOperator; +}()); +var BufferSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferSubscriber, _super); + function BufferSubscriber(destination, closingNotifier) { + var _this = _super.call(this, destination) || this; + _this.buffer = []; + _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, closingNotifier)); + return _this; } - TimeoutErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); - return TimeoutErrorImpl; -})(); -var TimeoutError = TimeoutErrorImpl; -//# sourceMappingURL=TimeoutError.js.map + BufferSubscriber.prototype._next = function (value) { + this.buffer.push(value); + }; + BufferSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + var buffer = this.buffer; + this.buffer = []; + this.destination.next(buffer); + }; + return BufferSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +//# sourceMappingURL=buffer.js.map /***/ }), -/* 225 */ +/* 245 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bindCallback", function() { return bindCallback; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _AsyncSubject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(210); -/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(226); -/* harmony import */ var _util_canReportError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(171); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(178); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(205); -/** PURE_IMPORTS_START _Observable,_AsyncSubject,_operators_map,_util_canReportError,_util_isArray,_util_isScheduler PURE_IMPORTS_END */ - - - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bufferCount", function() { return bufferCount; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function bindCallback(callbackFunc, resultSelector, scheduler) { - if (resultSelector) { - if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_5__["isScheduler"])(resultSelector)) { - scheduler = resultSelector; - } - else { - return function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - return bindCallback(callbackFunc, scheduler).apply(void 0, args).pipe(Object(_operators_map__WEBPACK_IMPORTED_MODULE_2__["map"])(function (args) { return Object(_util_isArray__WEBPACK_IMPORTED_MODULE_4__["isArray"])(args) ? resultSelector.apply(void 0, args) : resultSelector(args); })); - }; - } +function bufferCount(bufferSize, startBufferEvery) { + if (startBufferEvery === void 0) { + startBufferEvery = null; } - return function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var context = this; - var subject; - var params = { - context: context, - subject: subject, - callbackFunc: callbackFunc, - scheduler: scheduler, - }; - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - if (!scheduler) { - if (!subject) { - subject = new _AsyncSubject__WEBPACK_IMPORTED_MODULE_1__["AsyncSubject"](); - var handler = function () { - var innerArgs = []; - for (var _i = 0; _i < arguments.length; _i++) { - innerArgs[_i] = arguments[_i]; - } - subject.next(innerArgs.length <= 1 ? innerArgs[0] : innerArgs); - subject.complete(); - }; - try { - callbackFunc.apply(context, args.concat([handler])); - } - catch (err) { - if (Object(_util_canReportError__WEBPACK_IMPORTED_MODULE_3__["canReportError"])(subject)) { - subject.error(err); - } - else { - console.warn(err); - } - } - } - return subject.subscribe(subscriber); - } - else { - var state = { - args: args, subscriber: subscriber, params: params, - }; - return scheduler.schedule(dispatch, 0, state); - } - }); + return function bufferCountOperatorFunction(source) { + return source.lift(new BufferCountOperator(bufferSize, startBufferEvery)); }; } -function dispatch(state) { - var _this = this; - var self = this; - var args = state.args, subscriber = state.subscriber, params = state.params; - var callbackFunc = params.callbackFunc, context = params.context, scheduler = params.scheduler; - var subject = params.subject; - if (!subject) { - subject = params.subject = new _AsyncSubject__WEBPACK_IMPORTED_MODULE_1__["AsyncSubject"](); - var handler = function () { - var innerArgs = []; - for (var _i = 0; _i < arguments.length; _i++) { - innerArgs[_i] = arguments[_i]; - } - var value = innerArgs.length <= 1 ? innerArgs[0] : innerArgs; - _this.add(scheduler.schedule(dispatchNext, 0, { value: value, subject: subject })); - }; - try { - callbackFunc.apply(context, args.concat([handler])); +var BufferCountOperator = /*@__PURE__*/ (function () { + function BufferCountOperator(bufferSize, startBufferEvery) { + this.bufferSize = bufferSize; + this.startBufferEvery = startBufferEvery; + if (!startBufferEvery || bufferSize === startBufferEvery) { + this.subscriberClass = BufferCountSubscriber; } - catch (err) { - subject.error(err); + else { + this.subscriberClass = BufferSkipCountSubscriber; } } - this.add(subject.subscribe(subscriber)); -} -function dispatchNext(state) { - var value = state.value, subject = state.subject; - subject.next(value); - subject.complete(); -} -function dispatchError(state) { - var err = state.err, subject = state.subject; - subject.error(err); -} -//# sourceMappingURL=bindCallback.js.map - - -/***/ }), -/* 226 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "map", function() { return map; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MapOperator", function() { return MapOperator; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ - - -function map(project, thisArg) { - return function mapOperation(source) { - if (typeof project !== 'function') { - throw new TypeError('argument is not a function. Are you looking for `mapTo()`?'); - } - return source.lift(new MapOperator(project, thisArg)); + BufferCountOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new this.subscriberClass(subscriber, this.bufferSize, this.startBufferEvery)); }; -} -var MapOperator = /*@__PURE__*/ (function () { - function MapOperator(project, thisArg) { - this.project = project; - this.thisArg = thisArg; + return BufferCountOperator; +}()); +var BufferCountSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferCountSubscriber, _super); + function BufferCountSubscriber(destination, bufferSize) { + var _this = _super.call(this, destination) || this; + _this.bufferSize = bufferSize; + _this.buffer = []; + return _this; } - MapOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new MapSubscriber(subscriber, this.project, this.thisArg)); + BufferCountSubscriber.prototype._next = function (value) { + var buffer = this.buffer; + buffer.push(value); + if (buffer.length == this.bufferSize) { + this.destination.next(buffer); + this.buffer = []; + } }; - return MapOperator; -}()); - -var MapSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MapSubscriber, _super); - function MapSubscriber(destination, project, thisArg) { + BufferCountSubscriber.prototype._complete = function () { + var buffer = this.buffer; + if (buffer.length > 0) { + this.destination.next(buffer); + } + _super.prototype._complete.call(this); + }; + return BufferCountSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +var BufferSkipCountSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferSkipCountSubscriber, _super); + function BufferSkipCountSubscriber(destination, bufferSize, startBufferEvery) { var _this = _super.call(this, destination) || this; - _this.project = project; + _this.bufferSize = bufferSize; + _this.startBufferEvery = startBufferEvery; + _this.buffers = []; _this.count = 0; - _this.thisArg = thisArg || _this; return _this; } - MapSubscriber.prototype._next = function (value) { - var result; - try { - result = this.project.call(this.thisArg, value, this.count++); + BufferSkipCountSubscriber.prototype._next = function (value) { + var _a = this, bufferSize = _a.bufferSize, startBufferEvery = _a.startBufferEvery, buffers = _a.buffers, count = _a.count; + this.count++; + if (count % startBufferEvery === 0) { + buffers.push([]); } - catch (err) { - this.destination.error(err); - return; + for (var i = buffers.length; i--;) { + var buffer = buffers[i]; + buffer.push(value); + if (buffer.length === bufferSize) { + buffers.splice(i, 1); + this.destination.next(buffer); + } } - this.destination.next(result); }; - return MapSubscriber; + BufferSkipCountSubscriber.prototype._complete = function () { + var _a = this, buffers = _a.buffers, destination = _a.destination; + while (buffers.length > 0) { + var buffer = buffers.shift(); + if (buffer.length > 0) { + destination.next(buffer); + } + } + _super.prototype._complete.call(this); + }; + return BufferSkipCountSubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=map.js.map +//# sourceMappingURL=bufferCount.js.map /***/ }), -/* 227 */ +/* 246 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bindNodeCallback", function() { return bindNodeCallback; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _AsyncSubject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(210); -/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(226); -/* harmony import */ var _util_canReportError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(171); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(205); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(178); -/** PURE_IMPORTS_START _Observable,_AsyncSubject,_operators_map,_util_canReportError,_util_isScheduler,_util_isArray PURE_IMPORTS_END */ - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bufferTime", function() { return bufferTime; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(186); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(143); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(176); +/** PURE_IMPORTS_START tslib,_scheduler_async,_Subscriber,_util_isScheduler PURE_IMPORTS_END */ -function bindNodeCallback(callbackFunc, resultSelector, scheduler) { - if (resultSelector) { - if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_4__["isScheduler"])(resultSelector)) { - scheduler = resultSelector; - } - else { - return function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - return bindNodeCallback(callbackFunc, scheduler).apply(void 0, args).pipe(Object(_operators_map__WEBPACK_IMPORTED_MODULE_2__["map"])(function (args) { return Object(_util_isArray__WEBPACK_IMPORTED_MODULE_5__["isArray"])(args) ? resultSelector.apply(void 0, args) : resultSelector(args); })); - }; - } +function bufferTime(bufferTimeSpan) { + var length = arguments.length; + var scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; + if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_3__["isScheduler"])(arguments[arguments.length - 1])) { + scheduler = arguments[arguments.length - 1]; + length--; } - return function () { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var params = { - subject: undefined, - args: args, - callbackFunc: callbackFunc, - scheduler: scheduler, - context: this, - }; - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - var context = params.context; - var subject = params.subject; - if (!scheduler) { - if (!subject) { - subject = params.subject = new _AsyncSubject__WEBPACK_IMPORTED_MODULE_1__["AsyncSubject"](); - var handler = function () { - var innerArgs = []; - for (var _i = 0; _i < arguments.length; _i++) { - innerArgs[_i] = arguments[_i]; - } - var err = innerArgs.shift(); - if (err) { - subject.error(err); - return; - } - subject.next(innerArgs.length <= 1 ? innerArgs[0] : innerArgs); - subject.complete(); - }; - try { - callbackFunc.apply(context, args.concat([handler])); - } - catch (err) { - if (Object(_util_canReportError__WEBPACK_IMPORTED_MODULE_3__["canReportError"])(subject)) { - subject.error(err); - } - else { - console.warn(err); - } - } - } - return subject.subscribe(subscriber); - } - else { - return scheduler.schedule(dispatch, 0, { params: params, subscriber: subscriber, context: context }); - } - }); + var bufferCreationInterval = null; + if (length >= 2) { + bufferCreationInterval = arguments[1]; + } + var maxBufferSize = Number.POSITIVE_INFINITY; + if (length >= 3) { + maxBufferSize = arguments[2]; + } + return function bufferTimeOperatorFunction(source) { + return source.lift(new BufferTimeOperator(bufferTimeSpan, bufferCreationInterval, maxBufferSize, scheduler)); }; } -function dispatch(state) { - var _this = this; - var params = state.params, subscriber = state.subscriber, context = state.context; - var callbackFunc = params.callbackFunc, args = params.args, scheduler = params.scheduler; - var subject = params.subject; - if (!subject) { - subject = params.subject = new _AsyncSubject__WEBPACK_IMPORTED_MODULE_1__["AsyncSubject"](); - var handler = function () { - var innerArgs = []; - for (var _i = 0; _i < arguments.length; _i++) { - innerArgs[_i] = arguments[_i]; - } - var err = innerArgs.shift(); - if (err) { - _this.add(scheduler.schedule(dispatchError, 0, { err: err, subject: subject })); - } - else { - var value = innerArgs.length <= 1 ? innerArgs[0] : innerArgs; - _this.add(scheduler.schedule(dispatchNext, 0, { value: value, subject: subject })); +var BufferTimeOperator = /*@__PURE__*/ (function () { + function BufferTimeOperator(bufferTimeSpan, bufferCreationInterval, maxBufferSize, scheduler) { + this.bufferTimeSpan = bufferTimeSpan; + this.bufferCreationInterval = bufferCreationInterval; + this.maxBufferSize = maxBufferSize; + this.scheduler = scheduler; + } + BufferTimeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new BufferTimeSubscriber(subscriber, this.bufferTimeSpan, this.bufferCreationInterval, this.maxBufferSize, this.scheduler)); + }; + return BufferTimeOperator; +}()); +var Context = /*@__PURE__*/ (function () { + function Context() { + this.buffer = []; + } + return Context; +}()); +var BufferTimeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferTimeSubscriber, _super); + function BufferTimeSubscriber(destination, bufferTimeSpan, bufferCreationInterval, maxBufferSize, scheduler) { + var _this = _super.call(this, destination) || this; + _this.bufferTimeSpan = bufferTimeSpan; + _this.bufferCreationInterval = bufferCreationInterval; + _this.maxBufferSize = maxBufferSize; + _this.scheduler = scheduler; + _this.contexts = []; + var context = _this.openContext(); + _this.timespanOnly = bufferCreationInterval == null || bufferCreationInterval < 0; + if (_this.timespanOnly) { + var timeSpanOnlyState = { subscriber: _this, context: context, bufferTimeSpan: bufferTimeSpan }; + _this.add(context.closeAction = scheduler.schedule(dispatchBufferTimeSpanOnly, bufferTimeSpan, timeSpanOnlyState)); + } + else { + var closeState = { subscriber: _this, context: context }; + var creationState = { bufferTimeSpan: bufferTimeSpan, bufferCreationInterval: bufferCreationInterval, subscriber: _this, scheduler: scheduler }; + _this.add(context.closeAction = scheduler.schedule(dispatchBufferClose, bufferTimeSpan, closeState)); + _this.add(scheduler.schedule(dispatchBufferCreation, bufferCreationInterval, creationState)); + } + return _this; + } + BufferTimeSubscriber.prototype._next = function (value) { + var contexts = this.contexts; + var len = contexts.length; + var filledBufferContext; + for (var i = 0; i < len; i++) { + var context_1 = contexts[i]; + var buffer = context_1.buffer; + buffer.push(value); + if (buffer.length == this.maxBufferSize) { + filledBufferContext = context_1; } - }; - try { - callbackFunc.apply(context, args.concat([handler])); } - catch (err) { - this.add(scheduler.schedule(dispatchError, 0, { err: err, subject: subject })); + if (filledBufferContext) { + this.onBufferFull(filledBufferContext); + } + }; + BufferTimeSubscriber.prototype._error = function (err) { + this.contexts.length = 0; + _super.prototype._error.call(this, err); + }; + BufferTimeSubscriber.prototype._complete = function () { + var _a = this, contexts = _a.contexts, destination = _a.destination; + while (contexts.length > 0) { + var context_2 = contexts.shift(); + destination.next(context_2.buffer); + } + _super.prototype._complete.call(this); + }; + BufferTimeSubscriber.prototype._unsubscribe = function () { + this.contexts = null; + }; + BufferTimeSubscriber.prototype.onBufferFull = function (context) { + this.closeContext(context); + var closeAction = context.closeAction; + closeAction.unsubscribe(); + this.remove(closeAction); + if (!this.closed && this.timespanOnly) { + context = this.openContext(); + var bufferTimeSpan = this.bufferTimeSpan; + var timeSpanOnlyState = { subscriber: this, context: context, bufferTimeSpan: bufferTimeSpan }; + this.add(context.closeAction = this.scheduler.schedule(dispatchBufferTimeSpanOnly, bufferTimeSpan, timeSpanOnlyState)); + } + }; + BufferTimeSubscriber.prototype.openContext = function () { + var context = new Context(); + this.contexts.push(context); + return context; + }; + BufferTimeSubscriber.prototype.closeContext = function (context) { + this.destination.next(context.buffer); + var contexts = this.contexts; + var spliceIndex = contexts ? contexts.indexOf(context) : -1; + if (spliceIndex >= 0) { + contexts.splice(contexts.indexOf(context), 1); } + }; + return BufferTimeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_2__["Subscriber"])); +function dispatchBufferTimeSpanOnly(state) { + var subscriber = state.subscriber; + var prevContext = state.context; + if (prevContext) { + subscriber.closeContext(prevContext); + } + if (!subscriber.closed) { + state.context = subscriber.openContext(); + state.context.closeAction = this.schedule(state, state.bufferTimeSpan); } - this.add(subject.subscribe(subscriber)); } -function dispatchNext(arg) { - var value = arg.value, subject = arg.subject; - subject.next(value); - subject.complete(); +function dispatchBufferCreation(state) { + var bufferCreationInterval = state.bufferCreationInterval, bufferTimeSpan = state.bufferTimeSpan, subscriber = state.subscriber, scheduler = state.scheduler; + var context = subscriber.openContext(); + var action = this; + if (!subscriber.closed) { + subscriber.add(context.closeAction = scheduler.schedule(dispatchBufferClose, bufferTimeSpan, { subscriber: subscriber, context: context })); + action.schedule(state, bufferCreationInterval); + } } -function dispatchError(arg) { - var err = arg.err, subject = arg.subject; - subject.error(err); +function dispatchBufferClose(arg) { + var subscriber = arg.subscriber, context = arg.context; + subscriber.closeContext(context); } -//# sourceMappingURL=bindNodeCallback.js.map +//# sourceMappingURL=bufferTime.js.map /***/ }), -/* 228 */ +/* 247 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return combineLatest; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CombineLatestOperator", function() { return CombineLatestOperator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CombineLatestSubscriber", function() { return CombineLatestSubscriber; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(205); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(178); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(230); -/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(206); -/** PURE_IMPORTS_START tslib,_util_isScheduler,_util_isArray,_OuterSubscriber,_util_subscribeToResult,_fromArray PURE_IMPORTS_END */ - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bufferToggle", function() { return bufferToggle; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(148); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(201); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(200); +/** PURE_IMPORTS_START tslib,_Subscription,_util_subscribeToResult,_OuterSubscriber PURE_IMPORTS_END */ -var NONE = {}; -function combineLatest() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; - } - var resultSelector = null; - var scheduler = null; - if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_1__["isScheduler"])(observables[observables.length - 1])) { - scheduler = observables.pop(); - } - if (typeof observables[observables.length - 1] === 'function') { - resultSelector = observables.pop(); - } - if (observables.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_2__["isArray"])(observables[0])) { - observables = observables[0]; - } - return Object(_fromArray__WEBPACK_IMPORTED_MODULE_5__["fromArray"])(observables, scheduler).lift(new CombineLatestOperator(resultSelector)); +function bufferToggle(openings, closingSelector) { + return function bufferToggleOperatorFunction(source) { + return source.lift(new BufferToggleOperator(openings, closingSelector)); + }; } -var CombineLatestOperator = /*@__PURE__*/ (function () { - function CombineLatestOperator(resultSelector) { - this.resultSelector = resultSelector; +var BufferToggleOperator = /*@__PURE__*/ (function () { + function BufferToggleOperator(openings, closingSelector) { + this.openings = openings; + this.closingSelector = closingSelector; } - CombineLatestOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new CombineLatestSubscriber(subscriber, this.resultSelector)); + BufferToggleOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new BufferToggleSubscriber(subscriber, this.openings, this.closingSelector)); }; - return CombineLatestOperator; + return BufferToggleOperator; }()); - -var CombineLatestSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CombineLatestSubscriber, _super); - function CombineLatestSubscriber(destination, resultSelector) { +var BufferToggleSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferToggleSubscriber, _super); + function BufferToggleSubscriber(destination, openings, closingSelector) { var _this = _super.call(this, destination) || this; - _this.resultSelector = resultSelector; - _this.active = 0; - _this.values = []; - _this.observables = []; + _this.openings = openings; + _this.closingSelector = closingSelector; + _this.contexts = []; + _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, openings)); return _this; } - CombineLatestSubscriber.prototype._next = function (observable) { - this.values.push(NONE); - this.observables.push(observable); - }; - CombineLatestSubscriber.prototype._complete = function () { - var observables = this.observables; - var len = observables.length; - if (len === 0) { - this.destination.complete(); - } - else { - this.active = len; - this.toRespond = len; - for (var i = 0; i < len; i++) { - var observable = observables[i]; - this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, observable, observable, i)); - } + BufferToggleSubscriber.prototype._next = function (value) { + var contexts = this.contexts; + var len = contexts.length; + for (var i = 0; i < len; i++) { + contexts[i].buffer.push(value); } }; - CombineLatestSubscriber.prototype.notifyComplete = function (unused) { - if ((this.active -= 1) === 0) { - this.destination.complete(); + BufferToggleSubscriber.prototype._error = function (err) { + var contexts = this.contexts; + while (contexts.length > 0) { + var context_1 = contexts.shift(); + context_1.subscription.unsubscribe(); + context_1.buffer = null; + context_1.subscription = null; } + this.contexts = null; + _super.prototype._error.call(this, err); }; - CombineLatestSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - var values = this.values; - var oldVal = values[outerIndex]; - var toRespond = !this.toRespond - ? 0 - : oldVal === NONE ? --this.toRespond : this.toRespond; - values[outerIndex] = innerValue; - if (toRespond === 0) { - if (this.resultSelector) { - this._tryResultSelector(values); - } - else { - this.destination.next(values.slice()); - } + BufferToggleSubscriber.prototype._complete = function () { + var contexts = this.contexts; + while (contexts.length > 0) { + var context_2 = contexts.shift(); + this.destination.next(context_2.buffer); + context_2.subscription.unsubscribe(); + context_2.buffer = null; + context_2.subscription = null; } + this.contexts = null; + _super.prototype._complete.call(this); }; - CombineLatestSubscriber.prototype._tryResultSelector = function (values) { - var result; + BufferToggleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + outerValue ? this.closeBuffer(outerValue) : this.openBuffer(innerValue); + }; + BufferToggleSubscriber.prototype.notifyComplete = function (innerSub) { + this.closeBuffer(innerSub.context); + }; + BufferToggleSubscriber.prototype.openBuffer = function (value) { try { - result = this.resultSelector.apply(this, values); + var closingSelector = this.closingSelector; + var closingNotifier = closingSelector.call(this, value); + if (closingNotifier) { + this.trySubscribe(closingNotifier); + } } catch (err) { - this.destination.error(err); - return; + this._error(err); } - this.destination.next(result); }; - return CombineLatestSubscriber; + BufferToggleSubscriber.prototype.closeBuffer = function (context) { + var contexts = this.contexts; + if (contexts && context) { + var buffer = context.buffer, subscription = context.subscription; + this.destination.next(buffer); + contexts.splice(contexts.indexOf(context), 1); + this.remove(subscription); + subscription.unsubscribe(); + } + }; + BufferToggleSubscriber.prototype.trySubscribe = function (closingNotifier) { + var contexts = this.contexts; + var buffer = []; + var subscription = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); + var context = { buffer: buffer, subscription: subscription }; + contexts.push(context); + var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, closingNotifier, context); + if (!innerSubscription || innerSubscription.closed) { + this.closeBuffer(context); + } + else { + innerSubscription.context = context; + this.add(innerSubscription); + subscription.add(innerSubscription); + } + }; + return BufferToggleSubscriber; }(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); - -//# sourceMappingURL=combineLatest.js.map +//# sourceMappingURL=bufferToggle.js.map /***/ }), -/* 229 */ +/* 248 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OuterSubscriber", function() { return OuterSubscriber; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bufferWhen", function() { return bufferWhen; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(148); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_Subscription,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -var OuterSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](OuterSubscriber, _super); - function OuterSubscriber() { - return _super !== null && _super.apply(this, arguments) || this; + + +function bufferWhen(closingSelector) { + return function (source) { + return source.lift(new BufferWhenOperator(closingSelector)); + }; +} +var BufferWhenOperator = /*@__PURE__*/ (function () { + function BufferWhenOperator(closingSelector) { + this.closingSelector = closingSelector; } - OuterSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.destination.next(innerValue); + BufferWhenOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new BufferWhenSubscriber(subscriber, this.closingSelector)); }; - OuterSubscriber.prototype.notifyError = function (error, innerSub) { - this.destination.error(error); + return BufferWhenOperator; +}()); +var BufferWhenSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferWhenSubscriber, _super); + function BufferWhenSubscriber(destination, closingSelector) { + var _this = _super.call(this, destination) || this; + _this.closingSelector = closingSelector; + _this.subscribing = false; + _this.openBuffer(); + return _this; + } + BufferWhenSubscriber.prototype._next = function (value) { + this.buffer.push(value); }; - OuterSubscriber.prototype.notifyComplete = function (innerSub) { - this.destination.complete(); + BufferWhenSubscriber.prototype._complete = function () { + var buffer = this.buffer; + if (buffer) { + this.destination.next(buffer); + } + _super.prototype._complete.call(this); }; - return OuterSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); - -//# sourceMappingURL=OuterSubscriber.js.map + BufferWhenSubscriber.prototype._unsubscribe = function () { + this.buffer = null; + this.subscribing = false; + }; + BufferWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.openBuffer(); + }; + BufferWhenSubscriber.prototype.notifyComplete = function () { + if (this.subscribing) { + this.complete(); + } + else { + this.openBuffer(); + } + }; + BufferWhenSubscriber.prototype.openBuffer = function () { + var closingSubscription = this.closingSubscription; + if (closingSubscription) { + this.remove(closingSubscription); + closingSubscription.unsubscribe(); + } + var buffer = this.buffer; + if (this.buffer) { + this.destination.next(buffer); + } + this.buffer = []; + var closingNotifier; + try { + var closingSelector = this.closingSelector; + closingNotifier = closingSelector(); + } + catch (err) { + return this.error(err); + } + closingSubscription = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); + this.closingSubscription = closingSubscription; + this.add(closingSubscription); + this.subscribing = true; + closingSubscription.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, closingNotifier)); + this.subscribing = false; + }; + return BufferWhenSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); +//# sourceMappingURL=bufferWhen.js.map /***/ }), -/* 230 */ +/* 249 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeToResult", function() { return subscribeToResult; }); -/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(231); -/* harmony import */ var _subscribeTo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(232); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(170); -/** PURE_IMPORTS_START _InnerSubscriber,_subscribeTo,_Observable PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "catchError", function() { return catchError; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(200); +/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(202); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function subscribeToResult(outerSubscriber, result, outerValue, outerIndex, destination) { - if (destination === void 0) { - destination = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_0__["InnerSubscriber"](outerSubscriber, outerValue, outerIndex); - } - if (destination.closed) { - return undefined; + +function catchError(selector) { + return function catchErrorOperatorFunction(source) { + var operator = new CatchOperator(selector); + var caught = source.lift(operator); + return (operator.caught = caught); + }; +} +var CatchOperator = /*@__PURE__*/ (function () { + function CatchOperator(selector) { + this.selector = selector; } - if (result instanceof _Observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]) { - return result.subscribe(destination); + CatchOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new CatchSubscriber(subscriber, this.selector, this.caught)); + }; + return CatchOperator; +}()); +var CatchSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CatchSubscriber, _super); + function CatchSubscriber(destination, selector, caught) { + var _this = _super.call(this, destination) || this; + _this.selector = selector; + _this.caught = caught; + return _this; } - return Object(_subscribeTo__WEBPACK_IMPORTED_MODULE_1__["subscribeTo"])(result)(destination); -} -//# sourceMappingURL=subscribeToResult.js.map + CatchSubscriber.prototype.error = function (err) { + if (!this.isStopped) { + var result = void 0; + try { + result = this.selector(err, this.caught); + } + catch (err2) { + _super.prototype.error.call(this, err2); + return; + } + this._unsubscribeAndRecycle(); + var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](this, undefined, undefined); + this.add(innerSubscriber); + Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, result, undefined, undefined, innerSubscriber); + } + }; + return CatchSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +//# sourceMappingURL=catchError.js.map /***/ }), -/* 231 */ +/* 250 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InnerSubscriber", function() { return InnerSubscriber; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "combineAll", function() { return combineAll; }); +/* harmony import */ var _observable_combineLatest__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(199); +/** PURE_IMPORTS_START _observable_combineLatest PURE_IMPORTS_END */ - -var InnerSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](InnerSubscriber, _super); - function InnerSubscriber(parent, outerValue, outerIndex) { - var _this = _super.call(this) || this; - _this.parent = parent; - _this.outerValue = outerValue; - _this.outerIndex = outerIndex; - _this.index = 0; - return _this; - } - InnerSubscriber.prototype._next = function (value) { - this.parent.notifyNext(this.outerValue, value, this.outerIndex, this.index++, this); - }; - InnerSubscriber.prototype._error = function (error) { - this.parent.notifyError(error, this); - this.unsubscribe(); - }; - InnerSubscriber.prototype._complete = function () { - this.parent.notifyComplete(this); - this.unsubscribe(); - }; - return InnerSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); - -//# sourceMappingURL=InnerSubscriber.js.map +function combineAll(project) { + return function (source) { return source.lift(new _observable_combineLatest__WEBPACK_IMPORTED_MODULE_0__["CombineLatestOperator"](project)); }; +} +//# sourceMappingURL=combineAll.js.map /***/ }), -/* 232 */ +/* 251 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeTo", function() { return subscribeTo; }); -/* harmony import */ var _subscribeToArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(207); -/* harmony import */ var _subscribeToPromise__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(233); -/* harmony import */ var _subscribeToIterable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(234); -/* harmony import */ var _subscribeToObservable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(236); -/* harmony import */ var _isArrayLike__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(237); -/* harmony import */ var _isPromise__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(238); -/* harmony import */ var _isObject__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(179); -/* harmony import */ var _symbol_iterator__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(235); -/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(183); -/** PURE_IMPORTS_START _subscribeToArray,_subscribeToPromise,_subscribeToIterable,_subscribeToObservable,_isArrayLike,_isPromise,_isObject,_symbol_iterator,_symbol_observable PURE_IMPORTS_END */ - - - - - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return combineLatest; }); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(149); +/* harmony import */ var _observable_combineLatest__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(199); +/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(214); +/** PURE_IMPORTS_START _util_isArray,_observable_combineLatest,_observable_from PURE_IMPORTS_END */ -var subscribeTo = function (result) { - if (!!result && typeof result[_symbol_observable__WEBPACK_IMPORTED_MODULE_8__["observable"]] === 'function') { - return Object(_subscribeToObservable__WEBPACK_IMPORTED_MODULE_3__["subscribeToObservable"])(result); - } - else if (Object(_isArrayLike__WEBPACK_IMPORTED_MODULE_4__["isArrayLike"])(result)) { - return Object(_subscribeToArray__WEBPACK_IMPORTED_MODULE_0__["subscribeToArray"])(result); - } - else if (Object(_isPromise__WEBPACK_IMPORTED_MODULE_5__["isPromise"])(result)) { - return Object(_subscribeToPromise__WEBPACK_IMPORTED_MODULE_1__["subscribeToPromise"])(result); +var none = {}; +function combineLatest() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; } - else if (!!result && typeof result[_symbol_iterator__WEBPACK_IMPORTED_MODULE_7__["iterator"]] === 'function') { - return Object(_subscribeToIterable__WEBPACK_IMPORTED_MODULE_2__["subscribeToIterable"])(result); + var project = null; + if (typeof observables[observables.length - 1] === 'function') { + project = observables.pop(); } - else { - var value = Object(_isObject__WEBPACK_IMPORTED_MODULE_6__["isObject"])(result) ? 'an invalid object' : "'" + result + "'"; - var msg = "You provided " + value + " where a stream was expected." - + ' You can provide an Observable, Promise, Array, or Iterable.'; - throw new TypeError(msg); + if (observables.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_0__["isArray"])(observables[0])) { + observables = observables[0].slice(); } -}; -//# sourceMappingURL=subscribeTo.js.map + return function (source) { return source.lift.call(Object(_observable_from__WEBPACK_IMPORTED_MODULE_2__["from"])([source].concat(observables)), new _observable_combineLatest__WEBPACK_IMPORTED_MODULE_1__["CombineLatestOperator"](project)); }; +} +//# sourceMappingURL=combineLatest.js.map /***/ }), -/* 233 */ +/* 252 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeToPromise", function() { return subscribeToPromise; }); -/* harmony import */ var _hostReportError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(176); -/** PURE_IMPORTS_START _hostReportError PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return concat; }); +/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(210); +/** PURE_IMPORTS_START _observable_concat PURE_IMPORTS_END */ -var subscribeToPromise = function (promise) { - return function (subscriber) { - promise.then(function (value) { - if (!subscriber.closed) { - subscriber.next(value); - subscriber.complete(); - } - }, function (err) { return subscriber.error(err); }) - .then(null, _hostReportError__WEBPACK_IMPORTED_MODULE_0__["hostReportError"]); - return subscriber; - }; -}; -//# sourceMappingURL=subscribeToPromise.js.map +function concat() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + return function (source) { return source.lift.call(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"].apply(void 0, [source].concat(observables))); }; +} +//# sourceMappingURL=concat.js.map /***/ }), -/* 234 */ +/* 253 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeToIterable", function() { return subscribeToIterable; }); -/* harmony import */ var _symbol_iterator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(235); -/** PURE_IMPORTS_START _symbol_iterator PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concatMap", function() { return concatMap; }); +/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(213); +/** PURE_IMPORTS_START _mergeMap PURE_IMPORTS_END */ -var subscribeToIterable = function (iterable) { - return function (subscriber) { - var iterator = iterable[_symbol_iterator__WEBPACK_IMPORTED_MODULE_0__["iterator"]](); - do { - var item = iterator.next(); - if (item.done) { - subscriber.complete(); - break; - } - subscriber.next(item.value); - if (subscriber.closed) { - break; - } - } while (true); - if (typeof iterator.return === 'function') { - subscriber.add(function () { - if (iterator.return) { - iterator.return(); - } - }); - } - return subscriber; - }; -}; -//# sourceMappingURL=subscribeToIterable.js.map +function concatMap(project, resultSelector) { + return Object(_mergeMap__WEBPACK_IMPORTED_MODULE_0__["mergeMap"])(project, resultSelector, 1); +} +//# sourceMappingURL=concatMap.js.map /***/ }), -/* 235 */ +/* 254 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getSymbolIterator", function() { return getSymbolIterator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "iterator", function() { return iterator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "$$iterator", function() { return $$iterator; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function getSymbolIterator() { - if (typeof Symbol !== 'function' || !Symbol.iterator) { - return '@@iterator'; - } - return Symbol.iterator; +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concatMapTo", function() { return concatMapTo; }); +/* harmony import */ var _concatMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(253); +/** PURE_IMPORTS_START _concatMap PURE_IMPORTS_END */ + +function concatMapTo(innerObservable, resultSelector) { + return Object(_concatMap__WEBPACK_IMPORTED_MODULE_0__["concatMap"])(function () { return innerObservable; }, resultSelector); } -var iterator = /*@__PURE__*/ getSymbolIterator(); -var $$iterator = iterator; -//# sourceMappingURL=iterator.js.map +//# sourceMappingURL=concatMapTo.js.map /***/ }), -/* 236 */ +/* 255 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeToObservable", function() { return subscribeToObservable; }); -/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(183); -/** PURE_IMPORTS_START _symbol_observable PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "count", function() { return count; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -var subscribeToObservable = function (obj) { - return function (subscriber) { - var obs = obj[_symbol_observable__WEBPACK_IMPORTED_MODULE_0__["observable"]](); - if (typeof obs.subscribe !== 'function') { - throw new TypeError('Provided object does not correctly implement Symbol.observable'); + +function count(predicate) { + return function (source) { return source.lift(new CountOperator(predicate, source)); }; +} +var CountOperator = /*@__PURE__*/ (function () { + function CountOperator(predicate, source) { + this.predicate = predicate; + this.source = source; + } + CountOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new CountSubscriber(subscriber, this.predicate, this.source)); + }; + return CountOperator; +}()); +var CountSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CountSubscriber, _super); + function CountSubscriber(destination, predicate, source) { + var _this = _super.call(this, destination) || this; + _this.predicate = predicate; + _this.source = source; + _this.count = 0; + _this.index = 0; + return _this; + } + CountSubscriber.prototype._next = function (value) { + if (this.predicate) { + this._tryPredicate(value); } else { - return obs.subscribe(subscriber); + this.count++; } }; -}; -//# sourceMappingURL=subscribeToObservable.js.map + CountSubscriber.prototype._tryPredicate = function (value) { + var result; + try { + result = this.predicate(value, this.index++, this.source); + } + catch (err) { + this.destination.error(err); + return; + } + if (result) { + this.count++; + } + }; + CountSubscriber.prototype._complete = function () { + this.destination.next(this.count); + this.destination.complete(); + }; + return CountSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=count.js.map /***/ }), -/* 237 */ +/* 256 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isArrayLike", function() { return isArrayLike; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var isArrayLike = (function (x) { return x && typeof x.length === 'number' && typeof x !== 'function'; }); -//# sourceMappingURL=isArrayLike.js.map +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "debounce", function() { return debounce; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -/***/ }), -/* 238 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isPromise", function() { return isPromise; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function isPromise(value) { - return !!value && typeof value.subscribe !== 'function' && typeof value.then === 'function'; +function debounce(durationSelector) { + return function (source) { return source.lift(new DebounceOperator(durationSelector)); }; } -//# sourceMappingURL=isPromise.js.map +var DebounceOperator = /*@__PURE__*/ (function () { + function DebounceOperator(durationSelector) { + this.durationSelector = durationSelector; + } + DebounceOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DebounceSubscriber(subscriber, this.durationSelector)); + }; + return DebounceOperator; +}()); +var DebounceSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DebounceSubscriber, _super); + function DebounceSubscriber(destination, durationSelector) { + var _this = _super.call(this, destination) || this; + _this.durationSelector = durationSelector; + _this.hasValue = false; + _this.durationSubscription = null; + return _this; + } + DebounceSubscriber.prototype._next = function (value) { + try { + var result = this.durationSelector.call(this, value); + if (result) { + this._tryNext(value, result); + } + } + catch (err) { + this.destination.error(err); + } + }; + DebounceSubscriber.prototype._complete = function () { + this.emitValue(); + this.destination.complete(); + }; + DebounceSubscriber.prototype._tryNext = function (value, duration) { + var subscription = this.durationSubscription; + this.value = value; + this.hasValue = true; + if (subscription) { + subscription.unsubscribe(); + this.remove(subscription); + } + subscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, duration); + if (subscription && !subscription.closed) { + this.add(this.durationSubscription = subscription); + } + }; + DebounceSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.emitValue(); + }; + DebounceSubscriber.prototype.notifyComplete = function () { + this.emitValue(); + }; + DebounceSubscriber.prototype.emitValue = function () { + if (this.hasValue) { + var value = this.value; + var subscription = this.durationSubscription; + if (subscription) { + this.durationSubscription = null; + subscription.unsubscribe(); + this.remove(subscription); + } + this.value = null; + this.hasValue = false; + _super.prototype._next.call(this, value); + } + }; + return DebounceSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +//# sourceMappingURL=debounce.js.map /***/ }), -/* 239 */ +/* 257 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return concat; }); -/* harmony import */ var _of__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(204); -/* harmony import */ var _operators_concatAll__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(240); -/** PURE_IMPORTS_START _of,_operators_concatAll PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "debounceTime", function() { return debounceTime; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(186); +/** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async PURE_IMPORTS_END */ -function concat() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; + +function debounceTime(dueTime, scheduler) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; } - return Object(_operators_concatAll__WEBPACK_IMPORTED_MODULE_1__["concatAll"])()(_of__WEBPACK_IMPORTED_MODULE_0__["of"].apply(void 0, observables)); + return function (source) { return source.lift(new DebounceTimeOperator(dueTime, scheduler)); }; } -//# sourceMappingURL=concat.js.map - - -/***/ }), -/* 240 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concatAll", function() { return concatAll; }); -/* harmony import */ var _mergeAll__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(241); -/** PURE_IMPORTS_START _mergeAll PURE_IMPORTS_END */ - -function concatAll() { - return Object(_mergeAll__WEBPACK_IMPORTED_MODULE_0__["mergeAll"])(1); +var DebounceTimeOperator = /*@__PURE__*/ (function () { + function DebounceTimeOperator(dueTime, scheduler) { + this.dueTime = dueTime; + this.scheduler = scheduler; + } + DebounceTimeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DebounceTimeSubscriber(subscriber, this.dueTime, this.scheduler)); + }; + return DebounceTimeOperator; +}()); +var DebounceTimeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DebounceTimeSubscriber, _super); + function DebounceTimeSubscriber(destination, dueTime, scheduler) { + var _this = _super.call(this, destination) || this; + _this.dueTime = dueTime; + _this.scheduler = scheduler; + _this.debouncedSubscription = null; + _this.lastValue = null; + _this.hasValue = false; + return _this; + } + DebounceTimeSubscriber.prototype._next = function (value) { + this.clearDebounce(); + this.lastValue = value; + this.hasValue = true; + this.add(this.debouncedSubscription = this.scheduler.schedule(dispatchNext, this.dueTime, this)); + }; + DebounceTimeSubscriber.prototype._complete = function () { + this.debouncedNext(); + this.destination.complete(); + }; + DebounceTimeSubscriber.prototype.debouncedNext = function () { + this.clearDebounce(); + if (this.hasValue) { + var lastValue = this.lastValue; + this.lastValue = null; + this.hasValue = false; + this.destination.next(lastValue); + } + }; + DebounceTimeSubscriber.prototype.clearDebounce = function () { + var debouncedSubscription = this.debouncedSubscription; + if (debouncedSubscription !== null) { + this.remove(debouncedSubscription); + debouncedSubscription.unsubscribe(); + this.debouncedSubscription = null; + } + }; + return DebounceTimeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +function dispatchNext(subscriber) { + subscriber.debouncedNext(); } -//# sourceMappingURL=concatAll.js.map +//# sourceMappingURL=debounceTime.js.map /***/ }), -/* 241 */ +/* 258 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeAll", function() { return mergeAll; }); -/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(242); -/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(220); -/** PURE_IMPORTS_START _mergeMap,_util_identity PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultIfEmpty", function() { return defaultIfEmpty; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function mergeAll(concurrent) { - if (concurrent === void 0) { - concurrent = Number.POSITIVE_INFINITY; +function defaultIfEmpty(defaultValue) { + if (defaultValue === void 0) { + defaultValue = null; } - return Object(_mergeMap__WEBPACK_IMPORTED_MODULE_0__["mergeMap"])(_util_identity__WEBPACK_IMPORTED_MODULE_1__["identity"], concurrent); + return function (source) { return source.lift(new DefaultIfEmptyOperator(defaultValue)); }; } -//# sourceMappingURL=mergeAll.js.map +var DefaultIfEmptyOperator = /*@__PURE__*/ (function () { + function DefaultIfEmptyOperator(defaultValue) { + this.defaultValue = defaultValue; + } + DefaultIfEmptyOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DefaultIfEmptySubscriber(subscriber, this.defaultValue)); + }; + return DefaultIfEmptyOperator; +}()); +var DefaultIfEmptySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DefaultIfEmptySubscriber, _super); + function DefaultIfEmptySubscriber(destination, defaultValue) { + var _this = _super.call(this, destination) || this; + _this.defaultValue = defaultValue; + _this.isEmpty = true; + return _this; + } + DefaultIfEmptySubscriber.prototype._next = function (value) { + this.isEmpty = false; + this.destination.next(value); + }; + DefaultIfEmptySubscriber.prototype._complete = function () { + if (this.isEmpty) { + this.destination.next(this.defaultValue); + } + this.destination.complete(); + }; + return DefaultIfEmptySubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=defaultIfEmpty.js.map /***/ }), -/* 242 */ +/* 259 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeMap", function() { return mergeMap; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MergeMapOperator", function() { return MergeMapOperator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MergeMapSubscriber", function() { return MergeMapSubscriber; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(230); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(229); -/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(231); -/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(226); -/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(243); -/** PURE_IMPORTS_START tslib,_util_subscribeToResult,_OuterSubscriber,_InnerSubscriber,_map,_observable_from PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "delay", function() { return delay; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(186); +/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(260); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(143); +/* harmony import */ var _Notification__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(173); +/** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_Subscriber,_Notification PURE_IMPORTS_END */ -function mergeMap(project, resultSelector, concurrent) { - if (concurrent === void 0) { - concurrent = Number.POSITIVE_INFINITY; - } - if (typeof resultSelector === 'function') { - return function (source) { return source.pipe(mergeMap(function (a, i) { return Object(_observable_from__WEBPACK_IMPORTED_MODULE_5__["from"])(project(a, i)).pipe(Object(_map__WEBPACK_IMPORTED_MODULE_4__["map"])(function (b, ii) { return resultSelector(a, b, i, ii); })); }, concurrent)); }; - } - else if (typeof resultSelector === 'number') { - concurrent = resultSelector; +function delay(delay, scheduler) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; } - return function (source) { return source.lift(new MergeMapOperator(project, concurrent)); }; + var absoluteDelay = Object(_util_isDate__WEBPACK_IMPORTED_MODULE_2__["isDate"])(delay); + var delayFor = absoluteDelay ? (+delay - scheduler.now()) : Math.abs(delay); + return function (source) { return source.lift(new DelayOperator(delayFor, scheduler)); }; } -var MergeMapOperator = /*@__PURE__*/ (function () { - function MergeMapOperator(project, concurrent) { - if (concurrent === void 0) { - concurrent = Number.POSITIVE_INFINITY; - } - this.project = project; - this.concurrent = concurrent; +var DelayOperator = /*@__PURE__*/ (function () { + function DelayOperator(delay, scheduler) { + this.delay = delay; + this.scheduler = scheduler; } - MergeMapOperator.prototype.call = function (observer, source) { - return source.subscribe(new MergeMapSubscriber(observer, this.project, this.concurrent)); + DelayOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DelaySubscriber(subscriber, this.delay, this.scheduler)); }; - return MergeMapOperator; + return DelayOperator; }()); - -var MergeMapSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MergeMapSubscriber, _super); - function MergeMapSubscriber(destination, project, concurrent) { - if (concurrent === void 0) { - concurrent = Number.POSITIVE_INFINITY; - } +var DelaySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DelaySubscriber, _super); + function DelaySubscriber(destination, delay, scheduler) { var _this = _super.call(this, destination) || this; - _this.project = project; - _this.concurrent = concurrent; - _this.hasCompleted = false; - _this.buffer = []; - _this.active = 0; - _this.index = 0; + _this.delay = delay; + _this.scheduler = scheduler; + _this.queue = []; + _this.active = false; + _this.errored = false; return _this; } - MergeMapSubscriber.prototype._next = function (value) { - if (this.active < this.concurrent) { - this._tryNext(value); + DelaySubscriber.dispatch = function (state) { + var source = state.source; + var queue = source.queue; + var scheduler = state.scheduler; + var destination = state.destination; + while (queue.length > 0 && (queue[0].time - scheduler.now()) <= 0) { + queue.shift().notification.observe(destination); + } + if (queue.length > 0) { + var delay_1 = Math.max(0, queue[0].time - scheduler.now()); + this.schedule(state, delay_1); } else { - this.buffer.push(value); + this.unsubscribe(); + source.active = false; } }; - MergeMapSubscriber.prototype._tryNext = function (value) { - var result; - var index = this.index++; - try { - result = this.project(value, index); - } - catch (err) { - this.destination.error(err); + DelaySubscriber.prototype._schedule = function (scheduler) { + this.active = true; + var destination = this.destination; + destination.add(scheduler.schedule(DelaySubscriber.dispatch, this.delay, { + source: this, destination: this.destination, scheduler: scheduler + })); + }; + DelaySubscriber.prototype.scheduleNotification = function (notification) { + if (this.errored === true) { return; } - this.active++; - this._innerSub(result, value, index); + var scheduler = this.scheduler; + var message = new DelayMessage(scheduler.now() + this.delay, notification); + this.queue.push(message); + if (this.active === false) { + this._schedule(scheduler); + } }; - MergeMapSubscriber.prototype._innerSub = function (ish, value, index) { - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_3__["InnerSubscriber"](this, undefined, undefined); - var destination = this.destination; - destination.add(innerSubscriber); - Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_1__["subscribeToResult"])(this, ish, value, index, innerSubscriber); + DelaySubscriber.prototype._next = function (value) { + this.scheduleNotification(_Notification__WEBPACK_IMPORTED_MODULE_4__["Notification"].createNext(value)); }; - MergeMapSubscriber.prototype._complete = function () { - this.hasCompleted = true; - if (this.active === 0 && this.buffer.length === 0) { - this.destination.complete(); - } + DelaySubscriber.prototype._error = function (err) { + this.errored = true; + this.queue = []; + this.destination.error(err); this.unsubscribe(); }; - MergeMapSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.destination.next(innerValue); - }; - MergeMapSubscriber.prototype.notifyComplete = function (innerSub) { - var buffer = this.buffer; - this.remove(innerSub); - this.active--; - if (buffer.length > 0) { - this._next(buffer.shift()); - } - else if (this.active === 0 && this.hasCompleted) { - this.destination.complete(); - } + DelaySubscriber.prototype._complete = function () { + this.scheduleNotification(_Notification__WEBPACK_IMPORTED_MODULE_4__["Notification"].createComplete()); + this.unsubscribe(); }; - return MergeMapSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); - -//# sourceMappingURL=mergeMap.js.map + return DelaySubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__["Subscriber"])); +var DelayMessage = /*@__PURE__*/ (function () { + function DelayMessage(time, notification) { + this.time = time; + this.notification = notification; + } + return DelayMessage; +}()); +//# sourceMappingURL=delay.js.map /***/ }), -/* 243 */ +/* 260 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "from", function() { return from; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _util_subscribeTo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(232); -/* harmony import */ var _scheduled_scheduled__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(244); -/** PURE_IMPORTS_START _Observable,_util_subscribeTo,_scheduled_scheduled PURE_IMPORTS_END */ - - - -function from(input, scheduler) { - if (!scheduler) { - if (input instanceof _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]) { - return input; - } - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](Object(_util_subscribeTo__WEBPACK_IMPORTED_MODULE_1__["subscribeTo"])(input)); - } - else { - return Object(_scheduled_scheduled__WEBPACK_IMPORTED_MODULE_2__["scheduled"])(input, scheduler); - } +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isDate", function() { return isDate; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function isDate(value) { + return value instanceof Date && !isNaN(+value); } -//# sourceMappingURL=from.js.map +//# sourceMappingURL=isDate.js.map /***/ }), -/* 244 */ +/* 261 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scheduled", function() { return scheduled; }); -/* harmony import */ var _scheduleObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(245); -/* harmony import */ var _schedulePromise__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(246); -/* harmony import */ var _scheduleArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(208); -/* harmony import */ var _scheduleIterable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(247); -/* harmony import */ var _util_isInteropObservable__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(248); -/* harmony import */ var _util_isPromise__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(238); -/* harmony import */ var _util_isArrayLike__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(237); -/* harmony import */ var _util_isIterable__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(249); -/** PURE_IMPORTS_START _scheduleObservable,_schedulePromise,_scheduleArray,_scheduleIterable,_util_isInteropObservable,_util_isPromise,_util_isArrayLike,_util_isIterable PURE_IMPORTS_END */ - - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "delayWhen", function() { return delayWhen; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(141); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_Subscriber,_Observable,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function scheduled(input, scheduler) { - if (input != null) { - if (Object(_util_isInteropObservable__WEBPACK_IMPORTED_MODULE_4__["isInteropObservable"])(input)) { - return Object(_scheduleObservable__WEBPACK_IMPORTED_MODULE_0__["scheduleObservable"])(input, scheduler); +function delayWhen(delayDurationSelector, subscriptionDelay) { + if (subscriptionDelay) { + return function (source) { + return new SubscriptionDelayObservable(source, subscriptionDelay) + .lift(new DelayWhenOperator(delayDurationSelector)); + }; + } + return function (source) { return source.lift(new DelayWhenOperator(delayDurationSelector)); }; +} +var DelayWhenOperator = /*@__PURE__*/ (function () { + function DelayWhenOperator(delayDurationSelector) { + this.delayDurationSelector = delayDurationSelector; + } + DelayWhenOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DelayWhenSubscriber(subscriber, this.delayDurationSelector)); + }; + return DelayWhenOperator; +}()); +var DelayWhenSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DelayWhenSubscriber, _super); + function DelayWhenSubscriber(destination, delayDurationSelector) { + var _this = _super.call(this, destination) || this; + _this.delayDurationSelector = delayDurationSelector; + _this.completed = false; + _this.delayNotifierSubscriptions = []; + _this.index = 0; + return _this; + } + DelayWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.destination.next(outerValue); + this.removeSubscription(innerSub); + this.tryComplete(); + }; + DelayWhenSubscriber.prototype.notifyError = function (error, innerSub) { + this._error(error); + }; + DelayWhenSubscriber.prototype.notifyComplete = function (innerSub) { + var value = this.removeSubscription(innerSub); + if (value) { + this.destination.next(value); } - else if (Object(_util_isPromise__WEBPACK_IMPORTED_MODULE_5__["isPromise"])(input)) { - return Object(_schedulePromise__WEBPACK_IMPORTED_MODULE_1__["schedulePromise"])(input, scheduler); + this.tryComplete(); + }; + DelayWhenSubscriber.prototype._next = function (value) { + var index = this.index++; + try { + var delayNotifier = this.delayDurationSelector(value, index); + if (delayNotifier) { + this.tryDelay(delayNotifier, value); + } } - else if (Object(_util_isArrayLike__WEBPACK_IMPORTED_MODULE_6__["isArrayLike"])(input)) { - return Object(_scheduleArray__WEBPACK_IMPORTED_MODULE_2__["scheduleArray"])(input, scheduler); + catch (err) { + this.destination.error(err); } - else if (Object(_util_isIterable__WEBPACK_IMPORTED_MODULE_7__["isIterable"])(input) || typeof input === 'string') { - return Object(_scheduleIterable__WEBPACK_IMPORTED_MODULE_3__["scheduleIterable"])(input, scheduler); + }; + DelayWhenSubscriber.prototype._complete = function () { + this.completed = true; + this.tryComplete(); + this.unsubscribe(); + }; + DelayWhenSubscriber.prototype.removeSubscription = function (subscription) { + subscription.unsubscribe(); + var subscriptionIdx = this.delayNotifierSubscriptions.indexOf(subscription); + if (subscriptionIdx !== -1) { + this.delayNotifierSubscriptions.splice(subscriptionIdx, 1); + } + return subscription.outerValue; + }; + DelayWhenSubscriber.prototype.tryDelay = function (delayNotifier, value) { + var notifierSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, delayNotifier, value); + if (notifierSubscription && !notifierSubscription.closed) { + var destination = this.destination; + destination.add(notifierSubscription); + this.delayNotifierSubscriptions.push(notifierSubscription); + } + }; + DelayWhenSubscriber.prototype.tryComplete = function () { + if (this.completed && this.delayNotifierSubscriptions.length === 0) { + this.destination.complete(); } + }; + return DelayWhenSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); +var SubscriptionDelayObservable = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubscriptionDelayObservable, _super); + function SubscriptionDelayObservable(source, subscriptionDelay) { + var _this = _super.call(this) || this; + _this.source = source; + _this.subscriptionDelay = subscriptionDelay; + return _this; } - throw new TypeError((input !== null && typeof input || input) + ' is not observable'); -} -//# sourceMappingURL=scheduled.js.map + SubscriptionDelayObservable.prototype._subscribe = function (subscriber) { + this.subscriptionDelay.subscribe(new SubscriptionDelaySubscriber(subscriber, this.source)); + }; + return SubscriptionDelayObservable; +}(_Observable__WEBPACK_IMPORTED_MODULE_2__["Observable"])); +var SubscriptionDelaySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubscriptionDelaySubscriber, _super); + function SubscriptionDelaySubscriber(parent, source) { + var _this = _super.call(this) || this; + _this.parent = parent; + _this.source = source; + _this.sourceSubscribed = false; + return _this; + } + SubscriptionDelaySubscriber.prototype._next = function (unused) { + this.subscribeToSource(); + }; + SubscriptionDelaySubscriber.prototype._error = function (err) { + this.unsubscribe(); + this.parent.error(err); + }; + SubscriptionDelaySubscriber.prototype._complete = function () { + this.unsubscribe(); + this.subscribeToSource(); + }; + SubscriptionDelaySubscriber.prototype.subscribeToSource = function () { + if (!this.sourceSubscribed) { + this.sourceSubscribed = true; + this.unsubscribe(); + this.source.subscribe(this.parent); + } + }; + return SubscriptionDelaySubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=delayWhen.js.map /***/ }), -/* 245 */ +/* 262 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scheduleObservable", function() { return scheduleObservable; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(177); -/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(183); -/** PURE_IMPORTS_START _Observable,_Subscription,_symbol_observable PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dematerialize", function() { return dematerialize; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function scheduleObservable(input, scheduler) { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - var sub = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); - sub.add(scheduler.schedule(function () { - var observable = input[_symbol_observable__WEBPACK_IMPORTED_MODULE_2__["observable"]](); - sub.add(observable.subscribe({ - next: function (value) { sub.add(scheduler.schedule(function () { return subscriber.next(value); })); }, - error: function (err) { sub.add(scheduler.schedule(function () { return subscriber.error(err); })); }, - complete: function () { sub.add(scheduler.schedule(function () { return subscriber.complete(); })); }, - })); - })); - return sub; - }); +function dematerialize() { + return function dematerializeOperatorFunction(source) { + return source.lift(new DeMaterializeOperator()); + }; } -//# sourceMappingURL=scheduleObservable.js.map +var DeMaterializeOperator = /*@__PURE__*/ (function () { + function DeMaterializeOperator() { + } + DeMaterializeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DeMaterializeSubscriber(subscriber)); + }; + return DeMaterializeOperator; +}()); +var DeMaterializeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DeMaterializeSubscriber, _super); + function DeMaterializeSubscriber(destination) { + return _super.call(this, destination) || this; + } + DeMaterializeSubscriber.prototype._next = function (value) { + value.observe(this.destination); + }; + return DeMaterializeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=dematerialize.js.map /***/ }), -/* 246 */ +/* 263 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "schedulePromise", function() { return schedulePromise; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(177); -/** PURE_IMPORTS_START _Observable,_Subscription PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distinct", function() { return distinct; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DistinctSubscriber", function() { return DistinctSubscriber; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function schedulePromise(input, scheduler) { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - var sub = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); - sub.add(scheduler.schedule(function () { - return input.then(function (value) { - sub.add(scheduler.schedule(function () { - subscriber.next(value); - sub.add(scheduler.schedule(function () { return subscriber.complete(); })); - })); - }, function (err) { - sub.add(scheduler.schedule(function () { return subscriber.error(err); })); - }); - })); - return sub; - }); + +function distinct(keySelector, flushes) { + return function (source) { return source.lift(new DistinctOperator(keySelector, flushes)); }; } -//# sourceMappingURL=schedulePromise.js.map +var DistinctOperator = /*@__PURE__*/ (function () { + function DistinctOperator(keySelector, flushes) { + this.keySelector = keySelector; + this.flushes = flushes; + } + DistinctOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DistinctSubscriber(subscriber, this.keySelector, this.flushes)); + }; + return DistinctOperator; +}()); +var DistinctSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DistinctSubscriber, _super); + function DistinctSubscriber(destination, keySelector, flushes) { + var _this = _super.call(this, destination) || this; + _this.keySelector = keySelector; + _this.values = new Set(); + if (flushes) { + _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, flushes)); + } + return _this; + } + DistinctSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.values.clear(); + }; + DistinctSubscriber.prototype.notifyError = function (error, innerSub) { + this._error(error); + }; + DistinctSubscriber.prototype._next = function (value) { + if (this.keySelector) { + this._useKeySelector(value); + } + else { + this._finalizeNext(value, value); + } + }; + DistinctSubscriber.prototype._useKeySelector = function (value) { + var key; + var destination = this.destination; + try { + key = this.keySelector(value); + } + catch (err) { + destination.error(err); + return; + } + this._finalizeNext(key, value); + }; + DistinctSubscriber.prototype._finalizeNext = function (key, value) { + var values = this.values; + if (!values.has(key)) { + values.add(key); + this.destination.next(value); + } + }; + return DistinctSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); + +//# sourceMappingURL=distinct.js.map /***/ }), -/* 247 */ +/* 264 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scheduleIterable", function() { return scheduleIterable; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(177); -/* harmony import */ var _symbol_iterator__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(235); -/** PURE_IMPORTS_START _Observable,_Subscription,_symbol_iterator PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distinctUntilChanged", function() { return distinctUntilChanged; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function scheduleIterable(input, scheduler) { - if (!input) { - throw new Error('Iterable cannot be null'); +function distinctUntilChanged(compare, keySelector) { + return function (source) { return source.lift(new DistinctUntilChangedOperator(compare, keySelector)); }; +} +var DistinctUntilChangedOperator = /*@__PURE__*/ (function () { + function DistinctUntilChangedOperator(compare, keySelector) { + this.compare = compare; + this.keySelector = keySelector; } - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - var sub = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); - var iterator; - sub.add(function () { - if (iterator && typeof iterator.return === 'function') { - iterator.return(); + DistinctUntilChangedOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DistinctUntilChangedSubscriber(subscriber, this.compare, this.keySelector)); + }; + return DistinctUntilChangedOperator; +}()); +var DistinctUntilChangedSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DistinctUntilChangedSubscriber, _super); + function DistinctUntilChangedSubscriber(destination, compare, keySelector) { + var _this = _super.call(this, destination) || this; + _this.keySelector = keySelector; + _this.hasKey = false; + if (typeof compare === 'function') { + _this.compare = compare; + } + return _this; + } + DistinctUntilChangedSubscriber.prototype.compare = function (x, y) { + return x === y; + }; + DistinctUntilChangedSubscriber.prototype._next = function (value) { + var key; + try { + var keySelector = this.keySelector; + key = keySelector ? keySelector(value) : value; + } + catch (err) { + return this.destination.error(err); + } + var result = false; + if (this.hasKey) { + try { + var compare = this.compare; + result = compare(this.key, key); } - }); - sub.add(scheduler.schedule(function () { - iterator = input[_symbol_iterator__WEBPACK_IMPORTED_MODULE_2__["iterator"]](); - sub.add(scheduler.schedule(function () { - if (subscriber.closed) { - return; - } - var value; - var done; - try { - var result = iterator.next(); - value = result.value; - done = result.done; - } - catch (err) { - subscriber.error(err); - return; - } - if (done) { - subscriber.complete(); - } - else { - subscriber.next(value); - this.schedule(); - } - })); - })); - return sub; - }); -} -//# sourceMappingURL=scheduleIterable.js.map + catch (err) { + return this.destination.error(err); + } + } + else { + this.hasKey = true; + } + if (!result) { + this.key = key; + this.destination.next(value); + } + }; + return DistinctUntilChangedSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=distinctUntilChanged.js.map /***/ }), -/* 248 */ +/* 265 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isInteropObservable", function() { return isInteropObservable; }); -/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(183); -/** PURE_IMPORTS_START _symbol_observable PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distinctUntilKeyChanged", function() { return distinctUntilKeyChanged; }); +/* harmony import */ var _distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(264); +/** PURE_IMPORTS_START _distinctUntilChanged PURE_IMPORTS_END */ -function isInteropObservable(input) { - return input && typeof input[_symbol_observable__WEBPACK_IMPORTED_MODULE_0__["observable"]] === 'function'; +function distinctUntilKeyChanged(key, compare) { + return Object(_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__["distinctUntilChanged"])(function (x, y) { return compare ? compare(x[key], y[key]) : x[key] === y[key]; }); } -//# sourceMappingURL=isInteropObservable.js.map +//# sourceMappingURL=distinctUntilKeyChanged.js.map /***/ }), -/* 249 */ +/* 266 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isIterable", function() { return isIterable; }); -/* harmony import */ var _symbol_iterator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(235); -/** PURE_IMPORTS_START _symbol_iterator PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "elementAt", function() { return elementAt; }); +/* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(193); +/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(235); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(267); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(258); +/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(268); +/** PURE_IMPORTS_START _util_ArgumentOutOfRangeError,_filter,_throwIfEmpty,_defaultIfEmpty,_take PURE_IMPORTS_END */ -function isIterable(input) { - return input && typeof input[_symbol_iterator__WEBPACK_IMPORTED_MODULE_0__["iterator"]] === 'function'; + + + + +function elementAt(index, defaultValue) { + if (index < 0) { + throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_0__["ArgumentOutOfRangeError"](); + } + var hasDefaultValue = arguments.length >= 2; + return function (source) { + return source.pipe(Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(function (v, i) { return i === index; }), Object(_take__WEBPACK_IMPORTED_MODULE_4__["take"])(1), hasDefaultValue + ? Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__["defaultIfEmpty"])(defaultValue) + : Object(_throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__["throwIfEmpty"])(function () { return new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_0__["ArgumentOutOfRangeError"](); })); + }; } -//# sourceMappingURL=isIterable.js.map +//# sourceMappingURL=elementAt.js.map /***/ }), -/* 250 */ +/* 267 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defer", function() { return defer; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(243); -/* harmony import */ var _empty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(203); -/** PURE_IMPORTS_START _Observable,_from,_empty PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "throwIfEmpty", function() { return throwIfEmpty; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(194); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_util_EmptyError,_Subscriber PURE_IMPORTS_END */ -function defer(observableFactory) { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - var input; - try { - input = observableFactory(); +function throwIfEmpty(errorFactory) { + if (errorFactory === void 0) { + errorFactory = defaultErrorFactory; + } + return function (source) { + return source.lift(new ThrowIfEmptyOperator(errorFactory)); + }; +} +var ThrowIfEmptyOperator = /*@__PURE__*/ (function () { + function ThrowIfEmptyOperator(errorFactory) { + this.errorFactory = errorFactory; + } + ThrowIfEmptyOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ThrowIfEmptySubscriber(subscriber, this.errorFactory)); + }; + return ThrowIfEmptyOperator; +}()); +var ThrowIfEmptySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ThrowIfEmptySubscriber, _super); + function ThrowIfEmptySubscriber(destination, errorFactory) { + var _this = _super.call(this, destination) || this; + _this.errorFactory = errorFactory; + _this.hasValue = false; + return _this; + } + ThrowIfEmptySubscriber.prototype._next = function (value) { + this.hasValue = true; + this.destination.next(value); + }; + ThrowIfEmptySubscriber.prototype._complete = function () { + if (!this.hasValue) { + var err = void 0; + try { + err = this.errorFactory(); + } + catch (e) { + err = e; + } + this.destination.error(err); } - catch (err) { - subscriber.error(err); - return undefined; + else { + return this.destination.complete(); } - var source = input ? Object(_from__WEBPACK_IMPORTED_MODULE_1__["from"])(input) : Object(_empty__WEBPACK_IMPORTED_MODULE_2__["empty"])(); - return source.subscribe(subscriber); - }); + }; + return ThrowIfEmptySubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_2__["Subscriber"])); +function defaultErrorFactory() { + return new _util_EmptyError__WEBPACK_IMPORTED_MODULE_1__["EmptyError"](); } -//# sourceMappingURL=defer.js.map +//# sourceMappingURL=throwIfEmpty.js.map /***/ }), -/* 251 */ +/* 268 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "forkJoin", function() { return forkJoin; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(178); -/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(226); -/* harmony import */ var _util_isObject__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(179); -/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(243); -/** PURE_IMPORTS_START _Observable,_util_isArray,_operators_map,_util_isObject,_from PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "take", function() { return take; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(193); +/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(174); +/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError,_observable_empty PURE_IMPORTS_END */ -function forkJoin() { - var sources = []; - for (var _i = 0; _i < arguments.length; _i++) { - sources[_i] = arguments[_i]; - } - if (sources.length === 1) { - var first_1 = sources[0]; - if (Object(_util_isArray__WEBPACK_IMPORTED_MODULE_1__["isArray"])(first_1)) { - return forkJoinInternal(first_1, null); +function take(count) { + return function (source) { + if (count === 0) { + return Object(_observable_empty__WEBPACK_IMPORTED_MODULE_3__["empty"])(); } - if (Object(_util_isObject__WEBPACK_IMPORTED_MODULE_3__["isObject"])(first_1) && Object.getPrototypeOf(first_1) === Object.prototype) { - var keys = Object.keys(first_1); - return forkJoinInternal(keys.map(function (key) { return first_1[key]; }), keys); + else { + return source.lift(new TakeOperator(count)); } - } - if (typeof sources[sources.length - 1] === 'function') { - var resultSelector_1 = sources.pop(); - sources = (sources.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_1__["isArray"])(sources[0])) ? sources[0] : sources; - return forkJoinInternal(sources, null).pipe(Object(_operators_map__WEBPACK_IMPORTED_MODULE_2__["map"])(function (args) { return resultSelector_1.apply(void 0, args); })); - } - return forkJoinInternal(sources, null); + }; } -function forkJoinInternal(sources, keys) { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - var len = sources.length; - if (len === 0) { - subscriber.complete(); - return; +var TakeOperator = /*@__PURE__*/ (function () { + function TakeOperator(total) { + this.total = total; + if (this.total < 0) { + throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__["ArgumentOutOfRangeError"]; } - var values = new Array(len); - var completed = 0; - var emitted = 0; - var _loop_1 = function (i) { - var source = Object(_from__WEBPACK_IMPORTED_MODULE_4__["from"])(sources[i]); - var hasValue = false; - subscriber.add(source.subscribe({ - next: function (value) { - if (!hasValue) { - hasValue = true; - emitted++; - } - values[i] = value; - }, - error: function (err) { return subscriber.error(err); }, - complete: function () { - completed++; - if (completed === len || !hasValue) { - if (emitted === len) { - subscriber.next(keys ? - keys.reduce(function (result, key, i) { return (result[key] = values[i], result); }, {}) : - values); - } - subscriber.complete(); - } - } - })); - }; - for (var i = 0; i < len; i++) { - _loop_1(i); + } + TakeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TakeSubscriber(subscriber, this.total)); + }; + return TakeOperator; +}()); +var TakeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeSubscriber, _super); + function TakeSubscriber(destination, total) { + var _this = _super.call(this, destination) || this; + _this.total = total; + _this.count = 0; + return _this; + } + TakeSubscriber.prototype._next = function (value) { + var total = this.total; + var count = ++this.count; + if (count <= total) { + this.destination.next(value); + if (count === total) { + this.destination.complete(); + this.unsubscribe(); + } } - }); -} -//# sourceMappingURL=forkJoin.js.map + }; + return TakeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=take.js.map /***/ }), -/* 252 */ +/* 269 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fromEvent", function() { return fromEvent; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(178); -/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(173); -/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(226); -/** PURE_IMPORTS_START _Observable,_util_isArray,_util_isFunction,_operators_map PURE_IMPORTS_END */ - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "endWith", function() { return endWith; }); +/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(210); +/* harmony import */ var _observable_of__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(175); +/** PURE_IMPORTS_START _observable_concat,_observable_of PURE_IMPORTS_END */ -var toString = /*@__PURE__*/ (function () { return Object.prototype.toString; })(); -function fromEvent(target, eventName, options, resultSelector) { - if (Object(_util_isFunction__WEBPACK_IMPORTED_MODULE_2__["isFunction"])(options)) { - resultSelector = options; - options = undefined; - } - if (resultSelector) { - return fromEvent(target, eventName, options).pipe(Object(_operators_map__WEBPACK_IMPORTED_MODULE_3__["map"])(function (args) { return Object(_util_isArray__WEBPACK_IMPORTED_MODULE_1__["isArray"])(args) ? resultSelector.apply(void 0, args) : resultSelector(args); })); - } - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - function handler(e) { - if (arguments.length > 1) { - subscriber.next(Array.prototype.slice.call(arguments)); - } - else { - subscriber.next(e); - } - } - setupSubscription(target, eventName, handler, subscriber, options); - }); -} -function setupSubscription(sourceObj, eventName, handler, subscriber, options) { - var unsubscribe; - if (isEventTarget(sourceObj)) { - var source_1 = sourceObj; - sourceObj.addEventListener(eventName, handler, options); - unsubscribe = function () { return source_1.removeEventListener(eventName, handler, options); }; - } - else if (isJQueryStyleEventEmitter(sourceObj)) { - var source_2 = sourceObj; - sourceObj.on(eventName, handler); - unsubscribe = function () { return source_2.off(eventName, handler); }; - } - else if (isNodeStyleEventEmitter(sourceObj)) { - var source_3 = sourceObj; - sourceObj.addListener(eventName, handler); - unsubscribe = function () { return source_3.removeListener(eventName, handler); }; - } - else if (sourceObj && sourceObj.length) { - for (var i = 0, len = sourceObj.length; i < len; i++) { - setupSubscription(sourceObj[i], eventName, handler, subscriber, options); - } - } - else { - throw new TypeError('Invalid event target'); +function endWith() { + var array = []; + for (var _i = 0; _i < arguments.length; _i++) { + array[_i] = arguments[_i]; } - subscriber.add(unsubscribe); -} -function isNodeStyleEventEmitter(sourceObj) { - return sourceObj && typeof sourceObj.addListener === 'function' && typeof sourceObj.removeListener === 'function'; -} -function isJQueryStyleEventEmitter(sourceObj) { - return sourceObj && typeof sourceObj.on === 'function' && typeof sourceObj.off === 'function'; -} -function isEventTarget(sourceObj) { - return sourceObj && typeof sourceObj.addEventListener === 'function' && typeof sourceObj.removeEventListener === 'function'; + return function (source) { return Object(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"])(source, _observable_of__WEBPACK_IMPORTED_MODULE_1__["of"].apply(void 0, array)); }; } -//# sourceMappingURL=fromEvent.js.map +//# sourceMappingURL=endWith.js.map /***/ }), -/* 253 */ +/* 270 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fromEventPattern", function() { return fromEventPattern; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(178); -/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(173); -/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(226); -/** PURE_IMPORTS_START _Observable,_util_isArray,_util_isFunction,_operators_map PURE_IMPORTS_END */ - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "every", function() { return every; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function fromEventPattern(addHandler, removeHandler, resultSelector) { - if (resultSelector) { - return fromEventPattern(addHandler, removeHandler).pipe(Object(_operators_map__WEBPACK_IMPORTED_MODULE_3__["map"])(function (args) { return Object(_util_isArray__WEBPACK_IMPORTED_MODULE_1__["isArray"])(args) ? resultSelector.apply(void 0, args) : resultSelector(args); })); +function every(predicate, thisArg) { + return function (source) { return source.lift(new EveryOperator(predicate, thisArg, source)); }; +} +var EveryOperator = /*@__PURE__*/ (function () { + function EveryOperator(predicate, thisArg, source) { + this.predicate = predicate; + this.thisArg = thisArg; + this.source = source; } - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - var handler = function () { - var e = []; - for (var _i = 0; _i < arguments.length; _i++) { - e[_i] = arguments[_i]; - } - return subscriber.next(e.length === 1 ? e[0] : e); - }; - var retValue; + EveryOperator.prototype.call = function (observer, source) { + return source.subscribe(new EverySubscriber(observer, this.predicate, this.thisArg, this.source)); + }; + return EveryOperator; +}()); +var EverySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](EverySubscriber, _super); + function EverySubscriber(destination, predicate, thisArg, source) { + var _this = _super.call(this, destination) || this; + _this.predicate = predicate; + _this.thisArg = thisArg; + _this.source = source; + _this.index = 0; + _this.thisArg = thisArg || _this; + return _this; + } + EverySubscriber.prototype.notifyComplete = function (everyValueMatch) { + this.destination.next(everyValueMatch); + this.destination.complete(); + }; + EverySubscriber.prototype._next = function (value) { + var result = false; try { - retValue = addHandler(handler); + result = this.predicate.call(this.thisArg, value, this.index++, this.source); } catch (err) { - subscriber.error(err); - return undefined; + this.destination.error(err); + return; } - if (!Object(_util_isFunction__WEBPACK_IMPORTED_MODULE_2__["isFunction"])(removeHandler)) { - return undefined; + if (!result) { + this.notifyComplete(false); } - return function () { return removeHandler(handler, retValue); }; - }); -} -//# sourceMappingURL=fromEventPattern.js.map + }; + EverySubscriber.prototype._complete = function () { + this.notifyComplete(true); + }; + return EverySubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=every.js.map /***/ }), -/* 254 */ +/* 271 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "generate", function() { return generate; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(220); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(205); -/** PURE_IMPORTS_START _Observable,_util_identity,_util_isScheduler PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "exhaust", function() { return exhaust; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function generate(initialStateOrOptions, condition, iterate, resultSelectorOrObservable, scheduler) { - var resultSelector; - var initialState; - if (arguments.length == 1) { - var options = initialStateOrOptions; - initialState = options.initialState; - condition = options.condition; - iterate = options.iterate; - resultSelector = options.resultSelector || _util_identity__WEBPACK_IMPORTED_MODULE_1__["identity"]; - scheduler = options.scheduler; - } - else if (resultSelectorOrObservable === undefined || Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_2__["isScheduler"])(resultSelectorOrObservable)) { - initialState = initialStateOrOptions; - resultSelector = _util_identity__WEBPACK_IMPORTED_MODULE_1__["identity"]; - scheduler = resultSelectorOrObservable; - } - else { - initialState = initialStateOrOptions; - resultSelector = resultSelectorOrObservable; - } - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - var state = initialState; - if (scheduler) { - return scheduler.schedule(dispatch, 0, { - subscriber: subscriber, - iterate: iterate, - condition: condition, - resultSelector: resultSelector, - state: state - }); - } - do { - if (condition) { - var conditionResult = void 0; - try { - conditionResult = condition(state); - } - catch (err) { - subscriber.error(err); - return undefined; - } - if (!conditionResult) { - subscriber.complete(); - break; - } - } - var value = void 0; - try { - value = resultSelector(state); - } - catch (err) { - subscriber.error(err); - return undefined; - } - subscriber.next(value); - if (subscriber.closed) { - break; - } - try { - state = iterate(state); - } - catch (err) { - subscriber.error(err); - return undefined; - } - } while (true); - return undefined; - }); +function exhaust() { + return function (source) { return source.lift(new SwitchFirstOperator()); }; } -function dispatch(state) { - var subscriber = state.subscriber, condition = state.condition; - if (subscriber.closed) { - return undefined; - } - if (state.needIterate) { - try { - state.state = state.iterate(state.state); - } - catch (err) { - subscriber.error(err); - return undefined; - } +var SwitchFirstOperator = /*@__PURE__*/ (function () { + function SwitchFirstOperator() { } - else { - state.needIterate = true; + SwitchFirstOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SwitchFirstSubscriber(subscriber)); + }; + return SwitchFirstOperator; +}()); +var SwitchFirstSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SwitchFirstSubscriber, _super); + function SwitchFirstSubscriber(destination) { + var _this = _super.call(this, destination) || this; + _this.hasCompleted = false; + _this.hasSubscription = false; + return _this; } - if (condition) { - var conditionResult = void 0; - try { - conditionResult = condition(state.state); - } - catch (err) { - subscriber.error(err); - return undefined; + SwitchFirstSubscriber.prototype._next = function (value) { + if (!this.hasSubscription) { + this.hasSubscription = true; + this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, value)); } - if (!conditionResult) { - subscriber.complete(); - return undefined; + }; + SwitchFirstSubscriber.prototype._complete = function () { + this.hasCompleted = true; + if (!this.hasSubscription) { + this.destination.complete(); } - if (subscriber.closed) { - return undefined; + }; + SwitchFirstSubscriber.prototype.notifyComplete = function (innerSub) { + this.remove(innerSub); + this.hasSubscription = false; + if (this.hasCompleted) { + this.destination.complete(); } - } - var value; - try { - value = state.resultSelector(state.state); - } - catch (err) { - subscriber.error(err); - return undefined; - } - if (subscriber.closed) { - return undefined; - } - subscriber.next(value); - if (subscriber.closed) { - return undefined; - } - return this.schedule(state); -} -//# sourceMappingURL=generate.js.map + }; + return SwitchFirstSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +//# sourceMappingURL=exhaust.js.map /***/ }), -/* 255 */ +/* 272 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "iif", function() { return iif; }); -/* harmony import */ var _defer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(250); -/* harmony import */ var _empty__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(203); -/** PURE_IMPORTS_START _defer,_empty PURE_IMPORTS_END */ - - -function iif(condition, trueResult, falseResult) { - if (trueResult === void 0) { - trueResult = _empty__WEBPACK_IMPORTED_MODULE_1__["EMPTY"]; - } - if (falseResult === void 0) { - falseResult = _empty__WEBPACK_IMPORTED_MODULE_1__["EMPTY"]; - } - return Object(_defer__WEBPACK_IMPORTED_MODULE_0__["defer"])(function () { return condition() ? trueResult : falseResult; }); -} -//# sourceMappingURL=iif.js.map +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "exhaustMap", function() { return exhaustMap; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(200); +/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(202); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(201); +/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(197); +/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(214); +/** PURE_IMPORTS_START tslib,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult,_map,_observable_from PURE_IMPORTS_END */ -/***/ }), -/* 256 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "interval", function() { return interval; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(215); -/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(257); -/** PURE_IMPORTS_START _Observable,_scheduler_async,_util_isNumeric PURE_IMPORTS_END */ -function interval(period, scheduler) { - if (period === void 0) { - period = 0; +function exhaustMap(project, resultSelector) { + if (resultSelector) { + return function (source) { return source.pipe(exhaustMap(function (a, i) { return Object(_observable_from__WEBPACK_IMPORTED_MODULE_5__["from"])(project(a, i)).pipe(Object(_map__WEBPACK_IMPORTED_MODULE_4__["map"])(function (b, ii) { return resultSelector(a, b, i, ii); })); })); }; } - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; + return function (source) { + return source.lift(new ExhaustMapOperator(project)); + }; +} +var ExhaustMapOperator = /*@__PURE__*/ (function () { + function ExhaustMapOperator(project) { + this.project = project; } - if (!Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_2__["isNumeric"])(period) || period < 0) { - period = 0; + ExhaustMapOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ExhaustMapSubscriber(subscriber, this.project)); + }; + return ExhaustMapOperator; +}()); +var ExhaustMapSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ExhaustMapSubscriber, _super); + function ExhaustMapSubscriber(destination, project) { + var _this = _super.call(this, destination) || this; + _this.project = project; + _this.hasSubscription = false; + _this.hasCompleted = false; + _this.index = 0; + return _this; } - if (!scheduler || typeof scheduler.schedule !== 'function') { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; - } - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - subscriber.add(scheduler.schedule(dispatch, period, { subscriber: subscriber, counter: 0, period: period })); - return subscriber; - }); -} -function dispatch(state) { - var subscriber = state.subscriber, counter = state.counter, period = state.period; - subscriber.next(counter); - this.schedule({ subscriber: subscriber, counter: counter + 1, period: period }, period); -} -//# sourceMappingURL=interval.js.map - - -/***/ }), -/* 257 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isNumeric", function() { return isNumeric; }); -/* harmony import */ var _isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(178); -/** PURE_IMPORTS_START _isArray PURE_IMPORTS_END */ - -function isNumeric(val) { - return !Object(_isArray__WEBPACK_IMPORTED_MODULE_0__["isArray"])(val) && (val - parseFloat(val) + 1) >= 0; -} -//# sourceMappingURL=isNumeric.js.map + ExhaustMapSubscriber.prototype._next = function (value) { + if (!this.hasSubscription) { + this.tryNext(value); + } + }; + ExhaustMapSubscriber.prototype.tryNext = function (value) { + var result; + var index = this.index++; + try { + result = this.project(value, index); + } + catch (err) { + this.destination.error(err); + return; + } + this.hasSubscription = true; + this._innerSub(result, value, index); + }; + ExhaustMapSubscriber.prototype._innerSub = function (result, value, index) { + var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](this, undefined, undefined); + var destination = this.destination; + destination.add(innerSubscriber); + Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, result, value, index, innerSubscriber); + }; + ExhaustMapSubscriber.prototype._complete = function () { + this.hasCompleted = true; + if (!this.hasSubscription) { + this.destination.complete(); + } + this.unsubscribe(); + }; + ExhaustMapSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.destination.next(innerValue); + }; + ExhaustMapSubscriber.prototype.notifyError = function (err) { + this.destination.error(err); + }; + ExhaustMapSubscriber.prototype.notifyComplete = function (innerSub) { + var destination = this.destination; + destination.remove(innerSub); + this.hasSubscription = false; + if (this.hasCompleted) { + this.destination.complete(); + } + }; + return ExhaustMapSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +//# sourceMappingURL=exhaustMap.js.map /***/ }), -/* 258 */ +/* 273 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return merge; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(205); -/* harmony import */ var _operators_mergeAll__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(241); -/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(206); -/** PURE_IMPORTS_START _Observable,_util_isScheduler,_operators_mergeAll,_fromArray PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "expand", function() { return expand; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExpandOperator", function() { return ExpandOperator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExpandSubscriber", function() { return ExpandSubscriber; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function merge() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; +function expand(project, concurrent, scheduler) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; } - var concurrent = Number.POSITIVE_INFINITY; - var scheduler = null; - var last = observables[observables.length - 1]; - if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_1__["isScheduler"])(last)) { - scheduler = observables.pop(); - if (observables.length > 1 && typeof observables[observables.length - 1] === 'number') { - concurrent = observables.pop(); - } + if (scheduler === void 0) { + scheduler = undefined; } - else if (typeof last === 'number') { - concurrent = observables.pop(); + concurrent = (concurrent || 0) < 1 ? Number.POSITIVE_INFINITY : concurrent; + return function (source) { return source.lift(new ExpandOperator(project, concurrent, scheduler)); }; +} +var ExpandOperator = /*@__PURE__*/ (function () { + function ExpandOperator(project, concurrent, scheduler) { + this.project = project; + this.concurrent = concurrent; + this.scheduler = scheduler; } - if (scheduler === null && observables.length === 1 && observables[0] instanceof _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]) { - return observables[0]; + ExpandOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ExpandSubscriber(subscriber, this.project, this.concurrent, this.scheduler)); + }; + return ExpandOperator; +}()); + +var ExpandSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ExpandSubscriber, _super); + function ExpandSubscriber(destination, project, concurrent, scheduler) { + var _this = _super.call(this, destination) || this; + _this.project = project; + _this.concurrent = concurrent; + _this.scheduler = scheduler; + _this.index = 0; + _this.active = 0; + _this.hasCompleted = false; + if (concurrent < Number.POSITIVE_INFINITY) { + _this.buffer = []; + } + return _this; } - return Object(_operators_mergeAll__WEBPACK_IMPORTED_MODULE_2__["mergeAll"])(concurrent)(Object(_fromArray__WEBPACK_IMPORTED_MODULE_3__["fromArray"])(observables, scheduler)); -} -//# sourceMappingURL=merge.js.map + ExpandSubscriber.dispatch = function (arg) { + var subscriber = arg.subscriber, result = arg.result, value = arg.value, index = arg.index; + subscriber.subscribeToProjection(result, value, index); + }; + ExpandSubscriber.prototype._next = function (value) { + var destination = this.destination; + if (destination.closed) { + this._complete(); + return; + } + var index = this.index++; + if (this.active < this.concurrent) { + destination.next(value); + try { + var project = this.project; + var result = project(value, index); + if (!this.scheduler) { + this.subscribeToProjection(result, value, index); + } + else { + var state = { subscriber: this, result: result, value: value, index: index }; + var destination_1 = this.destination; + destination_1.add(this.scheduler.schedule(ExpandSubscriber.dispatch, 0, state)); + } + } + catch (e) { + destination.error(e); + } + } + else { + this.buffer.push(value); + } + }; + ExpandSubscriber.prototype.subscribeToProjection = function (result, value, index) { + this.active++; + var destination = this.destination; + destination.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, result, value, index)); + }; + ExpandSubscriber.prototype._complete = function () { + this.hasCompleted = true; + if (this.hasCompleted && this.active === 0) { + this.destination.complete(); + } + this.unsubscribe(); + }; + ExpandSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this._next(innerValue); + }; + ExpandSubscriber.prototype.notifyComplete = function (innerSub) { + var buffer = this.buffer; + var destination = this.destination; + destination.remove(innerSub); + this.active--; + if (buffer && buffer.length > 0) { + this._next(buffer.shift()); + } + if (this.hasCompleted && this.active === 0) { + this.destination.complete(); + } + }; + return ExpandSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); + +//# sourceMappingURL=expand.js.map /***/ }), -/* 259 */ +/* 274 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NEVER", function() { return NEVER; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "never", function() { return never; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(185); -/** PURE_IMPORTS_START _Observable,_util_noop PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "finalize", function() { return finalize; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(148); +/** PURE_IMPORTS_START tslib,_Subscriber,_Subscription PURE_IMPORTS_END */ -var NEVER = /*@__PURE__*/ new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](_util_noop__WEBPACK_IMPORTED_MODULE_1__["noop"]); -function never() { - return NEVER; + +function finalize(callback) { + return function (source) { return source.lift(new FinallyOperator(callback)); }; } -//# sourceMappingURL=never.js.map +var FinallyOperator = /*@__PURE__*/ (function () { + function FinallyOperator(callback) { + this.callback = callback; + } + FinallyOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new FinallySubscriber(subscriber, this.callback)); + }; + return FinallyOperator; +}()); +var FinallySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FinallySubscriber, _super); + function FinallySubscriber(destination, callback) { + var _this = _super.call(this, destination) || this; + _this.add(new _Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"](callback)); + return _this; + } + return FinallySubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=finalize.js.map /***/ }), -/* 260 */ +/* 275 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return onErrorResumeNext; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(243); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(178); -/* harmony import */ var _empty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(203); -/** PURE_IMPORTS_START _Observable,_from,_util_isArray,_empty PURE_IMPORTS_END */ - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "find", function() { return find; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FindValueOperator", function() { return FindValueOperator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FindValueSubscriber", function() { return FindValueSubscriber; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function onErrorResumeNext() { - var sources = []; - for (var _i = 0; _i < arguments.length; _i++) { - sources[_i] = arguments[_i]; +function find(predicate, thisArg) { + if (typeof predicate !== 'function') { + throw new TypeError('predicate is not a function'); } - if (sources.length === 0) { - return _empty__WEBPACK_IMPORTED_MODULE_3__["EMPTY"]; + return function (source) { return source.lift(new FindValueOperator(predicate, source, false, thisArg)); }; +} +var FindValueOperator = /*@__PURE__*/ (function () { + function FindValueOperator(predicate, source, yieldIndex, thisArg) { + this.predicate = predicate; + this.source = source; + this.yieldIndex = yieldIndex; + this.thisArg = thisArg; } - var first = sources[0], remainder = sources.slice(1); - if (sources.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_2__["isArray"])(first)) { - return onErrorResumeNext.apply(void 0, first); + FindValueOperator.prototype.call = function (observer, source) { + return source.subscribe(new FindValueSubscriber(observer, this.predicate, this.source, this.yieldIndex, this.thisArg)); + }; + return FindValueOperator; +}()); + +var FindValueSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FindValueSubscriber, _super); + function FindValueSubscriber(destination, predicate, source, yieldIndex, thisArg) { + var _this = _super.call(this, destination) || this; + _this.predicate = predicate; + _this.source = source; + _this.yieldIndex = yieldIndex; + _this.thisArg = thisArg; + _this.index = 0; + return _this; } - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - var subNext = function () { return subscriber.add(onErrorResumeNext.apply(void 0, remainder).subscribe(subscriber)); }; - return Object(_from__WEBPACK_IMPORTED_MODULE_1__["from"])(first).subscribe({ - next: function (value) { subscriber.next(value); }, - error: subNext, - complete: subNext, - }); - }); -} -//# sourceMappingURL=onErrorResumeNext.js.map + FindValueSubscriber.prototype.notifyComplete = function (value) { + var destination = this.destination; + destination.next(value); + destination.complete(); + this.unsubscribe(); + }; + FindValueSubscriber.prototype._next = function (value) { + var _a = this, predicate = _a.predicate, thisArg = _a.thisArg; + var index = this.index++; + try { + var result = predicate.call(thisArg || this, value, index, this.source); + if (result) { + this.notifyComplete(this.yieldIndex ? index : value); + } + } + catch (err) { + this.destination.error(err); + } + }; + FindValueSubscriber.prototype._complete = function () { + this.notifyComplete(this.yieldIndex ? -1 : undefined); + }; + return FindValueSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); + +//# sourceMappingURL=find.js.map /***/ }), -/* 261 */ +/* 276 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pairs", function() { return pairs; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dispatch", function() { return dispatch; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(177); -/** PURE_IMPORTS_START _Observable,_Subscription PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findIndex", function() { return findIndex; }); +/* harmony import */ var _operators_find__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(275); +/** PURE_IMPORTS_START _operators_find PURE_IMPORTS_END */ -function pairs(obj, scheduler) { - if (!scheduler) { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - var keys = Object.keys(obj); - for (var i = 0; i < keys.length && !subscriber.closed; i++) { - var key = keys[i]; - if (obj.hasOwnProperty(key)) { - subscriber.next([key, obj[key]]); - } - } - subscriber.complete(); - }); - } - else { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - var keys = Object.keys(obj); - var subscription = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); - subscription.add(scheduler.schedule(dispatch, 0, { keys: keys, index: 0, subscriber: subscriber, subscription: subscription, obj: obj })); - return subscription; - }); - } -} -function dispatch(state) { - var keys = state.keys, index = state.index, subscriber = state.subscriber, subscription = state.subscription, obj = state.obj; - if (!subscriber.closed) { - if (index < keys.length) { - var key = keys[index]; - subscriber.next([key, obj[key]]); - subscription.add(this.schedule({ keys: keys, index: index + 1, subscriber: subscriber, subscription: subscription, obj: obj })); - } - else { - subscriber.complete(); - } - } +function findIndex(predicate, thisArg) { + return function (source) { return source.lift(new _operators_find__WEBPACK_IMPORTED_MODULE_0__["FindValueOperator"](predicate, source, true, thisArg)); }; } -//# sourceMappingURL=pairs.js.map +//# sourceMappingURL=findIndex.js.map /***/ }), -/* 262 */ +/* 277 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return partition; }); -/* harmony import */ var _util_not__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(263); -/* harmony import */ var _util_subscribeTo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(232); -/* harmony import */ var _operators_filter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(264); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(170); -/** PURE_IMPORTS_START _util_not,_util_subscribeTo,_operators_filter,_Observable PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "first", function() { return first; }); +/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(194); +/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(235); +/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(268); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(258); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(267); +/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(191); +/** PURE_IMPORTS_START _util_EmptyError,_filter,_take,_defaultIfEmpty,_throwIfEmpty,_util_identity PURE_IMPORTS_END */ -function partition(source, predicate, thisArg) { - return [ - Object(_operators_filter__WEBPACK_IMPORTED_MODULE_2__["filter"])(predicate, thisArg)(new _Observable__WEBPACK_IMPORTED_MODULE_3__["Observable"](Object(_util_subscribeTo__WEBPACK_IMPORTED_MODULE_1__["subscribeTo"])(source))), - Object(_operators_filter__WEBPACK_IMPORTED_MODULE_2__["filter"])(Object(_util_not__WEBPACK_IMPORTED_MODULE_0__["not"])(predicate, thisArg))(new _Observable__WEBPACK_IMPORTED_MODULE_3__["Observable"](Object(_util_subscribeTo__WEBPACK_IMPORTED_MODULE_1__["subscribeTo"])(source))) - ]; + + +function first(predicate, defaultValue) { + var hasDefaultValue = arguments.length >= 2; + return function (source) { return source.pipe(predicate ? Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(function (v, i) { return predicate(v, i, source); }) : _util_identity__WEBPACK_IMPORTED_MODULE_5__["identity"], Object(_take__WEBPACK_IMPORTED_MODULE_2__["take"])(1), hasDefaultValue ? Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__["defaultIfEmpty"])(defaultValue) : Object(_throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__["throwIfEmpty"])(function () { return new _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__["EmptyError"](); })); }; } -//# sourceMappingURL=partition.js.map +//# sourceMappingURL=first.js.map /***/ }), -/* 263 */ +/* 278 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "not", function() { return not; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function not(pred, thisArg) { - function notPred() { - return !(notPred.pred.apply(notPred.thisArg, arguments)); - } - notPred.pred = pred; - notPred.thisArg = thisArg; - return notPred; +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ignoreElements", function() { return ignoreElements; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function ignoreElements() { + return function ignoreElementsOperatorFunction(source) { + return source.lift(new IgnoreElementsOperator()); + }; } -//# sourceMappingURL=not.js.map +var IgnoreElementsOperator = /*@__PURE__*/ (function () { + function IgnoreElementsOperator() { + } + IgnoreElementsOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new IgnoreElementsSubscriber(subscriber)); + }; + return IgnoreElementsOperator; +}()); +var IgnoreElementsSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](IgnoreElementsSubscriber, _super); + function IgnoreElementsSubscriber() { + return _super !== null && _super.apply(this, arguments) || this; + } + IgnoreElementsSubscriber.prototype._next = function (unused) { + }; + return IgnoreElementsSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=ignoreElements.js.map /***/ }), -/* 264 */ +/* 279 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "filter", function() { return filter; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isEmpty", function() { return isEmpty; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function filter(predicate, thisArg) { - return function filterOperatorFunction(source) { - return source.lift(new FilterOperator(predicate, thisArg)); - }; +function isEmpty() { + return function (source) { return source.lift(new IsEmptyOperator()); }; } -var FilterOperator = /*@__PURE__*/ (function () { - function FilterOperator(predicate, thisArg) { - this.predicate = predicate; - this.thisArg = thisArg; +var IsEmptyOperator = /*@__PURE__*/ (function () { + function IsEmptyOperator() { } - FilterOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new FilterSubscriber(subscriber, this.predicate, this.thisArg)); + IsEmptyOperator.prototype.call = function (observer, source) { + return source.subscribe(new IsEmptySubscriber(observer)); }; - return FilterOperator; + return IsEmptyOperator; }()); -var FilterSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FilterSubscriber, _super); - function FilterSubscriber(destination, predicate, thisArg) { - var _this = _super.call(this, destination) || this; - _this.predicate = predicate; - _this.thisArg = thisArg; - _this.count = 0; - return _this; +var IsEmptySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](IsEmptySubscriber, _super); + function IsEmptySubscriber(destination) { + return _super.call(this, destination) || this; } - FilterSubscriber.prototype._next = function (value) { - var result; - try { - result = this.predicate.call(this.thisArg, value, this.count++); - } - catch (err) { - this.destination.error(err); - return; - } - if (result) { - this.destination.next(value); - } + IsEmptySubscriber.prototype.notifyComplete = function (isEmpty) { + var destination = this.destination; + destination.next(isEmpty); + destination.complete(); }; - return FilterSubscriber; + IsEmptySubscriber.prototype._next = function (value) { + this.notifyComplete(false); + }; + IsEmptySubscriber.prototype._complete = function () { + this.notifyComplete(true); + }; + return IsEmptySubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=filter.js.map +//# sourceMappingURL=isEmpty.js.map /***/ }), -/* 265 */ +/* 280 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "race", function() { return race; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RaceOperator", function() { return RaceOperator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RaceSubscriber", function() { return RaceSubscriber; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(178); -/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(206); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_util_isArray,_fromArray,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "last", function() { return last; }); +/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(194); +/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(235); +/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(281); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(267); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(258); +/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(191); +/** PURE_IMPORTS_START _util_EmptyError,_filter,_takeLast,_throwIfEmpty,_defaultIfEmpty,_util_identity PURE_IMPORTS_END */ -function race() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; - } - if (observables.length === 1) { - if (Object(_util_isArray__WEBPACK_IMPORTED_MODULE_1__["isArray"])(observables[0])) { - observables = observables[0]; - } - else { - return observables[0]; - } - } - return Object(_fromArray__WEBPACK_IMPORTED_MODULE_2__["fromArray"])(observables, undefined).lift(new RaceOperator()); -} -var RaceOperator = /*@__PURE__*/ (function () { - function RaceOperator() { - } - RaceOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new RaceSubscriber(subscriber)); - }; - return RaceOperator; -}()); -var RaceSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RaceSubscriber, _super); - function RaceSubscriber(destination) { +function last(predicate, defaultValue) { + var hasDefaultValue = arguments.length >= 2; + return function (source) { return source.pipe(predicate ? Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(function (v, i) { return predicate(v, i, source); }) : _util_identity__WEBPACK_IMPORTED_MODULE_5__["identity"], Object(_takeLast__WEBPACK_IMPORTED_MODULE_2__["takeLast"])(1), hasDefaultValue ? Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__["defaultIfEmpty"])(defaultValue) : Object(_throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__["throwIfEmpty"])(function () { return new _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__["EmptyError"](); })); }; +} +//# sourceMappingURL=last.js.map + + +/***/ }), +/* 281 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "takeLast", function() { return takeLast; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(193); +/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(174); +/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError,_observable_empty PURE_IMPORTS_END */ + + + + +function takeLast(count) { + return function takeLastOperatorFunction(source) { + if (count === 0) { + return Object(_observable_empty__WEBPACK_IMPORTED_MODULE_3__["empty"])(); + } + else { + return source.lift(new TakeLastOperator(count)); + } + }; +} +var TakeLastOperator = /*@__PURE__*/ (function () { + function TakeLastOperator(total) { + this.total = total; + if (this.total < 0) { + throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__["ArgumentOutOfRangeError"]; + } + } + TakeLastOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TakeLastSubscriber(subscriber, this.total)); + }; + return TakeLastOperator; +}()); +var TakeLastSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeLastSubscriber, _super); + function TakeLastSubscriber(destination, total) { var _this = _super.call(this, destination) || this; - _this.hasFirst = false; - _this.observables = []; - _this.subscriptions = []; + _this.total = total; + _this.ring = new Array(); + _this.count = 0; return _this; } - RaceSubscriber.prototype._next = function (observable) { - this.observables.push(observable); - }; - RaceSubscriber.prototype._complete = function () { - var observables = this.observables; - var len = observables.length; - if (len === 0) { - this.destination.complete(); + TakeLastSubscriber.prototype._next = function (value) { + var ring = this.ring; + var total = this.total; + var count = this.count++; + if (ring.length < total) { + ring.push(value); } else { - for (var i = 0; i < len && !this.hasFirst; i++) { - var observable = observables[i]; - var subscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, observable, observable, i); - if (this.subscriptions) { - this.subscriptions.push(subscription); - } - this.add(subscription); - } - this.observables = null; + var index = count % total; + ring[index] = value; } }; - RaceSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - if (!this.hasFirst) { - this.hasFirst = true; - for (var i = 0; i < this.subscriptions.length; i++) { - if (i !== outerIndex) { - var subscription = this.subscriptions[i]; - subscription.unsubscribe(); - this.remove(subscription); - } + TakeLastSubscriber.prototype._complete = function () { + var destination = this.destination; + var count = this.count; + if (count > 0) { + var total = this.count >= this.total ? this.total : this.count; + var ring = this.ring; + for (var i = 0; i < total; i++) { + var idx = (count++) % total; + destination.next(ring[idx]); } - this.subscriptions = null; } - this.destination.next(innerValue); + destination.complete(); }; - return RaceSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); - -//# sourceMappingURL=race.js.map + return TakeLastSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=takeLast.js.map /***/ }), -/* 266 */ +/* 282 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "range", function() { return range; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dispatch", function() { return dispatch; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapTo", function() { return mapTo; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function range(start, count, scheduler) { - if (start === void 0) { - start = 0; - } - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - if (count === undefined) { - count = start; - start = 0; - } - var index = 0; - var current = start; - if (scheduler) { - return scheduler.schedule(dispatch, 0, { - index: index, count: count, start: start, subscriber: subscriber - }); - } - else { - do { - if (index++ >= count) { - subscriber.complete(); - break; - } - subscriber.next(current++); - if (subscriber.closed) { - break; - } - } while (true); - } - return undefined; - }); + +function mapTo(value) { + return function (source) { return source.lift(new MapToOperator(value)); }; } -function dispatch(state) { - var start = state.start, index = state.index, count = state.count, subscriber = state.subscriber; - if (index >= count) { - subscriber.complete(); - return; +var MapToOperator = /*@__PURE__*/ (function () { + function MapToOperator(value) { + this.value = value; } - subscriber.next(start); - if (subscriber.closed) { - return; + MapToOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new MapToSubscriber(subscriber, this.value)); + }; + return MapToOperator; +}()); +var MapToSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MapToSubscriber, _super); + function MapToSubscriber(destination, value) { + var _this = _super.call(this, destination) || this; + _this.value = value; + return _this; } - state.index = index + 1; - state.start = start + 1; - this.schedule(state); -} -//# sourceMappingURL=range.js.map + MapToSubscriber.prototype._next = function (x) { + this.destination.next(this.value); + }; + return MapToSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=mapTo.js.map /***/ }), -/* 267 */ +/* 283 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timer", function() { return timer; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(215); -/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(257); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(205); -/** PURE_IMPORTS_START _Observable,_scheduler_async,_util_isNumeric,_util_isScheduler PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "materialize", function() { return materialize; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _Notification__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(173); +/** PURE_IMPORTS_START tslib,_Subscriber,_Notification PURE_IMPORTS_END */ -function timer(dueTime, periodOrScheduler, scheduler) { - if (dueTime === void 0) { - dueTime = 0; - } - var period = -1; - if (Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_2__["isNumeric"])(periodOrScheduler)) { - period = Number(periodOrScheduler) < 1 && 1 || Number(periodOrScheduler); - } - else if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_3__["isScheduler"])(periodOrScheduler)) { - scheduler = periodOrScheduler; - } - if (!Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_3__["isScheduler"])(scheduler)) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; - } - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - var due = Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_2__["isNumeric"])(dueTime) - ? dueTime - : (+dueTime - scheduler.now()); - return scheduler.schedule(dispatch, due, { - index: 0, period: period, subscriber: subscriber - }); - }); +function materialize() { + return function materializeOperatorFunction(source) { + return source.lift(new MaterializeOperator()); + }; } -function dispatch(state) { - var index = state.index, period = state.period, subscriber = state.subscriber; - subscriber.next(index); - if (subscriber.closed) { - return; +var MaterializeOperator = /*@__PURE__*/ (function () { + function MaterializeOperator() { } - else if (period === -1) { - return subscriber.complete(); + MaterializeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new MaterializeSubscriber(subscriber)); + }; + return MaterializeOperator; +}()); +var MaterializeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MaterializeSubscriber, _super); + function MaterializeSubscriber(destination) { + return _super.call(this, destination) || this; } - state.index = index + 1; - this.schedule(state, period); + MaterializeSubscriber.prototype._next = function (value) { + this.destination.next(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createNext(value)); + }; + MaterializeSubscriber.prototype._error = function (err) { + var destination = this.destination; + destination.next(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createError(err)); + destination.complete(); + }; + MaterializeSubscriber.prototype._complete = function () { + var destination = this.destination; + destination.next(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createComplete()); + destination.complete(); + }; + return MaterializeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=materialize.js.map + + +/***/ }), +/* 284 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "max", function() { return max; }); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(285); +/** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ + +function max(comparer) { + var max = (typeof comparer === 'function') + ? function (x, y) { return comparer(x, y) > 0 ? x : y; } + : function (x, y) { return x > y ? x : y; }; + return Object(_reduce__WEBPACK_IMPORTED_MODULE_0__["reduce"])(max); } -//# sourceMappingURL=timer.js.map +//# sourceMappingURL=max.js.map /***/ }), -/* 268 */ +/* 285 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "using", function() { return using; }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(170); -/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(243); -/* harmony import */ var _empty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(203); -/** PURE_IMPORTS_START _Observable,_from,_empty PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return reduce; }); +/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(286); +/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(281); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(258); +/* harmony import */ var _util_pipe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(155); +/** PURE_IMPORTS_START _scan,_takeLast,_defaultIfEmpty,_util_pipe PURE_IMPORTS_END */ -function using(resourceFactory, observableFactory) { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (subscriber) { - var resource; - try { - resource = resourceFactory(); + +function reduce(accumulator, seed) { + if (arguments.length >= 2) { + return function reduceOperatorFunctionWithSeed(source) { + return Object(_util_pipe__WEBPACK_IMPORTED_MODULE_3__["pipe"])(Object(_scan__WEBPACK_IMPORTED_MODULE_0__["scan"])(accumulator, seed), Object(_takeLast__WEBPACK_IMPORTED_MODULE_1__["takeLast"])(1), Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__["defaultIfEmpty"])(seed))(source); + }; + } + return function reduceOperatorFunction(source) { + return Object(_util_pipe__WEBPACK_IMPORTED_MODULE_3__["pipe"])(Object(_scan__WEBPACK_IMPORTED_MODULE_0__["scan"])(function (acc, value, index) { return accumulator(acc, value, index + 1); }), Object(_takeLast__WEBPACK_IMPORTED_MODULE_1__["takeLast"])(1))(source); + }; +} +//# sourceMappingURL=reduce.js.map + + +/***/ }), +/* 286 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scan", function() { return scan; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function scan(accumulator, seed) { + var hasSeed = false; + if (arguments.length >= 2) { + hasSeed = true; + } + return function scanOperatorFunction(source) { + return source.lift(new ScanOperator(accumulator, seed, hasSeed)); + }; +} +var ScanOperator = /*@__PURE__*/ (function () { + function ScanOperator(accumulator, seed, hasSeed) { + if (hasSeed === void 0) { + hasSeed = false; } - catch (err) { - subscriber.error(err); - return undefined; + this.accumulator = accumulator; + this.seed = seed; + this.hasSeed = hasSeed; + } + ScanOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ScanSubscriber(subscriber, this.accumulator, this.seed, this.hasSeed)); + }; + return ScanOperator; +}()); +var ScanSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ScanSubscriber, _super); + function ScanSubscriber(destination, accumulator, _seed, hasSeed) { + var _this = _super.call(this, destination) || this; + _this.accumulator = accumulator; + _this._seed = _seed; + _this.hasSeed = hasSeed; + _this.index = 0; + return _this; + } + Object.defineProperty(ScanSubscriber.prototype, "seed", { + get: function () { + return this._seed; + }, + set: function (value) { + this.hasSeed = true; + this._seed = value; + }, + enumerable: true, + configurable: true + }); + ScanSubscriber.prototype._next = function (value) { + if (!this.hasSeed) { + this.seed = value; + this.destination.next(value); + } + else { + return this._tryNext(value); } + }; + ScanSubscriber.prototype._tryNext = function (value) { + var index = this.index++; var result; try { - result = observableFactory(resource); + result = this.accumulator(this.seed, value, index); } catch (err) { - subscriber.error(err); - return undefined; + this.destination.error(err); } - var source = result ? Object(_from__WEBPACK_IMPORTED_MODULE_1__["from"])(result) : _empty__WEBPACK_IMPORTED_MODULE_2__["EMPTY"]; - var subscription = source.subscribe(subscriber); - return function () { - subscription.unsubscribe(); - if (resource) { - resource.unsubscribe(); - } - }; - }); + this.seed = result; + this.destination.next(result); + }; + return ScanSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=scan.js.map + + +/***/ }), +/* 287 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return merge; }); +/* harmony import */ var _observable_merge__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(229); +/** PURE_IMPORTS_START _observable_merge PURE_IMPORTS_END */ + +function merge() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + return function (source) { return source.lift.call(_observable_merge__WEBPACK_IMPORTED_MODULE_0__["merge"].apply(void 0, [source].concat(observables))); }; } -//# sourceMappingURL=using.js.map +//# sourceMappingURL=merge.js.map /***/ }), -/* 269 */ +/* 288 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return zip; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ZipOperator", function() { return ZipOperator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ZipSubscriber", function() { return ZipSubscriber; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(206); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(178); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(172); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(230); -/* harmony import */ var _internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(235); -/** PURE_IMPORTS_START tslib,_fromArray,_util_isArray,_Subscriber,_OuterSubscriber,_util_subscribeToResult,_.._internal_symbol_iterator PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeMapTo", function() { return mergeMapTo; }); +/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(213); +/** PURE_IMPORTS_START _mergeMap PURE_IMPORTS_END */ + +function mergeMapTo(innerObservable, resultSelector, concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; + } + if (typeof resultSelector === 'function') { + return Object(_mergeMap__WEBPACK_IMPORTED_MODULE_0__["mergeMap"])(function () { return innerObservable; }, resultSelector, concurrent); + } + if (typeof resultSelector === 'number') { + concurrent = resultSelector; + } + return Object(_mergeMap__WEBPACK_IMPORTED_MODULE_0__["mergeMap"])(function () { return innerObservable; }, concurrent); +} +//# sourceMappingURL=mergeMapTo.js.map +/***/ }), +/* 289 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeScan", function() { return mergeScan; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MergeScanOperator", function() { return MergeScanOperator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MergeScanSubscriber", function() { return MergeScanSubscriber; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(201); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(200); +/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(202); +/** PURE_IMPORTS_START tslib,_util_subscribeToResult,_OuterSubscriber,_InnerSubscriber PURE_IMPORTS_END */ -function zip() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; - } - var resultSelector = observables[observables.length - 1]; - if (typeof resultSelector === 'function') { - observables.pop(); +function mergeScan(accumulator, seed, concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; } - return Object(_fromArray__WEBPACK_IMPORTED_MODULE_1__["fromArray"])(observables, undefined).lift(new ZipOperator(resultSelector)); + return function (source) { return source.lift(new MergeScanOperator(accumulator, seed, concurrent)); }; } -var ZipOperator = /*@__PURE__*/ (function () { - function ZipOperator(resultSelector) { - this.resultSelector = resultSelector; +var MergeScanOperator = /*@__PURE__*/ (function () { + function MergeScanOperator(accumulator, seed, concurrent) { + this.accumulator = accumulator; + this.seed = seed; + this.concurrent = concurrent; } - ZipOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ZipSubscriber(subscriber, this.resultSelector)); + MergeScanOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new MergeScanSubscriber(subscriber, this.accumulator, this.seed, this.concurrent)); }; - return ZipOperator; + return MergeScanOperator; }()); -var ZipSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ZipSubscriber, _super); - function ZipSubscriber(destination, resultSelector, values) { - if (values === void 0) { - values = Object.create(null); - } +var MergeScanSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MergeScanSubscriber, _super); + function MergeScanSubscriber(destination, accumulator, acc, concurrent) { var _this = _super.call(this, destination) || this; - _this.iterators = []; + _this.accumulator = accumulator; + _this.acc = acc; + _this.concurrent = concurrent; + _this.hasValue = false; + _this.hasCompleted = false; + _this.buffer = []; _this.active = 0; - _this.resultSelector = (typeof resultSelector === 'function') ? resultSelector : null; - _this.values = values; + _this.index = 0; return _this; } - ZipSubscriber.prototype._next = function (value) { - var iterators = this.iterators; - if (Object(_util_isArray__WEBPACK_IMPORTED_MODULE_2__["isArray"])(value)) { - iterators.push(new StaticArrayIterator(value)); - } - else if (typeof value[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__["iterator"]] === 'function') { - iterators.push(new StaticIterator(value[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__["iterator"]]())); + MergeScanSubscriber.prototype._next = function (value) { + if (this.active < this.concurrent) { + var index = this.index++; + var destination = this.destination; + var ish = void 0; + try { + var accumulator = this.accumulator; + ish = accumulator(this.acc, value, index); + } + catch (e) { + return destination.error(e); + } + this.active++; + this._innerSub(ish, value, index); } else { - iterators.push(new ZipBufferIterator(this.destination, this, value)); + this.buffer.push(value); } }; - ZipSubscriber.prototype._complete = function () { - var iterators = this.iterators; - var len = iterators.length; - this.unsubscribe(); - if (len === 0) { + MergeScanSubscriber.prototype._innerSub = function (ish, value, index) { + var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_3__["InnerSubscriber"](this, undefined, undefined); + var destination = this.destination; + destination.add(innerSubscriber); + Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_1__["subscribeToResult"])(this, ish, value, index, innerSubscriber); + }; + MergeScanSubscriber.prototype._complete = function () { + this.hasCompleted = true; + if (this.active === 0 && this.buffer.length === 0) { + if (this.hasValue === false) { + this.destination.next(this.acc); + } this.destination.complete(); - return; - } - this.active = len; - for (var i = 0; i < len; i++) { - var iterator = iterators[i]; - if (iterator.stillUnsubscribed) { - var destination = this.destination; - destination.add(iterator.subscribe(iterator, i)); - } - else { - this.active--; - } } + this.unsubscribe(); }; - ZipSubscriber.prototype.notifyInactive = function () { - this.active--; - if (this.active === 0) { - this.destination.complete(); - } + MergeScanSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + var destination = this.destination; + this.acc = innerValue; + this.hasValue = true; + destination.next(innerValue); }; - ZipSubscriber.prototype.checkIterators = function () { - var iterators = this.iterators; - var len = iterators.length; + MergeScanSubscriber.prototype.notifyComplete = function (innerSub) { + var buffer = this.buffer; var destination = this.destination; - for (var i = 0; i < len; i++) { - var iterator = iterators[i]; - if (typeof iterator.hasValue === 'function' && !iterator.hasValue()) { - return; - } + destination.remove(innerSub); + this.active--; + if (buffer.length > 0) { + this._next(buffer.shift()); } - var shouldComplete = false; - var args = []; - for (var i = 0; i < len; i++) { - var iterator = iterators[i]; - var result = iterator.next(); - if (iterator.hasCompleted()) { - shouldComplete = true; - } - if (result.done) { - destination.complete(); - return; + else if (this.active === 0 && this.hasCompleted) { + if (this.hasValue === false) { + this.destination.next(this.acc); } - args.push(result.value); + this.destination.complete(); } - if (this.resultSelector) { - this._tryresultSelector(args); + }; + return MergeScanSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); + +//# sourceMappingURL=mergeScan.js.map + + +/***/ }), +/* 290 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "min", function() { return min; }); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(285); +/** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ + +function min(comparer) { + var min = (typeof comparer === 'function') + ? function (x, y) { return comparer(x, y) < 0 ? x : y; } + : function (x, y) { return x < y ? x : y; }; + return Object(_reduce__WEBPACK_IMPORTED_MODULE_0__["reduce"])(min); +} +//# sourceMappingURL=min.js.map + + +/***/ }), +/* 291 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "multicast", function() { return multicast; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MulticastOperator", function() { return MulticastOperator; }); +/* harmony import */ var _observable_ConnectableObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(157); +/** PURE_IMPORTS_START _observable_ConnectableObservable PURE_IMPORTS_END */ + +function multicast(subjectOrSubjectFactory, selector) { + return function multicastOperatorFunction(source) { + var subjectFactory; + if (typeof subjectOrSubjectFactory === 'function') { + subjectFactory = subjectOrSubjectFactory; } else { - destination.next(args); - } - if (shouldComplete) { - destination.complete(); - } - }; - ZipSubscriber.prototype._tryresultSelector = function (args) { - var result; - try { - result = this.resultSelector.apply(this, args); + subjectFactory = function subjectFactory() { + return subjectOrSubjectFactory; + }; } - catch (err) { - this.destination.error(err); - return; + if (typeof selector === 'function') { + return source.lift(new MulticastOperator(subjectFactory, selector)); } - this.destination.next(result); + var connectable = Object.create(source, _observable_ConnectableObservable__WEBPACK_IMPORTED_MODULE_0__["connectableObservableDescriptor"]); + connectable.source = source; + connectable.subjectFactory = subjectFactory; + return connectable; }; - return ZipSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__["Subscriber"])); - -var StaticIterator = /*@__PURE__*/ (function () { - function StaticIterator(iterator) { - this.iterator = iterator; - this.nextResult = iterator.next(); +} +var MulticastOperator = /*@__PURE__*/ (function () { + function MulticastOperator(subjectFactory, selector) { + this.subjectFactory = subjectFactory; + this.selector = selector; } - StaticIterator.prototype.hasValue = function () { - return true; - }; - StaticIterator.prototype.next = function () { - var result = this.nextResult; - this.nextResult = this.iterator.next(); - return result; - }; - StaticIterator.prototype.hasCompleted = function () { - var nextResult = this.nextResult; - return nextResult && nextResult.done; + MulticastOperator.prototype.call = function (subscriber, source) { + var selector = this.selector; + var subject = this.subjectFactory(); + var subscription = selector(subject).subscribe(subscriber); + subscription.add(source.subscribe(subject)); + return subscription; }; - return StaticIterator; + return MulticastOperator; }()); -var StaticArrayIterator = /*@__PURE__*/ (function () { - function StaticArrayIterator(array) { - this.array = array; - this.index = 0; - this.length = 0; - this.length = array.length; + +//# sourceMappingURL=multicast.js.map + + +/***/ }), +/* 292 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return onErrorResumeNext; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNextStatic", function() { return onErrorResumeNextStatic; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(214); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(149); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(200); +/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(202); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_observable_from,_util_isArray,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ + + + + + + +function onErrorResumeNext() { + var nextSources = []; + for (var _i = 0; _i < arguments.length; _i++) { + nextSources[_i] = arguments[_i]; } - StaticArrayIterator.prototype[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__["iterator"]] = function () { - return this; - }; - StaticArrayIterator.prototype.next = function (value) { - var i = this.index++; - var array = this.array; - return i < this.length ? { value: array[i], done: false } : { value: null, done: true }; - }; - StaticArrayIterator.prototype.hasValue = function () { - return this.array.length > this.index; - }; - StaticArrayIterator.prototype.hasCompleted = function () { - return this.array.length === this.index; + if (nextSources.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_2__["isArray"])(nextSources[0])) { + nextSources = nextSources[0]; + } + return function (source) { return source.lift(new OnErrorResumeNextOperator(nextSources)); }; +} +function onErrorResumeNextStatic() { + var nextSources = []; + for (var _i = 0; _i < arguments.length; _i++) { + nextSources[_i] = arguments[_i]; + } + var source = null; + if (nextSources.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_2__["isArray"])(nextSources[0])) { + nextSources = nextSources[0]; + } + source = nextSources.shift(); + return Object(_observable_from__WEBPACK_IMPORTED_MODULE_1__["from"])(source, null).lift(new OnErrorResumeNextOperator(nextSources)); +} +var OnErrorResumeNextOperator = /*@__PURE__*/ (function () { + function OnErrorResumeNextOperator(nextSources) { + this.nextSources = nextSources; + } + OnErrorResumeNextOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new OnErrorResumeNextSubscriber(subscriber, this.nextSources)); }; - return StaticArrayIterator; + return OnErrorResumeNextOperator; }()); -var ZipBufferIterator = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ZipBufferIterator, _super); - function ZipBufferIterator(destination, parent, observable) { +var OnErrorResumeNextSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](OnErrorResumeNextSubscriber, _super); + function OnErrorResumeNextSubscriber(destination, nextSources) { var _this = _super.call(this, destination) || this; - _this.parent = parent; - _this.observable = observable; - _this.stillUnsubscribed = true; - _this.buffer = []; - _this.isComplete = false; + _this.destination = destination; + _this.nextSources = nextSources; return _this; } - ZipBufferIterator.prototype[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__["iterator"]] = function () { - return this; + OnErrorResumeNextSubscriber.prototype.notifyError = function (error, innerSub) { + this.subscribeToNextSource(); }; - ZipBufferIterator.prototype.next = function () { - var buffer = this.buffer; - if (buffer.length === 0 && this.isComplete) { - return { value: null, done: true }; - } - else { - return { value: buffer.shift(), done: false }; - } + OnErrorResumeNextSubscriber.prototype.notifyComplete = function (innerSub) { + this.subscribeToNextSource(); }; - ZipBufferIterator.prototype.hasValue = function () { - return this.buffer.length > 0; + OnErrorResumeNextSubscriber.prototype._error = function (err) { + this.subscribeToNextSource(); + this.unsubscribe(); }; - ZipBufferIterator.prototype.hasCompleted = function () { - return this.buffer.length === 0 && this.isComplete; + OnErrorResumeNextSubscriber.prototype._complete = function () { + this.subscribeToNextSource(); + this.unsubscribe(); }; - ZipBufferIterator.prototype.notifyComplete = function () { - if (this.buffer.length > 0) { - this.isComplete = true; - this.parent.notifyInactive(); + OnErrorResumeNextSubscriber.prototype.subscribeToNextSource = function () { + var next = this.nextSources.shift(); + if (!!next) { + var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_4__["InnerSubscriber"](this, undefined, undefined); + var destination = this.destination; + destination.add(innerSubscriber); + Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_5__["subscribeToResult"])(this, next, undefined, undefined, innerSubscriber); } else { this.destination.complete(); } }; - ZipBufferIterator.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.buffer.push(innerValue); - this.parent.checkIterators(); - }; - ZipBufferIterator.prototype.subscribe = function (value, index) { - return Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_5__["subscribeToResult"])(this, this.observable, this, index); - }; - return ZipBufferIterator; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_4__["OuterSubscriber"])); -//# sourceMappingURL=zip.js.map + return OnErrorResumeNextSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); +//# sourceMappingURL=onErrorResumeNext.js.map /***/ }), -/* 270 */ +/* 293 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(271); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "audit", function() { return _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__["audit"]; }); - -/* harmony import */ var _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(272); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "auditTime", function() { return _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__["auditTime"]; }); - -/* harmony import */ var _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(273); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buffer", function() { return _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__["buffer"]; }); - -/* harmony import */ var _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(274); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferCount", function() { return _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__["bufferCount"]; }); - -/* harmony import */ var _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(275); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferTime", function() { return _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__["bufferTime"]; }); - -/* harmony import */ var _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(276); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferToggle", function() { return _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__["bufferToggle"]; }); - -/* harmony import */ var _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(277); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferWhen", function() { return _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__["bufferWhen"]; }); - -/* harmony import */ var _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(278); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "catchError", function() { return _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__["catchError"]; }); - -/* harmony import */ var _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(279); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineAll", function() { return _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__["combineAll"]; }); - -/* harmony import */ var _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(280); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__["combineLatest"]; }); - -/* harmony import */ var _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(281); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__["concat"]; }); - -/* harmony import */ var _internal_operators_concatAll__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(240); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatAll", function() { return _internal_operators_concatAll__WEBPACK_IMPORTED_MODULE_11__["concatAll"]; }); - -/* harmony import */ var _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(282); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMap", function() { return _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__["concatMap"]; }); - -/* harmony import */ var _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(283); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMapTo", function() { return _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__["concatMapTo"]; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pairwise", function() { return pairwise; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -/* harmony import */ var _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(284); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "count", function() { return _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__["count"]; }); -/* harmony import */ var _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(285); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "debounce", function() { return _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__["debounce"]; }); +function pairwise() { + return function (source) { return source.lift(new PairwiseOperator()); }; +} +var PairwiseOperator = /*@__PURE__*/ (function () { + function PairwiseOperator() { + } + PairwiseOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new PairwiseSubscriber(subscriber)); + }; + return PairwiseOperator; +}()); +var PairwiseSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PairwiseSubscriber, _super); + function PairwiseSubscriber(destination) { + var _this = _super.call(this, destination) || this; + _this.hasPrev = false; + return _this; + } + PairwiseSubscriber.prototype._next = function (value) { + var pair; + if (this.hasPrev) { + pair = [this.prev, value]; + } + else { + this.hasPrev = true; + } + this.prev = value; + if (pair) { + this.destination.next(pair); + } + }; + return PairwiseSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=pairwise.js.map -/* harmony import */ var _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(286); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "debounceTime", function() { return _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__["debounceTime"]; }); -/* harmony import */ var _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(287); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "defaultIfEmpty", function() { return _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__["defaultIfEmpty"]; }); +/***/ }), +/* 294 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -/* harmony import */ var _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(288); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delay", function() { return _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__["delay"]; }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return partition; }); +/* harmony import */ var _util_not__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(234); +/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(235); +/** PURE_IMPORTS_START _util_not,_filter PURE_IMPORTS_END */ -/* harmony import */ var _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(290); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delayWhen", function() { return _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__["delayWhen"]; }); -/* harmony import */ var _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(291); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "dematerialize", function() { return _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__["dematerialize"]; }); +function partition(predicate, thisArg) { + return function (source) { + return [ + Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(predicate, thisArg)(source), + Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(Object(_util_not__WEBPACK_IMPORTED_MODULE_0__["not"])(predicate, thisArg))(source) + ]; + }; +} +//# sourceMappingURL=partition.js.map -/* harmony import */ var _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(292); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinct", function() { return _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__["distinct"]; }); -/* harmony import */ var _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(293); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilChanged", function() { return _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__["distinctUntilChanged"]; }); +/***/ }), +/* 295 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -/* harmony import */ var _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(294); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilKeyChanged", function() { return _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__["distinctUntilKeyChanged"]; }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pluck", function() { return pluck; }); +/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(197); +/** PURE_IMPORTS_START _map PURE_IMPORTS_END */ -/* harmony import */ var _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(295); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "elementAt", function() { return _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__["elementAt"]; }); +function pluck() { + var properties = []; + for (var _i = 0; _i < arguments.length; _i++) { + properties[_i] = arguments[_i]; + } + var length = properties.length; + if (length === 0) { + throw new Error('list of properties cannot be empty.'); + } + return function (source) { return Object(_map__WEBPACK_IMPORTED_MODULE_0__["map"])(plucker(properties, length))(source); }; +} +function plucker(props, length) { + var mapper = function (x) { + var currentProp = x; + for (var i = 0; i < length; i++) { + var p = currentProp[props[i]]; + if (typeof p !== 'undefined') { + currentProp = p; + } + else { + return undefined; + } + } + return currentProp; + }; + return mapper; +} +//# sourceMappingURL=pluck.js.map -/* harmony import */ var _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(298); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "endWith", function() { return _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__["endWith"]; }); -/* harmony import */ var _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(299); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "every", function() { return _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__["every"]; }); +/***/ }), +/* 296 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -/* harmony import */ var _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(300); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaust", function() { return _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__["exhaust"]; }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publish", function() { return publish; }); +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(158); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(291); +/** PURE_IMPORTS_START _Subject,_multicast PURE_IMPORTS_END */ -/* harmony import */ var _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(301); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaustMap", function() { return _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__["exhaustMap"]; }); -/* harmony import */ var _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(302); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "expand", function() { return _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__["expand"]; }); +function publish(selector) { + return selector ? + Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(function () { return new _Subject__WEBPACK_IMPORTED_MODULE_0__["Subject"](); }, selector) : + Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(new _Subject__WEBPACK_IMPORTED_MODULE_0__["Subject"]()); +} +//# sourceMappingURL=publish.js.map -/* harmony import */ var _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(264); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "filter", function() { return _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__["filter"]; }); -/* harmony import */ var _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(303); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "finalize", function() { return _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__["finalize"]; }); +/***/ }), +/* 297 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -/* harmony import */ var _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(304); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "find", function() { return _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__["find"]; }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishBehavior", function() { return publishBehavior; }); +/* harmony import */ var _BehaviorSubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(163); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(291); +/** PURE_IMPORTS_START _BehaviorSubject,_multicast PURE_IMPORTS_END */ -/* harmony import */ var _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(305); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "findIndex", function() { return _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__["findIndex"]; }); -/* harmony import */ var _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(306); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "first", function() { return _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__["first"]; }); +function publishBehavior(value) { + return function (source) { return Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(new _BehaviorSubject__WEBPACK_IMPORTED_MODULE_0__["BehaviorSubject"](value))(source); }; +} +//# sourceMappingURL=publishBehavior.js.map -/* harmony import */ var _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(191); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "groupBy", function() { return _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_35__["groupBy"]; }); -/* harmony import */ var _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(307); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ignoreElements", function() { return _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__["ignoreElements"]; }); +/***/ }), +/* 298 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -/* harmony import */ var _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(308); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "isEmpty", function() { return _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__["isEmpty"]; }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishLast", function() { return publishLast; }); +/* harmony import */ var _AsyncSubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(181); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(291); +/** PURE_IMPORTS_START _AsyncSubject,_multicast PURE_IMPORTS_END */ -/* harmony import */ var _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(309); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "last", function() { return _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__["last"]; }); -/* harmony import */ var _internal_operators_map__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(226); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "map", function() { return _internal_operators_map__WEBPACK_IMPORTED_MODULE_39__["map"]; }); +function publishLast() { + return function (source) { return Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(new _AsyncSubject__WEBPACK_IMPORTED_MODULE_0__["AsyncSubject"]())(source); }; +} +//# sourceMappingURL=publishLast.js.map -/* harmony import */ var _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(311); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mapTo", function() { return _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__["mapTo"]; }); -/* harmony import */ var _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(312); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "materialize", function() { return _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__["materialize"]; }); +/***/ }), +/* 299 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -/* harmony import */ var _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(313); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "max", function() { return _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__["max"]; }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishReplay", function() { return publishReplay; }); +/* harmony import */ var _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(164); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(291); +/** PURE_IMPORTS_START _ReplaySubject,_multicast PURE_IMPORTS_END */ -/* harmony import */ var _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(316); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__["merge"]; }); -/* harmony import */ var _internal_operators_mergeAll__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(241); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeAll", function() { return _internal_operators_mergeAll__WEBPACK_IMPORTED_MODULE_44__["mergeAll"]; }); +function publishReplay(bufferSize, windowTime, selectorOrScheduler, scheduler) { + if (selectorOrScheduler && typeof selectorOrScheduler !== 'function') { + scheduler = selectorOrScheduler; + } + var selector = typeof selectorOrScheduler === 'function' ? selectorOrScheduler : undefined; + var subject = new _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__["ReplaySubject"](bufferSize, windowTime, scheduler); + return function (source) { return Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(function () { return subject; }, selector)(source); }; +} +//# sourceMappingURL=publishReplay.js.map -/* harmony import */ var _internal_operators_mergeMap__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(242); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeMap", function() { return _internal_operators_mergeMap__WEBPACK_IMPORTED_MODULE_45__["mergeMap"]; }); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "flatMap", function() { return _internal_operators_mergeMap__WEBPACK_IMPORTED_MODULE_45__["mergeMap"]; }); +/***/ }), +/* 300 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -/* harmony import */ var _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(317); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeMapTo", function() { return _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__["mergeMapTo"]; }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "race", function() { return race; }); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(149); +/* harmony import */ var _observable_race__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(236); +/** PURE_IMPORTS_START _util_isArray,_observable_race PURE_IMPORTS_END */ -/* harmony import */ var _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(318); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeScan", function() { return _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__["mergeScan"]; }); -/* harmony import */ var _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(319); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "min", function() { return _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__["min"]; }); +function race() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + return function raceOperatorFunction(source) { + if (observables.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_0__["isArray"])(observables[0])) { + observables = observables[0]; + } + return source.lift.call(_observable_race__WEBPACK_IMPORTED_MODULE_1__["race"].apply(void 0, [source].concat(observables))); + }; +} +//# sourceMappingURL=race.js.map -/* harmony import */ var _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(320); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "multicast", function() { return _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__["multicast"]; }); -/* harmony import */ var _internal_operators_observeOn__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(201); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "observeOn", function() { return _internal_operators_observeOn__WEBPACK_IMPORTED_MODULE_50__["observeOn"]; }); +/***/ }), +/* 301 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -/* harmony import */ var _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(321); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__["onErrorResumeNext"]; }); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "repeat", function() { return repeat; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(174); +/** PURE_IMPORTS_START tslib,_Subscriber,_observable_empty PURE_IMPORTS_END */ -/* harmony import */ var _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(322); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pairwise", function() { return _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__["pairwise"]; }); -/* harmony import */ var _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(323); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__["partition"]; }); -/* harmony import */ var _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(324); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pluck", function() { return _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__["pluck"]; }); - -/* harmony import */ var _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(325); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publish", function() { return _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__["publish"]; }); - -/* harmony import */ var _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(326); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishBehavior", function() { return _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__["publishBehavior"]; }); - -/* harmony import */ var _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(327); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishLast", function() { return _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__["publishLast"]; }); - -/* harmony import */ var _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(328); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishReplay", function() { return _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__["publishReplay"]; }); - -/* harmony import */ var _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(329); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "race", function() { return _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__["race"]; }); - -/* harmony import */ var _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(314); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__["reduce"]; }); - -/* harmony import */ var _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(330); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeat", function() { return _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__["repeat"]; }); - -/* harmony import */ var _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(331); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeatWhen", function() { return _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__["repeatWhen"]; }); - -/* harmony import */ var _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(332); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retry", function() { return _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__["retry"]; }); - -/* harmony import */ var _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(333); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retryWhen", function() { return _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__["retryWhen"]; }); - -/* harmony import */ var _internal_operators_refCount__WEBPACK_IMPORTED_MODULE_65__ = __webpack_require__(190); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "refCount", function() { return _internal_operators_refCount__WEBPACK_IMPORTED_MODULE_65__["refCount"]; }); - -/* harmony import */ var _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(334); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sample", function() { return _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__["sample"]; }); - -/* harmony import */ var _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(335); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sampleTime", function() { return _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__["sampleTime"]; }); - -/* harmony import */ var _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(315); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "scan", function() { return _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__["scan"]; }); - -/* harmony import */ var _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(336); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sequenceEqual", function() { return _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__["sequenceEqual"]; }); - -/* harmony import */ var _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(337); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "share", function() { return _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__["share"]; }); - -/* harmony import */ var _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(338); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "shareReplay", function() { return _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__["shareReplay"]; }); - -/* harmony import */ var _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(339); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "single", function() { return _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__["single"]; }); - -/* harmony import */ var _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__ = __webpack_require__(340); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skip", function() { return _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__["skip"]; }); - -/* harmony import */ var _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__ = __webpack_require__(341); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipLast", function() { return _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__["skipLast"]; }); - -/* harmony import */ var _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__ = __webpack_require__(342); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipUntil", function() { return _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__["skipUntil"]; }); - -/* harmony import */ var _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__ = __webpack_require__(343); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipWhile", function() { return _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__["skipWhile"]; }); - -/* harmony import */ var _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__ = __webpack_require__(344); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "startWith", function() { return _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__["startWith"]; }); - -/* harmony import */ var _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__ = __webpack_require__(345); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__["subscribeOn"]; }); - -/* harmony import */ var _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__ = __webpack_require__(347); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__["switchAll"]; }); - -/* harmony import */ var _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__ = __webpack_require__(348); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMap", function() { return _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__["switchMap"]; }); - -/* harmony import */ var _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__ = __webpack_require__(349); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__["switchMapTo"]; }); - -/* harmony import */ var _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__ = __webpack_require__(297); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "take", function() { return _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__["take"]; }); - -/* harmony import */ var _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__ = __webpack_require__(310); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeLast", function() { return _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__["takeLast"]; }); - -/* harmony import */ var _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__ = __webpack_require__(350); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeUntil", function() { return _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__["takeUntil"]; }); - -/* harmony import */ var _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__ = __webpack_require__(351); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeWhile", function() { return _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__["takeWhile"]; }); - -/* harmony import */ var _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__ = __webpack_require__(352); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "tap", function() { return _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__["tap"]; }); - -/* harmony import */ var _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__ = __webpack_require__(353); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttle", function() { return _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__["throttle"]; }); - -/* harmony import */ var _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__ = __webpack_require__(354); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttleTime", function() { return _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__["throttleTime"]; }); - -/* harmony import */ var _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__ = __webpack_require__(296); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throwIfEmpty", function() { return _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__["throwIfEmpty"]; }); - -/* harmony import */ var _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__ = __webpack_require__(355); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeInterval", function() { return _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__["timeInterval"]; }); - -/* harmony import */ var _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__ = __webpack_require__(356); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__["timeout"]; }); - -/* harmony import */ var _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__ = __webpack_require__(357); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeoutWith", function() { return _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__["timeoutWith"]; }); - -/* harmony import */ var _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__ = __webpack_require__(358); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timestamp", function() { return _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__["timestamp"]; }); - -/* harmony import */ var _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__ = __webpack_require__(359); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__["toArray"]; }); - -/* harmony import */ var _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__ = __webpack_require__(360); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "window", function() { return _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__["window"]; }); - -/* harmony import */ var _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__ = __webpack_require__(361); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowCount", function() { return _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__["windowCount"]; }); - -/* harmony import */ var _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__ = __webpack_require__(362); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowTime", function() { return _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__["windowTime"]; }); - -/* harmony import */ var _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__ = __webpack_require__(363); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowToggle", function() { return _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__["windowToggle"]; }); - -/* harmony import */ var _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__ = __webpack_require__(364); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowWhen", function() { return _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__["windowWhen"]; }); - -/* harmony import */ var _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__ = __webpack_require__(365); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "withLatestFrom", function() { return _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__["withLatestFrom"]; }); - -/* harmony import */ var _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__ = __webpack_require__(366); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__["zip"]; }); - -/* harmony import */ var _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__ = __webpack_require__(367); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zipAll", function() { return _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__["zipAll"]; }); - -/** PURE_IMPORTS_START PURE_IMPORTS_END */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//# sourceMappingURL=index.js.map +function repeat(count) { + if (count === void 0) { + count = -1; + } + return function (source) { + if (count === 0) { + return Object(_observable_empty__WEBPACK_IMPORTED_MODULE_2__["empty"])(); + } + else if (count < 0) { + return source.lift(new RepeatOperator(-1, source)); + } + else { + return source.lift(new RepeatOperator(count - 1, source)); + } + }; +} +var RepeatOperator = /*@__PURE__*/ (function () { + function RepeatOperator(count, source) { + this.count = count; + this.source = source; + } + RepeatOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new RepeatSubscriber(subscriber, this.count, this.source)); + }; + return RepeatOperator; +}()); +var RepeatSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RepeatSubscriber, _super); + function RepeatSubscriber(destination, count, source) { + var _this = _super.call(this, destination) || this; + _this.count = count; + _this.source = source; + return _this; + } + RepeatSubscriber.prototype.complete = function () { + if (!this.isStopped) { + var _a = this, source = _a.source, count = _a.count; + if (count === 0) { + return _super.prototype.complete.call(this); + } + else if (count > -1) { + this.count = count - 1; + } + source.subscribe(this._unsubscribeAndRecycle()); + } + }; + return RepeatSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=repeat.js.map /***/ }), -/* 271 */ +/* 302 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "audit", function() { return audit; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "repeatWhen", function() { return repeatWhen; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(158); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_Subject,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function audit(durationSelector) { - return function auditOperatorFunction(source) { - return source.lift(new AuditOperator(durationSelector)); - }; + +function repeatWhen(notifier) { + return function (source) { return source.lift(new RepeatWhenOperator(notifier)); }; } -var AuditOperator = /*@__PURE__*/ (function () { - function AuditOperator(durationSelector) { - this.durationSelector = durationSelector; +var RepeatWhenOperator = /*@__PURE__*/ (function () { + function RepeatWhenOperator(notifier) { + this.notifier = notifier; } - AuditOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new AuditSubscriber(subscriber, this.durationSelector)); + RepeatWhenOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new RepeatWhenSubscriber(subscriber, this.notifier, source)); }; - return AuditOperator; + return RepeatWhenOperator; }()); -var AuditSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AuditSubscriber, _super); - function AuditSubscriber(destination, durationSelector) { +var RepeatWhenSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RepeatWhenSubscriber, _super); + function RepeatWhenSubscriber(destination, notifier, source) { var _this = _super.call(this, destination) || this; - _this.durationSelector = durationSelector; - _this.hasValue = false; + _this.notifier = notifier; + _this.source = source; + _this.sourceIsBeingSubscribedTo = true; return _this; } - AuditSubscriber.prototype._next = function (value) { - this.value = value; - this.hasValue = true; - if (!this.throttled) { - var duration = void 0; - try { - var durationSelector = this.durationSelector; - duration = durationSelector(value); - } - catch (err) { - return this.destination.error(err); - } - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, duration); - if (!innerSubscription || innerSubscription.closed) { - this.clearThrottle(); + RepeatWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.sourceIsBeingSubscribedTo = true; + this.source.subscribe(this); + }; + RepeatWhenSubscriber.prototype.notifyComplete = function (innerSub) { + if (this.sourceIsBeingSubscribedTo === false) { + return _super.prototype.complete.call(this); + } + }; + RepeatWhenSubscriber.prototype.complete = function () { + this.sourceIsBeingSubscribedTo = false; + if (!this.isStopped) { + if (!this.retries) { + this.subscribeToRetries(); } - else { - this.add(this.throttled = innerSubscription); + if (!this.retriesSubscription || this.retriesSubscription.closed) { + return _super.prototype.complete.call(this); } + this._unsubscribeAndRecycle(); + this.notifications.next(); } }; - AuditSubscriber.prototype.clearThrottle = function () { - var _a = this, value = _a.value, hasValue = _a.hasValue, throttled = _a.throttled; - if (throttled) { - this.remove(throttled); - this.throttled = null; - throttled.unsubscribe(); + RepeatWhenSubscriber.prototype._unsubscribe = function () { + var _a = this, notifications = _a.notifications, retriesSubscription = _a.retriesSubscription; + if (notifications) { + notifications.unsubscribe(); + this.notifications = null; } - if (hasValue) { - this.value = null; - this.hasValue = false; - this.destination.next(value); + if (retriesSubscription) { + retriesSubscription.unsubscribe(); + this.retriesSubscription = null; } + this.retries = null; }; - AuditSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex) { - this.clearThrottle(); + RepeatWhenSubscriber.prototype._unsubscribeAndRecycle = function () { + var _unsubscribe = this._unsubscribe; + this._unsubscribe = null; + _super.prototype._unsubscribeAndRecycle.call(this); + this._unsubscribe = _unsubscribe; + return this; }; - AuditSubscriber.prototype.notifyComplete = function () { - this.clearThrottle(); + RepeatWhenSubscriber.prototype.subscribeToRetries = function () { + this.notifications = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); + var retries; + try { + var notifier = this.notifier; + retries = notifier(this.notifications); + } + catch (e) { + return _super.prototype.complete.call(this); + } + this.retries = retries; + this.retriesSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, retries); }; - return AuditSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=audit.js.map + return RepeatWhenSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); +//# sourceMappingURL=repeatWhen.js.map /***/ }), -/* 272 */ +/* 303 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "auditTime", function() { return auditTime; }); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(215); -/* harmony import */ var _audit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(271); -/* harmony import */ var _observable_timer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(267); -/** PURE_IMPORTS_START _scheduler_async,_audit,_observable_timer PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "retry", function() { return retry; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function auditTime(duration, scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; +function retry(count) { + if (count === void 0) { + count = -1; } - return Object(_audit__WEBPACK_IMPORTED_MODULE_1__["audit"])(function () { return Object(_observable_timer__WEBPACK_IMPORTED_MODULE_2__["timer"])(duration, scheduler); }); -} -//# sourceMappingURL=auditTime.js.map - - -/***/ }), -/* 273 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buffer", function() { return buffer; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - - - -function buffer(closingNotifier) { - return function bufferOperatorFunction(source) { - return source.lift(new BufferOperator(closingNotifier)); - }; + return function (source) { return source.lift(new RetryOperator(count, source)); }; } -var BufferOperator = /*@__PURE__*/ (function () { - function BufferOperator(closingNotifier) { - this.closingNotifier = closingNotifier; +var RetryOperator = /*@__PURE__*/ (function () { + function RetryOperator(count, source) { + this.count = count; + this.source = source; } - BufferOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new BufferSubscriber(subscriber, this.closingNotifier)); + RetryOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new RetrySubscriber(subscriber, this.count, this.source)); }; - return BufferOperator; + return RetryOperator; }()); -var BufferSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferSubscriber, _super); - function BufferSubscriber(destination, closingNotifier) { +var RetrySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RetrySubscriber, _super); + function RetrySubscriber(destination, count, source) { var _this = _super.call(this, destination) || this; - _this.buffer = []; - _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, closingNotifier)); + _this.count = count; + _this.source = source; return _this; } - BufferSubscriber.prototype._next = function (value) { - this.buffer.push(value); - }; - BufferSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - var buffer = this.buffer; - this.buffer = []; - this.destination.next(buffer); + RetrySubscriber.prototype.error = function (err) { + if (!this.isStopped) { + var _a = this, source = _a.source, count = _a.count; + if (count === 0) { + return _super.prototype.error.call(this, err); + } + else if (count > -1) { + this.count = count - 1; + } + source.subscribe(this._unsubscribeAndRecycle()); + } }; - return BufferSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=buffer.js.map + return RetrySubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=retry.js.map /***/ }), -/* 274 */ +/* 304 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bufferCount", function() { return bufferCount; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "retryWhen", function() { return retryWhen; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(158); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_Subject,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function bufferCount(bufferSize, startBufferEvery) { - if (startBufferEvery === void 0) { - startBufferEvery = null; - } - return function bufferCountOperatorFunction(source) { - return source.lift(new BufferCountOperator(bufferSize, startBufferEvery)); - }; + + +function retryWhen(notifier) { + return function (source) { return source.lift(new RetryWhenOperator(notifier, source)); }; } -var BufferCountOperator = /*@__PURE__*/ (function () { - function BufferCountOperator(bufferSize, startBufferEvery) { - this.bufferSize = bufferSize; - this.startBufferEvery = startBufferEvery; - if (!startBufferEvery || bufferSize === startBufferEvery) { - this.subscriberClass = BufferCountSubscriber; - } - else { - this.subscriberClass = BufferSkipCountSubscriber; - } +var RetryWhenOperator = /*@__PURE__*/ (function () { + function RetryWhenOperator(notifier, source) { + this.notifier = notifier; + this.source = source; } - BufferCountOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new this.subscriberClass(subscriber, this.bufferSize, this.startBufferEvery)); + RetryWhenOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new RetryWhenSubscriber(subscriber, this.notifier, this.source)); }; - return BufferCountOperator; + return RetryWhenOperator; }()); -var BufferCountSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferCountSubscriber, _super); - function BufferCountSubscriber(destination, bufferSize) { +var RetryWhenSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RetryWhenSubscriber, _super); + function RetryWhenSubscriber(destination, notifier, source) { var _this = _super.call(this, destination) || this; - _this.bufferSize = bufferSize; - _this.buffer = []; + _this.notifier = notifier; + _this.source = source; return _this; } - BufferCountSubscriber.prototype._next = function (value) { - var buffer = this.buffer; - buffer.push(value); - if (buffer.length == this.bufferSize) { - this.destination.next(buffer); - this.buffer = []; - } - }; - BufferCountSubscriber.prototype._complete = function () { - var buffer = this.buffer; - if (buffer.length > 0) { - this.destination.next(buffer); - } - _super.prototype._complete.call(this); - }; - return BufferCountSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -var BufferSkipCountSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferSkipCountSubscriber, _super); - function BufferSkipCountSubscriber(destination, bufferSize, startBufferEvery) { - var _this = _super.call(this, destination) || this; - _this.bufferSize = bufferSize; - _this.startBufferEvery = startBufferEvery; - _this.buffers = []; - _this.count = 0; - return _this; - } - BufferSkipCountSubscriber.prototype._next = function (value) { - var _a = this, bufferSize = _a.bufferSize, startBufferEvery = _a.startBufferEvery, buffers = _a.buffers, count = _a.count; - this.count++; - if (count % startBufferEvery === 0) { - buffers.push([]); - } - for (var i = buffers.length; i--;) { - var buffer = buffers[i]; - buffer.push(value); - if (buffer.length === bufferSize) { - buffers.splice(i, 1); - this.destination.next(buffer); + RetryWhenSubscriber.prototype.error = function (err) { + if (!this.isStopped) { + var errors = this.errors; + var retries = this.retries; + var retriesSubscription = this.retriesSubscription; + if (!retries) { + errors = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); + try { + var notifier = this.notifier; + retries = notifier(errors); + } + catch (e) { + return _super.prototype.error.call(this, e); + } + retriesSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, retries); } + else { + this.errors = null; + this.retriesSubscription = null; + } + this._unsubscribeAndRecycle(); + this.errors = errors; + this.retries = retries; + this.retriesSubscription = retriesSubscription; + errors.next(err); } }; - BufferSkipCountSubscriber.prototype._complete = function () { - var _a = this, buffers = _a.buffers, destination = _a.destination; - while (buffers.length > 0) { - var buffer = buffers.shift(); - if (buffer.length > 0) { - destination.next(buffer); - } + RetryWhenSubscriber.prototype._unsubscribe = function () { + var _a = this, errors = _a.errors, retriesSubscription = _a.retriesSubscription; + if (errors) { + errors.unsubscribe(); + this.errors = null; } - _super.prototype._complete.call(this); + if (retriesSubscription) { + retriesSubscription.unsubscribe(); + this.retriesSubscription = null; + } + this.retries = null; }; - return BufferSkipCountSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=bufferCount.js.map + RetryWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + var _unsubscribe = this._unsubscribe; + this._unsubscribe = null; + this._unsubscribeAndRecycle(); + this._unsubscribe = _unsubscribe; + this.source.subscribe(this); + }; + return RetryWhenSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); +//# sourceMappingURL=retryWhen.js.map /***/ }), -/* 275 */ +/* 305 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bufferTime", function() { return bufferTime; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(215); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(172); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(205); -/** PURE_IMPORTS_START tslib,_scheduler_async,_Subscriber,_util_isScheduler PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sample", function() { return sample; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function bufferTime(bufferTimeSpan) { - var length = arguments.length; - var scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; - if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_3__["isScheduler"])(arguments[arguments.length - 1])) { - scheduler = arguments[arguments.length - 1]; - length--; - } - var bufferCreationInterval = null; - if (length >= 2) { - bufferCreationInterval = arguments[1]; - } - var maxBufferSize = Number.POSITIVE_INFINITY; - if (length >= 3) { - maxBufferSize = arguments[2]; - } - return function bufferTimeOperatorFunction(source) { - return source.lift(new BufferTimeOperator(bufferTimeSpan, bufferCreationInterval, maxBufferSize, scheduler)); - }; +function sample(notifier) { + return function (source) { return source.lift(new SampleOperator(notifier)); }; } -var BufferTimeOperator = /*@__PURE__*/ (function () { - function BufferTimeOperator(bufferTimeSpan, bufferCreationInterval, maxBufferSize, scheduler) { - this.bufferTimeSpan = bufferTimeSpan; - this.bufferCreationInterval = bufferCreationInterval; - this.maxBufferSize = maxBufferSize; - this.scheduler = scheduler; +var SampleOperator = /*@__PURE__*/ (function () { + function SampleOperator(notifier) { + this.notifier = notifier; } - BufferTimeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new BufferTimeSubscriber(subscriber, this.bufferTimeSpan, this.bufferCreationInterval, this.maxBufferSize, this.scheduler)); + SampleOperator.prototype.call = function (subscriber, source) { + var sampleSubscriber = new SampleSubscriber(subscriber); + var subscription = source.subscribe(sampleSubscriber); + subscription.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(sampleSubscriber, this.notifier)); + return subscription; }; - return BufferTimeOperator; -}()); -var Context = /*@__PURE__*/ (function () { - function Context() { - this.buffer = []; - } - return Context; + return SampleOperator; }()); -var BufferTimeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferTimeSubscriber, _super); - function BufferTimeSubscriber(destination, bufferTimeSpan, bufferCreationInterval, maxBufferSize, scheduler) { - var _this = _super.call(this, destination) || this; - _this.bufferTimeSpan = bufferTimeSpan; - _this.bufferCreationInterval = bufferCreationInterval; - _this.maxBufferSize = maxBufferSize; - _this.scheduler = scheduler; - _this.contexts = []; - var context = _this.openContext(); - _this.timespanOnly = bufferCreationInterval == null || bufferCreationInterval < 0; - if (_this.timespanOnly) { - var timeSpanOnlyState = { subscriber: _this, context: context, bufferTimeSpan: bufferTimeSpan }; - _this.add(context.closeAction = scheduler.schedule(dispatchBufferTimeSpanOnly, bufferTimeSpan, timeSpanOnlyState)); - } - else { - var closeState = { subscriber: _this, context: context }; - var creationState = { bufferTimeSpan: bufferTimeSpan, bufferCreationInterval: bufferCreationInterval, subscriber: _this, scheduler: scheduler }; - _this.add(context.closeAction = scheduler.schedule(dispatchBufferClose, bufferTimeSpan, closeState)); - _this.add(scheduler.schedule(dispatchBufferCreation, bufferCreationInterval, creationState)); - } +var SampleSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SampleSubscriber, _super); + function SampleSubscriber() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.hasValue = false; return _this; } - BufferTimeSubscriber.prototype._next = function (value) { - var contexts = this.contexts; - var len = contexts.length; - var filledBufferContext; - for (var i = 0; i < len; i++) { - var context_1 = contexts[i]; - var buffer = context_1.buffer; - buffer.push(value); - if (buffer.length == this.maxBufferSize) { - filledBufferContext = context_1; - } - } - if (filledBufferContext) { - this.onBufferFull(filledBufferContext); - } - }; - BufferTimeSubscriber.prototype._error = function (err) { - this.contexts.length = 0; - _super.prototype._error.call(this, err); - }; - BufferTimeSubscriber.prototype._complete = function () { - var _a = this, contexts = _a.contexts, destination = _a.destination; - while (contexts.length > 0) { - var context_2 = contexts.shift(); - destination.next(context_2.buffer); - } - _super.prototype._complete.call(this); - }; - BufferTimeSubscriber.prototype._unsubscribe = function () { - this.contexts = null; + SampleSubscriber.prototype._next = function (value) { + this.value = value; + this.hasValue = true; }; - BufferTimeSubscriber.prototype.onBufferFull = function (context) { - this.closeContext(context); - var closeAction = context.closeAction; - closeAction.unsubscribe(); - this.remove(closeAction); - if (!this.closed && this.timespanOnly) { - context = this.openContext(); - var bufferTimeSpan = this.bufferTimeSpan; - var timeSpanOnlyState = { subscriber: this, context: context, bufferTimeSpan: bufferTimeSpan }; - this.add(context.closeAction = this.scheduler.schedule(dispatchBufferTimeSpanOnly, bufferTimeSpan, timeSpanOnlyState)); - } + SampleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.emitValue(); }; - BufferTimeSubscriber.prototype.openContext = function () { - var context = new Context(); - this.contexts.push(context); - return context; + SampleSubscriber.prototype.notifyComplete = function () { + this.emitValue(); }; - BufferTimeSubscriber.prototype.closeContext = function (context) { - this.destination.next(context.buffer); - var contexts = this.contexts; - var spliceIndex = contexts ? contexts.indexOf(context) : -1; - if (spliceIndex >= 0) { - contexts.splice(contexts.indexOf(context), 1); + SampleSubscriber.prototype.emitValue = function () { + if (this.hasValue) { + this.hasValue = false; + this.destination.next(this.value); } }; - return BufferTimeSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_2__["Subscriber"])); -function dispatchBufferTimeSpanOnly(state) { - var subscriber = state.subscriber; - var prevContext = state.context; - if (prevContext) { - subscriber.closeContext(prevContext); - } - if (!subscriber.closed) { - state.context = subscriber.openContext(); - state.context.closeAction = this.schedule(state, state.bufferTimeSpan); - } -} -function dispatchBufferCreation(state) { - var bufferCreationInterval = state.bufferCreationInterval, bufferTimeSpan = state.bufferTimeSpan, subscriber = state.subscriber, scheduler = state.scheduler; - var context = subscriber.openContext(); - var action = this; - if (!subscriber.closed) { - subscriber.add(context.closeAction = scheduler.schedule(dispatchBufferClose, bufferTimeSpan, { subscriber: subscriber, context: context })); - action.schedule(state, bufferCreationInterval); - } -} -function dispatchBufferClose(arg) { - var subscriber = arg.subscriber, context = arg.context; - subscriber.closeContext(context); -} -//# sourceMappingURL=bufferTime.js.map + return SampleSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +//# sourceMappingURL=sample.js.map /***/ }), -/* 276 */ +/* 306 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bufferToggle", function() { return bufferToggle; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(177); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(230); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(229); -/** PURE_IMPORTS_START tslib,_Subscription,_util_subscribeToResult,_OuterSubscriber PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sampleTime", function() { return sampleTime; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(186); +/** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async PURE_IMPORTS_END */ -function bufferToggle(openings, closingSelector) { - return function bufferToggleOperatorFunction(source) { - return source.lift(new BufferToggleOperator(openings, closingSelector)); - }; +function sampleTime(period, scheduler) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; + } + return function (source) { return source.lift(new SampleTimeOperator(period, scheduler)); }; } -var BufferToggleOperator = /*@__PURE__*/ (function () { - function BufferToggleOperator(openings, closingSelector) { - this.openings = openings; - this.closingSelector = closingSelector; +var SampleTimeOperator = /*@__PURE__*/ (function () { + function SampleTimeOperator(period, scheduler) { + this.period = period; + this.scheduler = scheduler; } - BufferToggleOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new BufferToggleSubscriber(subscriber, this.openings, this.closingSelector)); + SampleTimeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SampleTimeSubscriber(subscriber, this.period, this.scheduler)); }; - return BufferToggleOperator; + return SampleTimeOperator; }()); -var BufferToggleSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferToggleSubscriber, _super); - function BufferToggleSubscriber(destination, openings, closingSelector) { +var SampleTimeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SampleTimeSubscriber, _super); + function SampleTimeSubscriber(destination, period, scheduler) { var _this = _super.call(this, destination) || this; - _this.openings = openings; - _this.closingSelector = closingSelector; - _this.contexts = []; - _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, openings)); + _this.period = period; + _this.scheduler = scheduler; + _this.hasValue = false; + _this.add(scheduler.schedule(dispatchNotification, period, { subscriber: _this, period: period })); return _this; } - BufferToggleSubscriber.prototype._next = function (value) { - var contexts = this.contexts; - var len = contexts.length; - for (var i = 0; i < len; i++) { - contexts[i].buffer.push(value); - } - }; - BufferToggleSubscriber.prototype._error = function (err) { - var contexts = this.contexts; - while (contexts.length > 0) { - var context_1 = contexts.shift(); - context_1.subscription.unsubscribe(); - context_1.buffer = null; - context_1.subscription = null; - } - this.contexts = null; - _super.prototype._error.call(this, err); - }; - BufferToggleSubscriber.prototype._complete = function () { - var contexts = this.contexts; - while (contexts.length > 0) { - var context_2 = contexts.shift(); - this.destination.next(context_2.buffer); - context_2.subscription.unsubscribe(); - context_2.buffer = null; - context_2.subscription = null; - } - this.contexts = null; - _super.prototype._complete.call(this); - }; - BufferToggleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - outerValue ? this.closeBuffer(outerValue) : this.openBuffer(innerValue); - }; - BufferToggleSubscriber.prototype.notifyComplete = function (innerSub) { - this.closeBuffer(innerSub.context); - }; - BufferToggleSubscriber.prototype.openBuffer = function (value) { - try { - var closingSelector = this.closingSelector; - var closingNotifier = closingSelector.call(this, value); - if (closingNotifier) { - this.trySubscribe(closingNotifier); - } - } - catch (err) { - this._error(err); - } - }; - BufferToggleSubscriber.prototype.closeBuffer = function (context) { - var contexts = this.contexts; - if (contexts && context) { - var buffer = context.buffer, subscription = context.subscription; - this.destination.next(buffer); - contexts.splice(contexts.indexOf(context), 1); - this.remove(subscription); - subscription.unsubscribe(); - } + SampleTimeSubscriber.prototype._next = function (value) { + this.lastValue = value; + this.hasValue = true; }; - BufferToggleSubscriber.prototype.trySubscribe = function (closingNotifier) { - var contexts = this.contexts; - var buffer = []; - var subscription = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); - var context = { buffer: buffer, subscription: subscription }; - contexts.push(context); - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, closingNotifier, context); - if (!innerSubscription || innerSubscription.closed) { - this.closeBuffer(context); - } - else { - innerSubscription.context = context; - this.add(innerSubscription); - subscription.add(innerSubscription); + SampleTimeSubscriber.prototype.notifyNext = function () { + if (this.hasValue) { + this.hasValue = false; + this.destination.next(this.lastValue); } }; - return BufferToggleSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); -//# sourceMappingURL=bufferToggle.js.map + return SampleTimeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +function dispatchNotification(state) { + var subscriber = state.subscriber, period = state.period; + subscriber.notifyNext(); + this.schedule(state, period); +} +//# sourceMappingURL=sampleTime.js.map /***/ }), -/* 277 */ +/* 307 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bufferWhen", function() { return bufferWhen; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(177); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_Subscription,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sequenceEqual", function() { return sequenceEqual; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SequenceEqualOperator", function() { return SequenceEqualOperator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SequenceEqualSubscriber", function() { return SequenceEqualSubscriber; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function bufferWhen(closingSelector) { - return function (source) { - return source.lift(new BufferWhenOperator(closingSelector)); - }; +function sequenceEqual(compareTo, comparator) { + return function (source) { return source.lift(new SequenceEqualOperator(compareTo, comparator)); }; } -var BufferWhenOperator = /*@__PURE__*/ (function () { - function BufferWhenOperator(closingSelector) { - this.closingSelector = closingSelector; +var SequenceEqualOperator = /*@__PURE__*/ (function () { + function SequenceEqualOperator(compareTo, comparator) { + this.compareTo = compareTo; + this.comparator = comparator; } - BufferWhenOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new BufferWhenSubscriber(subscriber, this.closingSelector)); + SequenceEqualOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SequenceEqualSubscriber(subscriber, this.compareTo, this.comparator)); }; - return BufferWhenOperator; + return SequenceEqualOperator; }()); -var BufferWhenSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferWhenSubscriber, _super); - function BufferWhenSubscriber(destination, closingSelector) { + +var SequenceEqualSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SequenceEqualSubscriber, _super); + function SequenceEqualSubscriber(destination, compareTo, comparator) { var _this = _super.call(this, destination) || this; - _this.closingSelector = closingSelector; - _this.subscribing = false; - _this.openBuffer(); + _this.compareTo = compareTo; + _this.comparator = comparator; + _this._a = []; + _this._b = []; + _this._oneComplete = false; + _this.destination.add(compareTo.subscribe(new SequenceEqualCompareToSubscriber(destination, _this))); return _this; } - BufferWhenSubscriber.prototype._next = function (value) { - this.buffer.push(value); + SequenceEqualSubscriber.prototype._next = function (value) { + if (this._oneComplete && this._b.length === 0) { + this.emit(false); + } + else { + this._a.push(value); + this.checkValues(); + } }; - BufferWhenSubscriber.prototype._complete = function () { - var buffer = this.buffer; - if (buffer) { - this.destination.next(buffer); + SequenceEqualSubscriber.prototype._complete = function () { + if (this._oneComplete) { + this.emit(this._a.length === 0 && this._b.length === 0); } - _super.prototype._complete.call(this); + else { + this._oneComplete = true; + } + this.unsubscribe(); }; - BufferWhenSubscriber.prototype._unsubscribe = function () { - this.buffer = null; - this.subscribing = false; + SequenceEqualSubscriber.prototype.checkValues = function () { + var _c = this, _a = _c._a, _b = _c._b, comparator = _c.comparator; + while (_a.length > 0 && _b.length > 0) { + var a = _a.shift(); + var b = _b.shift(); + var areEqual = false; + try { + areEqual = comparator ? comparator(a, b) : a === b; + } + catch (e) { + this.destination.error(e); + } + if (!areEqual) { + this.emit(false); + } + } }; - BufferWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.openBuffer(); + SequenceEqualSubscriber.prototype.emit = function (value) { + var destination = this.destination; + destination.next(value); + destination.complete(); }; - BufferWhenSubscriber.prototype.notifyComplete = function () { - if (this.subscribing) { - this.complete(); + SequenceEqualSubscriber.prototype.nextB = function (value) { + if (this._oneComplete && this._a.length === 0) { + this.emit(false); } else { - this.openBuffer(); + this._b.push(value); + this.checkValues(); } }; - BufferWhenSubscriber.prototype.openBuffer = function () { - var closingSubscription = this.closingSubscription; - if (closingSubscription) { - this.remove(closingSubscription); - closingSubscription.unsubscribe(); - } - var buffer = this.buffer; - if (this.buffer) { - this.destination.next(buffer); - } - this.buffer = []; - var closingNotifier; - try { - var closingSelector = this.closingSelector; - closingNotifier = closingSelector(); + SequenceEqualSubscriber.prototype.completeB = function () { + if (this._oneComplete) { + this.emit(this._a.length === 0 && this._b.length === 0); } - catch (err) { - return this.error(err); + else { + this._oneComplete = true; } - closingSubscription = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); - this.closingSubscription = closingSubscription; - this.add(closingSubscription); - this.subscribing = true; - closingSubscription.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, closingNotifier)); - this.subscribing = false; }; - return BufferWhenSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); -//# sourceMappingURL=bufferWhen.js.map - - -/***/ }), -/* 278 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "catchError", function() { return catchError; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(229); -/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(231); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - - - + return SequenceEqualSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -function catchError(selector) { - return function catchErrorOperatorFunction(source) { - var operator = new CatchOperator(selector); - var caught = source.lift(operator); - return (operator.caught = caught); - }; -} -var CatchOperator = /*@__PURE__*/ (function () { - function CatchOperator(selector) { - this.selector = selector; - } - CatchOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new CatchSubscriber(subscriber, this.selector, this.caught)); - }; - return CatchOperator; -}()); -var CatchSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CatchSubscriber, _super); - function CatchSubscriber(destination, selector, caught) { +var SequenceEqualCompareToSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SequenceEqualCompareToSubscriber, _super); + function SequenceEqualCompareToSubscriber(destination, parent) { var _this = _super.call(this, destination) || this; - _this.selector = selector; - _this.caught = caught; + _this.parent = parent; return _this; } - CatchSubscriber.prototype.error = function (err) { - if (!this.isStopped) { - var result = void 0; - try { - result = this.selector(err, this.caught); - } - catch (err2) { - _super.prototype.error.call(this, err2); - return; - } - this._unsubscribeAndRecycle(); - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](this, undefined, undefined); - this.add(innerSubscriber); - Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, result, undefined, undefined, innerSubscriber); - } + SequenceEqualCompareToSubscriber.prototype._next = function (value) { + this.parent.nextB(value); }; - return CatchSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=catchError.js.map - - -/***/ }), -/* 279 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "combineAll", function() { return combineAll; }); -/* harmony import */ var _observable_combineLatest__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(228); -/** PURE_IMPORTS_START _observable_combineLatest PURE_IMPORTS_END */ - -function combineAll(project) { - return function (source) { return source.lift(new _observable_combineLatest__WEBPACK_IMPORTED_MODULE_0__["CombineLatestOperator"](project)); }; -} -//# sourceMappingURL=combineAll.js.map + SequenceEqualCompareToSubscriber.prototype._error = function (err) { + this.parent.error(err); + this.unsubscribe(); + }; + SequenceEqualCompareToSubscriber.prototype._complete = function () { + this.parent.completeB(); + this.unsubscribe(); + }; + return SequenceEqualCompareToSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=sequenceEqual.js.map /***/ }), -/* 280 */ +/* 308 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return combineLatest; }); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(178); -/* harmony import */ var _observable_combineLatest__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(228); -/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(243); -/** PURE_IMPORTS_START _util_isArray,_observable_combineLatest,_observable_from PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "share", function() { return share; }); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(291); +/* harmony import */ var _refCount__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(161); +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(158); +/** PURE_IMPORTS_START _multicast,_refCount,_Subject PURE_IMPORTS_END */ -var none = {}; -function combineLatest() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; - } - var project = null; - if (typeof observables[observables.length - 1] === 'function') { - project = observables.pop(); - } - if (observables.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_0__["isArray"])(observables[0])) { - observables = observables[0].slice(); - } - return function (source) { return source.lift.call(Object(_observable_from__WEBPACK_IMPORTED_MODULE_2__["from"])([source].concat(observables)), new _observable_combineLatest__WEBPACK_IMPORTED_MODULE_1__["CombineLatestOperator"](project)); }; +function shareSubjectFactory() { + return new _Subject__WEBPACK_IMPORTED_MODULE_2__["Subject"](); } -//# sourceMappingURL=combineLatest.js.map +function share() { + return function (source) { return Object(_refCount__WEBPACK_IMPORTED_MODULE_1__["refCount"])()(Object(_multicast__WEBPACK_IMPORTED_MODULE_0__["multicast"])(shareSubjectFactory)(source)); }; +} +//# sourceMappingURL=share.js.map /***/ }), -/* 281 */ +/* 309 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return concat; }); -/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(239); -/** PURE_IMPORTS_START _observable_concat PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shareReplay", function() { return shareReplay; }); +/* harmony import */ var _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(164); +/** PURE_IMPORTS_START _ReplaySubject PURE_IMPORTS_END */ -function concat() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; +function shareReplay(configOrBufferSize, windowTime, scheduler) { + var config; + if (configOrBufferSize && typeof configOrBufferSize === 'object') { + config = configOrBufferSize; } - return function (source) { return source.lift.call(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"].apply(void 0, [source].concat(observables))); }; + else { + config = { + bufferSize: configOrBufferSize, + windowTime: windowTime, + refCount: false, + scheduler: scheduler + }; + } + return function (source) { return source.lift(shareReplayOperator(config)); }; } -//# sourceMappingURL=concat.js.map - - -/***/ }), -/* 282 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concatMap", function() { return concatMap; }); -/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(242); -/** PURE_IMPORTS_START _mergeMap PURE_IMPORTS_END */ - -function concatMap(project, resultSelector) { - return Object(_mergeMap__WEBPACK_IMPORTED_MODULE_0__["mergeMap"])(project, resultSelector, 1); +function shareReplayOperator(_a) { + var _b = _a.bufferSize, bufferSize = _b === void 0 ? Number.POSITIVE_INFINITY : _b, _c = _a.windowTime, windowTime = _c === void 0 ? Number.POSITIVE_INFINITY : _c, useRefCount = _a.refCount, scheduler = _a.scheduler; + var subject; + var refCount = 0; + var subscription; + var hasError = false; + var isComplete = false; + return function shareReplayOperation(source) { + refCount++; + if (!subject || hasError) { + hasError = false; + subject = new _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__["ReplaySubject"](bufferSize, windowTime, scheduler); + subscription = source.subscribe({ + next: function (value) { subject.next(value); }, + error: function (err) { + hasError = true; + subject.error(err); + }, + complete: function () { + isComplete = true; + subject.complete(); + }, + }); + } + var innerSub = subject.subscribe(this); + this.add(function () { + refCount--; + innerSub.unsubscribe(); + if (subscription && !isComplete && useRefCount && refCount === 0) { + subscription.unsubscribe(); + subscription = undefined; + subject = undefined; + } + }); + }; } -//# sourceMappingURL=concatMap.js.map +//# sourceMappingURL=shareReplay.js.map /***/ }), -/* 283 */ +/* 310 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concatMapTo", function() { return concatMapTo; }); -/* harmony import */ var _concatMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(282); -/** PURE_IMPORTS_START _concatMap PURE_IMPORTS_END */ - -function concatMapTo(innerObservable, resultSelector) { - return Object(_concatMap__WEBPACK_IMPORTED_MODULE_0__["concatMap"])(function () { return innerObservable; }, resultSelector); -} -//# sourceMappingURL=concatMapTo.js.map - - -/***/ }), -/* 284 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "single", function() { return single; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(194); +/** PURE_IMPORTS_START tslib,_Subscriber,_util_EmptyError PURE_IMPORTS_END */ -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "count", function() { return count; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function count(predicate) { - return function (source) { return source.lift(new CountOperator(predicate, source)); }; +function single(predicate) { + return function (source) { return source.lift(new SingleOperator(predicate, source)); }; } -var CountOperator = /*@__PURE__*/ (function () { - function CountOperator(predicate, source) { +var SingleOperator = /*@__PURE__*/ (function () { + function SingleOperator(predicate, source) { this.predicate = predicate; this.source = source; } - CountOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new CountSubscriber(subscriber, this.predicate, this.source)); + SingleOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SingleSubscriber(subscriber, this.predicate, this.source)); }; - return CountOperator; + return SingleOperator; }()); -var CountSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CountSubscriber, _super); - function CountSubscriber(destination, predicate, source) { +var SingleSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SingleSubscriber, _super); + function SingleSubscriber(destination, predicate, source) { var _this = _super.call(this, destination) || this; _this.predicate = predicate; _this.source = source; - _this.count = 0; + _this.seenValue = false; _this.index = 0; return _this; } - CountSubscriber.prototype._next = function (value) { + SingleSubscriber.prototype.applySingleValue = function (value) { + if (this.seenValue) { + this.destination.error('Sequence contains more than one element'); + } + else { + this.seenValue = true; + this.singleValue = value; + } + }; + SingleSubscriber.prototype._next = function (value) { + var index = this.index++; if (this.predicate) { - this._tryPredicate(value); + this.tryNext(value, index); } else { - this.count++; + this.applySingleValue(value); } }; - CountSubscriber.prototype._tryPredicate = function (value) { - var result; + SingleSubscriber.prototype.tryNext = function (value, index) { try { - result = this.predicate(value, this.index++, this.source); + if (this.predicate(value, index, this.source)) { + this.applySingleValue(value); + } } catch (err) { this.destination.error(err); - return; - } - if (result) { - this.count++; } }; - CountSubscriber.prototype._complete = function () { - this.destination.next(this.count); - this.destination.complete(); + SingleSubscriber.prototype._complete = function () { + var destination = this.destination; + if (this.index > 0) { + destination.next(this.seenValue ? this.singleValue : undefined); + destination.complete(); + } + else { + destination.error(new _util_EmptyError__WEBPACK_IMPORTED_MODULE_2__["EmptyError"]); + } }; - return CountSubscriber; + return SingleSubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=count.js.map +//# sourceMappingURL=single.js.map /***/ }), -/* 285 */ +/* 311 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "debounce", function() { return debounce; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skip", function() { return skip; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function debounce(durationSelector) { - return function (source) { return source.lift(new DebounceOperator(durationSelector)); }; +function skip(count) { + return function (source) { return source.lift(new SkipOperator(count)); }; } -var DebounceOperator = /*@__PURE__*/ (function () { - function DebounceOperator(durationSelector) { - this.durationSelector = durationSelector; +var SkipOperator = /*@__PURE__*/ (function () { + function SkipOperator(total) { + this.total = total; } - DebounceOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DebounceSubscriber(subscriber, this.durationSelector)); + SkipOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SkipSubscriber(subscriber, this.total)); }; - return DebounceOperator; + return SkipOperator; }()); -var DebounceSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DebounceSubscriber, _super); - function DebounceSubscriber(destination, durationSelector) { +var SkipSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipSubscriber, _super); + function SkipSubscriber(destination, total) { var _this = _super.call(this, destination) || this; - _this.durationSelector = durationSelector; - _this.hasValue = false; - _this.durationSubscription = null; + _this.total = total; + _this.count = 0; return _this; } - DebounceSubscriber.prototype._next = function (value) { - try { - var result = this.durationSelector.call(this, value); - if (result) { - this._tryNext(value, result); - } - } - catch (err) { - this.destination.error(err); - } - }; - DebounceSubscriber.prototype._complete = function () { - this.emitValue(); - this.destination.complete(); - }; - DebounceSubscriber.prototype._tryNext = function (value, duration) { - var subscription = this.durationSubscription; - this.value = value; - this.hasValue = true; - if (subscription) { - subscription.unsubscribe(); - this.remove(subscription); - } - subscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, duration); - if (subscription && !subscription.closed) { - this.add(this.durationSubscription = subscription); - } - }; - DebounceSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.emitValue(); - }; - DebounceSubscriber.prototype.notifyComplete = function () { - this.emitValue(); - }; - DebounceSubscriber.prototype.emitValue = function () { - if (this.hasValue) { - var value = this.value; - var subscription = this.durationSubscription; - if (subscription) { - this.durationSubscription = null; - subscription.unsubscribe(); - this.remove(subscription); - } - this.value = null; - this.hasValue = false; - _super.prototype._next.call(this, value); + SkipSubscriber.prototype._next = function (x) { + if (++this.count > this.total) { + this.destination.next(x); } }; - return DebounceSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=debounce.js.map + return SkipSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=skip.js.map /***/ }), -/* 286 */ +/* 312 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "debounceTime", function() { return debounceTime; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(215); -/** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skipLast", function() { return skipLast; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(193); +/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError PURE_IMPORTS_END */ -function debounceTime(dueTime, scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; - } - return function (source) { return source.lift(new DebounceTimeOperator(dueTime, scheduler)); }; +function skipLast(count) { + return function (source) { return source.lift(new SkipLastOperator(count)); }; } -var DebounceTimeOperator = /*@__PURE__*/ (function () { - function DebounceTimeOperator(dueTime, scheduler) { - this.dueTime = dueTime; - this.scheduler = scheduler; +var SkipLastOperator = /*@__PURE__*/ (function () { + function SkipLastOperator(_skipCount) { + this._skipCount = _skipCount; + if (this._skipCount < 0) { + throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__["ArgumentOutOfRangeError"]; + } } - DebounceTimeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DebounceTimeSubscriber(subscriber, this.dueTime, this.scheduler)); + SkipLastOperator.prototype.call = function (subscriber, source) { + if (this._skipCount === 0) { + return source.subscribe(new _Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"](subscriber)); + } + else { + return source.subscribe(new SkipLastSubscriber(subscriber, this._skipCount)); + } }; - return DebounceTimeOperator; + return SkipLastOperator; }()); -var DebounceTimeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DebounceTimeSubscriber, _super); - function DebounceTimeSubscriber(destination, dueTime, scheduler) { +var SkipLastSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipLastSubscriber, _super); + function SkipLastSubscriber(destination, _skipCount) { var _this = _super.call(this, destination) || this; - _this.dueTime = dueTime; - _this.scheduler = scheduler; - _this.debouncedSubscription = null; - _this.lastValue = null; - _this.hasValue = false; + _this._skipCount = _skipCount; + _this._count = 0; + _this._ring = new Array(_skipCount); return _this; } - DebounceTimeSubscriber.prototype._next = function (value) { - this.clearDebounce(); - this.lastValue = value; - this.hasValue = true; - this.add(this.debouncedSubscription = this.scheduler.schedule(dispatchNext, this.dueTime, this)); - }; - DebounceTimeSubscriber.prototype._complete = function () { - this.debouncedNext(); - this.destination.complete(); - }; - DebounceTimeSubscriber.prototype.debouncedNext = function () { - this.clearDebounce(); - if (this.hasValue) { - var lastValue = this.lastValue; - this.lastValue = null; - this.hasValue = false; - this.destination.next(lastValue); + SkipLastSubscriber.prototype._next = function (value) { + var skipCount = this._skipCount; + var count = this._count++; + if (count < skipCount) { + this._ring[count] = value; } - }; - DebounceTimeSubscriber.prototype.clearDebounce = function () { - var debouncedSubscription = this.debouncedSubscription; - if (debouncedSubscription !== null) { - this.remove(debouncedSubscription); - debouncedSubscription.unsubscribe(); - this.debouncedSubscription = null; + else { + var currentIndex = count % skipCount; + var ring = this._ring; + var oldValue = ring[currentIndex]; + ring[currentIndex] = value; + this.destination.next(oldValue); } }; - return DebounceTimeSubscriber; + return SkipLastSubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -function dispatchNext(subscriber) { - subscriber.debouncedNext(); -} -//# sourceMappingURL=debounceTime.js.map +//# sourceMappingURL=skipLast.js.map /***/ }), -/* 287 */ +/* 313 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultIfEmpty", function() { return defaultIfEmpty; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skipUntil", function() { return skipUntil; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(200); +/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(202); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function defaultIfEmpty(defaultValue) { - if (defaultValue === void 0) { - defaultValue = null; - } - return function (source) { return source.lift(new DefaultIfEmptyOperator(defaultValue)); }; + + +function skipUntil(notifier) { + return function (source) { return source.lift(new SkipUntilOperator(notifier)); }; } -var DefaultIfEmptyOperator = /*@__PURE__*/ (function () { - function DefaultIfEmptyOperator(defaultValue) { - this.defaultValue = defaultValue; +var SkipUntilOperator = /*@__PURE__*/ (function () { + function SkipUntilOperator(notifier) { + this.notifier = notifier; } - DefaultIfEmptyOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DefaultIfEmptySubscriber(subscriber, this.defaultValue)); + SkipUntilOperator.prototype.call = function (destination, source) { + return source.subscribe(new SkipUntilSubscriber(destination, this.notifier)); }; - return DefaultIfEmptyOperator; + return SkipUntilOperator; }()); -var DefaultIfEmptySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DefaultIfEmptySubscriber, _super); - function DefaultIfEmptySubscriber(destination, defaultValue) { +var SkipUntilSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipUntilSubscriber, _super); + function SkipUntilSubscriber(destination, notifier) { var _this = _super.call(this, destination) || this; - _this.defaultValue = defaultValue; - _this.isEmpty = true; + _this.hasValue = false; + var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](_this, undefined, undefined); + _this.add(innerSubscriber); + _this.innerSubscription = innerSubscriber; + Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(_this, notifier, undefined, undefined, innerSubscriber); return _this; } - DefaultIfEmptySubscriber.prototype._next = function (value) { - this.isEmpty = false; - this.destination.next(value); + SkipUntilSubscriber.prototype._next = function (value) { + if (this.hasValue) { + _super.prototype._next.call(this, value); + } }; - DefaultIfEmptySubscriber.prototype._complete = function () { - if (this.isEmpty) { - this.destination.next(this.defaultValue); + SkipUntilSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.hasValue = true; + if (this.innerSubscription) { + this.innerSubscription.unsubscribe(); } - this.destination.complete(); }; - return DefaultIfEmptySubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=defaultIfEmpty.js.map + SkipUntilSubscriber.prototype.notifyComplete = function () { + }; + return SkipUntilSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +//# sourceMappingURL=skipUntil.js.map /***/ }), -/* 288 */ +/* 314 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "delay", function() { return delay; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(215); -/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(289); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(172); -/* harmony import */ var _Notification__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(202); -/** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_Subscriber,_Notification PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skipWhile", function() { return skipWhile; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + +function skipWhile(predicate) { + return function (source) { return source.lift(new SkipWhileOperator(predicate)); }; +} +var SkipWhileOperator = /*@__PURE__*/ (function () { + function SkipWhileOperator(predicate) { + this.predicate = predicate; + } + SkipWhileOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SkipWhileSubscriber(subscriber, this.predicate)); + }; + return SkipWhileOperator; +}()); +var SkipWhileSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipWhileSubscriber, _super); + function SkipWhileSubscriber(destination, predicate) { + var _this = _super.call(this, destination) || this; + _this.predicate = predicate; + _this.skipping = true; + _this.index = 0; + return _this; + } + SkipWhileSubscriber.prototype._next = function (value) { + var destination = this.destination; + if (this.skipping) { + this.tryCallPredicate(value); + } + if (!this.skipping) { + destination.next(value); + } + }; + SkipWhileSubscriber.prototype.tryCallPredicate = function (value) { + try { + var result = this.predicate(value, this.index++); + this.skipping = Boolean(result); + } + catch (err) { + this.destination.error(err); + } + }; + return SkipWhileSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=skipWhile.js.map +/***/ }), +/* 315 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "startWith", function() { return startWith; }); +/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(210); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(176); +/** PURE_IMPORTS_START _observable_concat,_util_isScheduler PURE_IMPORTS_END */ -function delay(delay, scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; + +function startWith() { + var array = []; + for (var _i = 0; _i < arguments.length; _i++) { + array[_i] = arguments[_i]; + } + var scheduler = array[array.length - 1]; + if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_1__["isScheduler"])(scheduler)) { + array.pop(); + return function (source) { return Object(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"])(array, source, scheduler); }; + } + else { + return function (source) { return Object(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"])(array, source); }; } - var absoluteDelay = Object(_util_isDate__WEBPACK_IMPORTED_MODULE_2__["isDate"])(delay); - var delayFor = absoluteDelay ? (+delay - scheduler.now()) : Math.abs(delay); - return function (source) { return source.lift(new DelayOperator(delayFor, scheduler)); }; } -var DelayOperator = /*@__PURE__*/ (function () { - function DelayOperator(delay, scheduler) { - this.delay = delay; +//# sourceMappingURL=startWith.js.map + + +/***/ }), +/* 316 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return subscribeOn; }); +/* harmony import */ var _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(317); +/** PURE_IMPORTS_START _observable_SubscribeOnObservable PURE_IMPORTS_END */ + +function subscribeOn(scheduler, delay) { + if (delay === void 0) { + delay = 0; + } + return function subscribeOnOperatorFunction(source) { + return source.lift(new SubscribeOnOperator(scheduler, delay)); + }; +} +var SubscribeOnOperator = /*@__PURE__*/ (function () { + function SubscribeOnOperator(scheduler, delay) { this.scheduler = scheduler; + this.delay = delay; } - DelayOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DelaySubscriber(subscriber, this.delay, this.scheduler)); + SubscribeOnOperator.prototype.call = function (subscriber, source) { + return new _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__["SubscribeOnObservable"](source, this.delay, this.scheduler).subscribe(subscriber); }; - return DelayOperator; + return SubscribeOnOperator; }()); -var DelaySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DelaySubscriber, _super); - function DelaySubscriber(destination, delay, scheduler) { - var _this = _super.call(this, destination) || this; - _this.delay = delay; +//# sourceMappingURL=subscribeOn.js.map + + +/***/ }), +/* 317 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubscribeOnObservable", function() { return SubscribeOnObservable; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(141); +/* harmony import */ var _scheduler_asap__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(182); +/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(228); +/** PURE_IMPORTS_START tslib,_Observable,_scheduler_asap,_util_isNumeric PURE_IMPORTS_END */ + + + + +var SubscribeOnObservable = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubscribeOnObservable, _super); + function SubscribeOnObservable(source, delayTime, scheduler) { + if (delayTime === void 0) { + delayTime = 0; + } + if (scheduler === void 0) { + scheduler = _scheduler_asap__WEBPACK_IMPORTED_MODULE_2__["asap"]; + } + var _this = _super.call(this) || this; + _this.source = source; + _this.delayTime = delayTime; _this.scheduler = scheduler; - _this.queue = []; - _this.active = false; - _this.errored = false; + if (!Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_3__["isNumeric"])(delayTime) || delayTime < 0) { + _this.delayTime = 0; + } + if (!scheduler || typeof scheduler.schedule !== 'function') { + _this.scheduler = _scheduler_asap__WEBPACK_IMPORTED_MODULE_2__["asap"]; + } return _this; } - DelaySubscriber.dispatch = function (state) { - var source = state.source; - var queue = source.queue; - var scheduler = state.scheduler; - var destination = state.destination; - while (queue.length > 0 && (queue[0].time - scheduler.now()) <= 0) { - queue.shift().notification.observe(destination); - } - if (queue.length > 0) { - var delay_1 = Math.max(0, queue[0].time - scheduler.now()); - this.schedule(state, delay_1); + SubscribeOnObservable.create = function (source, delay, scheduler) { + if (delay === void 0) { + delay = 0; } - else { - this.unsubscribe(); - source.active = false; + if (scheduler === void 0) { + scheduler = _scheduler_asap__WEBPACK_IMPORTED_MODULE_2__["asap"]; } + return new SubscribeOnObservable(source, delay, scheduler); }; - DelaySubscriber.prototype._schedule = function (scheduler) { - this.active = true; - var destination = this.destination; - destination.add(scheduler.schedule(DelaySubscriber.dispatch, this.delay, { - source: this, destination: this.destination, scheduler: scheduler - })); + SubscribeOnObservable.dispatch = function (arg) { + var source = arg.source, subscriber = arg.subscriber; + return this.add(source.subscribe(subscriber)); }; - DelaySubscriber.prototype.scheduleNotification = function (notification) { - if (this.errored === true) { - return; - } + SubscribeOnObservable.prototype._subscribe = function (subscriber) { + var delay = this.delayTime; + var source = this.source; var scheduler = this.scheduler; - var message = new DelayMessage(scheduler.now() + this.delay, notification); - this.queue.push(message); - if (this.active === false) { - this._schedule(scheduler); - } - }; - DelaySubscriber.prototype._next = function (value) { - this.scheduleNotification(_Notification__WEBPACK_IMPORTED_MODULE_4__["Notification"].createNext(value)); - }; - DelaySubscriber.prototype._error = function (err) { - this.errored = true; - this.queue = []; - this.destination.error(err); - this.unsubscribe(); - }; - DelaySubscriber.prototype._complete = function () { - this.scheduleNotification(_Notification__WEBPACK_IMPORTED_MODULE_4__["Notification"].createComplete()); - this.unsubscribe(); + return scheduler.schedule(SubscribeOnObservable.dispatch, delay, { + source: source, subscriber: subscriber + }); }; - return DelaySubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__["Subscriber"])); -var DelayMessage = /*@__PURE__*/ (function () { - function DelayMessage(time, notification) { - this.time = time; - this.notification = notification; - } - return DelayMessage; -}()); -//# sourceMappingURL=delay.js.map + return SubscribeOnObservable; +}(_Observable__WEBPACK_IMPORTED_MODULE_1__["Observable"])); + +//# sourceMappingURL=SubscribeOnObservable.js.map /***/ }), -/* 289 */ +/* 318 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isDate", function() { return isDate; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function isDate(value) { - return value instanceof Date && !isNaN(+value); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return switchAll; }); +/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(319); +/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(191); +/** PURE_IMPORTS_START _switchMap,_util_identity PURE_IMPORTS_END */ + + +function switchAll() { + return Object(_switchMap__WEBPACK_IMPORTED_MODULE_0__["switchMap"])(_util_identity__WEBPACK_IMPORTED_MODULE_1__["identity"]); } -//# sourceMappingURL=isDate.js.map +//# sourceMappingURL=switchAll.js.map /***/ }), -/* 290 */ +/* 319 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "delayWhen", function() { return delayWhen; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(170); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_Subscriber,_Observable,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchMap", function() { return switchMap; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(200); +/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(202); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(201); +/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(197); +/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(214); +/** PURE_IMPORTS_START tslib,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult,_map,_observable_from PURE_IMPORTS_END */ -function delayWhen(delayDurationSelector, subscriptionDelay) { - if (subscriptionDelay) { - return function (source) { - return new SubscriptionDelayObservable(source, subscriptionDelay) - .lift(new DelayWhenOperator(delayDurationSelector)); - }; + +function switchMap(project, resultSelector) { + if (typeof resultSelector === 'function') { + return function (source) { return source.pipe(switchMap(function (a, i) { return Object(_observable_from__WEBPACK_IMPORTED_MODULE_5__["from"])(project(a, i)).pipe(Object(_map__WEBPACK_IMPORTED_MODULE_4__["map"])(function (b, ii) { return resultSelector(a, b, i, ii); })); })); }; } - return function (source) { return source.lift(new DelayWhenOperator(delayDurationSelector)); }; + return function (source) { return source.lift(new SwitchMapOperator(project)); }; } -var DelayWhenOperator = /*@__PURE__*/ (function () { - function DelayWhenOperator(delayDurationSelector) { - this.delayDurationSelector = delayDurationSelector; +var SwitchMapOperator = /*@__PURE__*/ (function () { + function SwitchMapOperator(project) { + this.project = project; } - DelayWhenOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DelayWhenSubscriber(subscriber, this.delayDurationSelector)); + SwitchMapOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SwitchMapSubscriber(subscriber, this.project)); }; - return DelayWhenOperator; + return SwitchMapOperator; }()); -var DelayWhenSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DelayWhenSubscriber, _super); - function DelayWhenSubscriber(destination, delayDurationSelector) { +var SwitchMapSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SwitchMapSubscriber, _super); + function SwitchMapSubscriber(destination, project) { var _this = _super.call(this, destination) || this; - _this.delayDurationSelector = delayDurationSelector; - _this.completed = false; - _this.delayNotifierSubscriptions = []; + _this.project = project; _this.index = 0; return _this; } - DelayWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.destination.next(outerValue); - this.removeSubscription(innerSub); - this.tryComplete(); - }; - DelayWhenSubscriber.prototype.notifyError = function (error, innerSub) { - this._error(error); - }; - DelayWhenSubscriber.prototype.notifyComplete = function (innerSub) { - var value = this.removeSubscription(innerSub); - if (value) { - this.destination.next(value); - } - this.tryComplete(); - }; - DelayWhenSubscriber.prototype._next = function (value) { + SwitchMapSubscriber.prototype._next = function (value) { + var result; var index = this.index++; try { - var delayNotifier = this.delayDurationSelector(value, index); - if (delayNotifier) { - this.tryDelay(delayNotifier, value); - } - } - catch (err) { - this.destination.error(err); + result = this.project(value, index); } - }; - DelayWhenSubscriber.prototype._complete = function () { - this.completed = true; - this.tryComplete(); - this.unsubscribe(); - }; - DelayWhenSubscriber.prototype.removeSubscription = function (subscription) { - subscription.unsubscribe(); - var subscriptionIdx = this.delayNotifierSubscriptions.indexOf(subscription); - if (subscriptionIdx !== -1) { - this.delayNotifierSubscriptions.splice(subscriptionIdx, 1); + catch (error) { + this.destination.error(error); + return; } - return subscription.outerValue; + this._innerSub(result, value, index); }; - DelayWhenSubscriber.prototype.tryDelay = function (delayNotifier, value) { - var notifierSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, delayNotifier, value); - if (notifierSubscription && !notifierSubscription.closed) { - var destination = this.destination; - destination.add(notifierSubscription); - this.delayNotifierSubscriptions.push(notifierSubscription); + SwitchMapSubscriber.prototype._innerSub = function (result, value, index) { + var innerSubscription = this.innerSubscription; + if (innerSubscription) { + innerSubscription.unsubscribe(); } + var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](this, undefined, undefined); + var destination = this.destination; + destination.add(innerSubscriber); + this.innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, result, value, index, innerSubscriber); }; - DelayWhenSubscriber.prototype.tryComplete = function () { - if (this.completed && this.delayNotifierSubscriptions.length === 0) { - this.destination.complete(); + SwitchMapSubscriber.prototype._complete = function () { + var innerSubscription = this.innerSubscription; + if (!innerSubscription || innerSubscription.closed) { + _super.prototype._complete.call(this); } - }; - return DelayWhenSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); -var SubscriptionDelayObservable = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubscriptionDelayObservable, _super); - function SubscriptionDelayObservable(source, subscriptionDelay) { - var _this = _super.call(this) || this; - _this.source = source; - _this.subscriptionDelay = subscriptionDelay; - return _this; - } - SubscriptionDelayObservable.prototype._subscribe = function (subscriber) { - this.subscriptionDelay.subscribe(new SubscriptionDelaySubscriber(subscriber, this.source)); - }; - return SubscriptionDelayObservable; -}(_Observable__WEBPACK_IMPORTED_MODULE_2__["Observable"])); -var SubscriptionDelaySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubscriptionDelaySubscriber, _super); - function SubscriptionDelaySubscriber(parent, source) { - var _this = _super.call(this) || this; - _this.parent = parent; - _this.source = source; - _this.sourceSubscribed = false; - return _this; - } - SubscriptionDelaySubscriber.prototype._next = function (unused) { - this.subscribeToSource(); - }; - SubscriptionDelaySubscriber.prototype._error = function (err) { this.unsubscribe(); - this.parent.error(err); }; - SubscriptionDelaySubscriber.prototype._complete = function () { - this.unsubscribe(); - this.subscribeToSource(); + SwitchMapSubscriber.prototype._unsubscribe = function () { + this.innerSubscription = null; }; - SubscriptionDelaySubscriber.prototype.subscribeToSource = function () { - if (!this.sourceSubscribed) { - this.sourceSubscribed = true; - this.unsubscribe(); - this.source.subscribe(this.parent); + SwitchMapSubscriber.prototype.notifyComplete = function (innerSub) { + var destination = this.destination; + destination.remove(innerSub); + this.innerSubscription = null; + if (this.isStopped) { + _super.prototype._complete.call(this); } }; - return SubscriptionDelaySubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=delayWhen.js.map + SwitchMapSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.destination.next(innerValue); + }; + return SwitchMapSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +//# sourceMappingURL=switchMap.js.map /***/ }), -/* 291 */ +/* 320 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dematerialize", function() { return dematerialize; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return switchMapTo; }); +/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(319); +/** PURE_IMPORTS_START _switchMap PURE_IMPORTS_END */ -function dematerialize() { - return function dematerializeOperatorFunction(source) { - return source.lift(new DeMaterializeOperator()); - }; +function switchMapTo(innerObservable, resultSelector) { + return resultSelector ? Object(_switchMap__WEBPACK_IMPORTED_MODULE_0__["switchMap"])(function () { return innerObservable; }, resultSelector) : Object(_switchMap__WEBPACK_IMPORTED_MODULE_0__["switchMap"])(function () { return innerObservable; }); } -var DeMaterializeOperator = /*@__PURE__*/ (function () { - function DeMaterializeOperator() { - } - DeMaterializeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DeMaterializeSubscriber(subscriber)); - }; - return DeMaterializeOperator; -}()); -var DeMaterializeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DeMaterializeSubscriber, _super); - function DeMaterializeSubscriber(destination) { - return _super.call(this, destination) || this; - } - DeMaterializeSubscriber.prototype._next = function (value) { - value.observe(this.destination); - }; - return DeMaterializeSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=dematerialize.js.map +//# sourceMappingURL=switchMapTo.js.map /***/ }), -/* 292 */ +/* 321 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distinct", function() { return distinct; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DistinctSubscriber", function() { return DistinctSubscriber; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(230); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "takeUntil", function() { return takeUntil; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(201); /** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function distinct(keySelector, flushes) { - return function (source) { return source.lift(new DistinctOperator(keySelector, flushes)); }; +function takeUntil(notifier) { + return function (source) { return source.lift(new TakeUntilOperator(notifier)); }; } -var DistinctOperator = /*@__PURE__*/ (function () { - function DistinctOperator(keySelector, flushes) { - this.keySelector = keySelector; - this.flushes = flushes; +var TakeUntilOperator = /*@__PURE__*/ (function () { + function TakeUntilOperator(notifier) { + this.notifier = notifier; } - DistinctOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DistinctSubscriber(subscriber, this.keySelector, this.flushes)); + TakeUntilOperator.prototype.call = function (subscriber, source) { + var takeUntilSubscriber = new TakeUntilSubscriber(subscriber); + var notifierSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(takeUntilSubscriber, this.notifier); + if (notifierSubscription && !takeUntilSubscriber.seenValue) { + takeUntilSubscriber.add(notifierSubscription); + return source.subscribe(takeUntilSubscriber); + } + return takeUntilSubscriber; }; - return DistinctOperator; + return TakeUntilOperator; }()); -var DistinctSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DistinctSubscriber, _super); - function DistinctSubscriber(destination, keySelector, flushes) { +var TakeUntilSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeUntilSubscriber, _super); + function TakeUntilSubscriber(destination) { var _this = _super.call(this, destination) || this; - _this.keySelector = keySelector; - _this.values = new Set(); - if (flushes) { - _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, flushes)); - } + _this.seenValue = false; return _this; } - DistinctSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.values.clear(); - }; - DistinctSubscriber.prototype.notifyError = function (error, innerSub) { - this._error(error); - }; - DistinctSubscriber.prototype._next = function (value) { - if (this.keySelector) { - this._useKeySelector(value); - } - else { - this._finalizeNext(value, value); - } - }; - DistinctSubscriber.prototype._useKeySelector = function (value) { - var key; - var destination = this.destination; - try { - key = this.keySelector(value); - } - catch (err) { - destination.error(err); - return; - } - this._finalizeNext(key, value); + TakeUntilSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.seenValue = true; + this.complete(); }; - DistinctSubscriber.prototype._finalizeNext = function (key, value) { - var values = this.values; - if (!values.has(key)) { - values.add(key); - this.destination.next(value); - } + TakeUntilSubscriber.prototype.notifyComplete = function () { }; - return DistinctSubscriber; + return TakeUntilSubscriber; }(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); - -//# sourceMappingURL=distinct.js.map +//# sourceMappingURL=takeUntil.js.map /***/ }), -/* 293 */ +/* 322 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distinctUntilChanged", function() { return distinctUntilChanged; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "takeWhile", function() { return takeWhile; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function distinctUntilChanged(compare, keySelector) { - return function (source) { return source.lift(new DistinctUntilChangedOperator(compare, keySelector)); }; +function takeWhile(predicate, inclusive) { + if (inclusive === void 0) { + inclusive = false; + } + return function (source) { + return source.lift(new TakeWhileOperator(predicate, inclusive)); + }; } -var DistinctUntilChangedOperator = /*@__PURE__*/ (function () { - function DistinctUntilChangedOperator(compare, keySelector) { - this.compare = compare; - this.keySelector = keySelector; +var TakeWhileOperator = /*@__PURE__*/ (function () { + function TakeWhileOperator(predicate, inclusive) { + this.predicate = predicate; + this.inclusive = inclusive; } - DistinctUntilChangedOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DistinctUntilChangedSubscriber(subscriber, this.compare, this.keySelector)); + TakeWhileOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TakeWhileSubscriber(subscriber, this.predicate, this.inclusive)); }; - return DistinctUntilChangedOperator; + return TakeWhileOperator; }()); -var DistinctUntilChangedSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DistinctUntilChangedSubscriber, _super); - function DistinctUntilChangedSubscriber(destination, compare, keySelector) { +var TakeWhileSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeWhileSubscriber, _super); + function TakeWhileSubscriber(destination, predicate, inclusive) { var _this = _super.call(this, destination) || this; - _this.keySelector = keySelector; - _this.hasKey = false; - if (typeof compare === 'function') { - _this.compare = compare; - } + _this.predicate = predicate; + _this.inclusive = inclusive; + _this.index = 0; return _this; } - DistinctUntilChangedSubscriber.prototype.compare = function (x, y) { - return x === y; - }; - DistinctUntilChangedSubscriber.prototype._next = function (value) { - var key; + TakeWhileSubscriber.prototype._next = function (value) { + var destination = this.destination; + var result; try { - var keySelector = this.keySelector; - key = keySelector ? keySelector(value) : value; + result = this.predicate(value, this.index++); } catch (err) { - return this.destination.error(err); + destination.error(err); + return; } - var result = false; - if (this.hasKey) { - try { - var compare = this.compare; - result = compare(this.key, key); - } - catch (err) { - return this.destination.error(err); - } + this.nextOrComplete(value, result); + }; + TakeWhileSubscriber.prototype.nextOrComplete = function (value, predicateResult) { + var destination = this.destination; + if (Boolean(predicateResult)) { + destination.next(value); } else { - this.hasKey = true; - } - if (!result) { - this.key = key; - this.destination.next(value); + if (this.inclusive) { + destination.next(value); + } + destination.complete(); } }; - return DistinctUntilChangedSubscriber; + return TakeWhileSubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=distinctUntilChanged.js.map - - -/***/ }), -/* 294 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distinctUntilKeyChanged", function() { return distinctUntilKeyChanged; }); -/* harmony import */ var _distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(293); -/** PURE_IMPORTS_START _distinctUntilChanged PURE_IMPORTS_END */ - -function distinctUntilKeyChanged(key, compare) { - return Object(_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__["distinctUntilChanged"])(function (x, y) { return compare ? compare(x[key], y[key]) : x[key] === y[key]; }); -} -//# sourceMappingURL=distinctUntilKeyChanged.js.map +//# sourceMappingURL=takeWhile.js.map /***/ }), -/* 295 */ +/* 323 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "elementAt", function() { return elementAt; }); -/* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(222); -/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(264); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(296); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(287); -/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(297); -/** PURE_IMPORTS_START _util_ArgumentOutOfRangeError,_filter,_throwIfEmpty,_defaultIfEmpty,_take PURE_IMPORTS_END */ - - - - - -function elementAt(index, defaultValue) { - if (index < 0) { - throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_0__["ArgumentOutOfRangeError"](); - } - var hasDefaultValue = arguments.length >= 2; - return function (source) { - return source.pipe(Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(function (v, i) { return i === index; }), Object(_take__WEBPACK_IMPORTED_MODULE_4__["take"])(1), hasDefaultValue - ? Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__["defaultIfEmpty"])(defaultValue) - : Object(_throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__["throwIfEmpty"])(function () { return new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_0__["ArgumentOutOfRangeError"](); })); - }; -} -//# sourceMappingURL=elementAt.js.map - - -/***/ }), -/* 296 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tap", function() { return tap; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(156); +/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(144); +/** PURE_IMPORTS_START tslib,_Subscriber,_util_noop,_util_isFunction PURE_IMPORTS_END */ -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "throwIfEmpty", function() { return throwIfEmpty; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(223); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_util_EmptyError,_Subscriber PURE_IMPORTS_END */ -function throwIfEmpty(errorFactory) { - if (errorFactory === void 0) { - errorFactory = defaultErrorFactory; - } - return function (source) { - return source.lift(new ThrowIfEmptyOperator(errorFactory)); +function tap(nextOrObserver, error, complete) { + return function tapOperatorFunction(source) { + return source.lift(new DoOperator(nextOrObserver, error, complete)); }; } -var ThrowIfEmptyOperator = /*@__PURE__*/ (function () { - function ThrowIfEmptyOperator(errorFactory) { - this.errorFactory = errorFactory; +var DoOperator = /*@__PURE__*/ (function () { + function DoOperator(nextOrObserver, error, complete) { + this.nextOrObserver = nextOrObserver; + this.error = error; + this.complete = complete; } - ThrowIfEmptyOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ThrowIfEmptySubscriber(subscriber, this.errorFactory)); + DoOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TapSubscriber(subscriber, this.nextOrObserver, this.error, this.complete)); }; - return ThrowIfEmptyOperator; + return DoOperator; }()); -var ThrowIfEmptySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ThrowIfEmptySubscriber, _super); - function ThrowIfEmptySubscriber(destination, errorFactory) { +var TapSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TapSubscriber, _super); + function TapSubscriber(destination, observerOrNext, error, complete) { var _this = _super.call(this, destination) || this; - _this.errorFactory = errorFactory; - _this.hasValue = false; + _this._tapNext = _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + _this._tapError = _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + _this._tapComplete = _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + _this._tapError = error || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + _this._tapComplete = complete || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + if (Object(_util_isFunction__WEBPACK_IMPORTED_MODULE_3__["isFunction"])(observerOrNext)) { + _this._context = _this; + _this._tapNext = observerOrNext; + } + else if (observerOrNext) { + _this._context = observerOrNext; + _this._tapNext = observerOrNext.next || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + _this._tapError = observerOrNext.error || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + _this._tapComplete = observerOrNext.complete || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + } return _this; } - ThrowIfEmptySubscriber.prototype._next = function (value) { - this.hasValue = true; - this.destination.next(value); - }; - ThrowIfEmptySubscriber.prototype._complete = function () { - if (!this.hasValue) { - var err = void 0; - try { - err = this.errorFactory(); - } - catch (e) { - err = e; - } - this.destination.error(err); + TapSubscriber.prototype._next = function (value) { + try { + this._tapNext.call(this._context, value); } - else { - return this.destination.complete(); + catch (err) { + this.destination.error(err); + return; } + this.destination.next(value); }; - return ThrowIfEmptySubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_2__["Subscriber"])); -function defaultErrorFactory() { - return new _util_EmptyError__WEBPACK_IMPORTED_MODULE_1__["EmptyError"](); -} -//# sourceMappingURL=throwIfEmpty.js.map - - -/***/ }), -/* 297 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "take", function() { return take; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(222); -/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(203); -/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError,_observable_empty PURE_IMPORTS_END */ - - - - -function take(count) { - return function (source) { - if (count === 0) { - return Object(_observable_empty__WEBPACK_IMPORTED_MODULE_3__["empty"])(); + TapSubscriber.prototype._error = function (err) { + try { + this._tapError.call(this._context, err); } - else { - return source.lift(new TakeOperator(count)); + catch (err) { + this.destination.error(err); + return; } + this.destination.error(err); }; -} -var TakeOperator = /*@__PURE__*/ (function () { - function TakeOperator(total) { - this.total = total; - if (this.total < 0) { - throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__["ArgumentOutOfRangeError"]; + TapSubscriber.prototype._complete = function () { + try { + this._tapComplete.call(this._context); } - } - TakeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new TakeSubscriber(subscriber, this.total)); - }; - return TakeOperator; -}()); -var TakeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeSubscriber, _super); - function TakeSubscriber(destination, total) { - var _this = _super.call(this, destination) || this; - _this.total = total; - _this.count = 0; - return _this; - } - TakeSubscriber.prototype._next = function (value) { - var total = this.total; - var count = ++this.count; - if (count <= total) { - this.destination.next(value); - if (count === total) { - this.destination.complete(); - this.unsubscribe(); - } + catch (err) { + this.destination.error(err); + return; } + return this.destination.complete(); }; - return TakeSubscriber; + return TapSubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=take.js.map +//# sourceMappingURL=tap.js.map /***/ }), -/* 298 */ +/* 324 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "endWith", function() { return endWith; }); -/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(239); -/* harmony import */ var _observable_of__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(204); -/** PURE_IMPORTS_START _observable_concat,_observable_of PURE_IMPORTS_END */ - - -function endWith() { - var array = []; - for (var _i = 0; _i < arguments.length; _i++) { - array[_i] = arguments[_i]; - } - return function (source) { return Object(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"])(source, _observable_of__WEBPACK_IMPORTED_MODULE_1__["of"].apply(void 0, array)); }; -} -//# sourceMappingURL=endWith.js.map - - -/***/ }), -/* 299 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultThrottleConfig", function() { return defaultThrottleConfig; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "throttle", function() { return throttle; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "every", function() { return every; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function every(predicate, thisArg) { - return function (source) { return source.lift(new EveryOperator(predicate, thisArg, source)); }; +var defaultThrottleConfig = { + leading: true, + trailing: false +}; +function throttle(durationSelector, config) { + if (config === void 0) { + config = defaultThrottleConfig; + } + return function (source) { return source.lift(new ThrottleOperator(durationSelector, config.leading, config.trailing)); }; } -var EveryOperator = /*@__PURE__*/ (function () { - function EveryOperator(predicate, thisArg, source) { - this.predicate = predicate; - this.thisArg = thisArg; - this.source = source; +var ThrottleOperator = /*@__PURE__*/ (function () { + function ThrottleOperator(durationSelector, leading, trailing) { + this.durationSelector = durationSelector; + this.leading = leading; + this.trailing = trailing; } - EveryOperator.prototype.call = function (observer, source) { - return source.subscribe(new EverySubscriber(observer, this.predicate, this.thisArg, this.source)); + ThrottleOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ThrottleSubscriber(subscriber, this.durationSelector, this.leading, this.trailing)); }; - return EveryOperator; + return ThrottleOperator; }()); -var EverySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](EverySubscriber, _super); - function EverySubscriber(destination, predicate, thisArg, source) { +var ThrottleSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ThrottleSubscriber, _super); + function ThrottleSubscriber(destination, durationSelector, _leading, _trailing) { var _this = _super.call(this, destination) || this; - _this.predicate = predicate; - _this.thisArg = thisArg; - _this.source = source; - _this.index = 0; - _this.thisArg = thisArg || _this; + _this.destination = destination; + _this.durationSelector = durationSelector; + _this._leading = _leading; + _this._trailing = _trailing; + _this._hasValue = false; return _this; } - EverySubscriber.prototype.notifyComplete = function (everyValueMatch) { - this.destination.next(everyValueMatch); - this.destination.complete(); + ThrottleSubscriber.prototype._next = function (value) { + this._hasValue = true; + this._sendValue = value; + if (!this._throttled) { + if (this._leading) { + this.send(); + } + else { + this.throttle(value); + } + } }; - EverySubscriber.prototype._next = function (value) { - var result = false; + ThrottleSubscriber.prototype.send = function () { + var _a = this, _hasValue = _a._hasValue, _sendValue = _a._sendValue; + if (_hasValue) { + this.destination.next(_sendValue); + this.throttle(_sendValue); + } + this._hasValue = false; + this._sendValue = null; + }; + ThrottleSubscriber.prototype.throttle = function (value) { + var duration = this.tryDurationSelector(value); + if (!!duration) { + this.add(this._throttled = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, duration)); + } + }; + ThrottleSubscriber.prototype.tryDurationSelector = function (value) { try { - result = this.predicate.call(this.thisArg, value, this.index++, this.source); + return this.durationSelector(value); } catch (err) { this.destination.error(err); - return; + return null; } - if (!result) { - this.notifyComplete(false); + }; + ThrottleSubscriber.prototype.throttlingDone = function () { + var _a = this, _throttled = _a._throttled, _trailing = _a._trailing; + if (_throttled) { + _throttled.unsubscribe(); + } + this._throttled = null; + if (_trailing) { + this.send(); } }; - EverySubscriber.prototype._complete = function () { - this.notifyComplete(true); + ThrottleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.throttlingDone(); }; - return EverySubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=every.js.map + ThrottleSubscriber.prototype.notifyComplete = function () { + this.throttlingDone(); + }; + return ThrottleSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +//# sourceMappingURL=throttle.js.map /***/ }), -/* 300 */ +/* 325 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "exhaust", function() { return exhaust; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "throttleTime", function() { return throttleTime; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(186); +/* harmony import */ var _throttle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(324); +/** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async,_throttle PURE_IMPORTS_END */ -function exhaust() { - return function (source) { return source.lift(new SwitchFirstOperator()); }; + +function throttleTime(duration, scheduler, config) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; + } + if (config === void 0) { + config = _throttle__WEBPACK_IMPORTED_MODULE_3__["defaultThrottleConfig"]; + } + return function (source) { return source.lift(new ThrottleTimeOperator(duration, scheduler, config.leading, config.trailing)); }; } -var SwitchFirstOperator = /*@__PURE__*/ (function () { - function SwitchFirstOperator() { +var ThrottleTimeOperator = /*@__PURE__*/ (function () { + function ThrottleTimeOperator(duration, scheduler, leading, trailing) { + this.duration = duration; + this.scheduler = scheduler; + this.leading = leading; + this.trailing = trailing; } - SwitchFirstOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SwitchFirstSubscriber(subscriber)); + ThrottleTimeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ThrottleTimeSubscriber(subscriber, this.duration, this.scheduler, this.leading, this.trailing)); }; - return SwitchFirstOperator; + return ThrottleTimeOperator; }()); -var SwitchFirstSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SwitchFirstSubscriber, _super); - function SwitchFirstSubscriber(destination) { +var ThrottleTimeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ThrottleTimeSubscriber, _super); + function ThrottleTimeSubscriber(destination, duration, scheduler, leading, trailing) { var _this = _super.call(this, destination) || this; - _this.hasCompleted = false; - _this.hasSubscription = false; + _this.duration = duration; + _this.scheduler = scheduler; + _this.leading = leading; + _this.trailing = trailing; + _this._hasTrailingValue = false; + _this._trailingValue = null; return _this; } - SwitchFirstSubscriber.prototype._next = function (value) { - if (!this.hasSubscription) { - this.hasSubscription = true; - this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, value)); + ThrottleTimeSubscriber.prototype._next = function (value) { + if (this.throttled) { + if (this.trailing) { + this._trailingValue = value; + this._hasTrailingValue = true; + } + } + else { + this.add(this.throttled = this.scheduler.schedule(dispatchNext, this.duration, { subscriber: this })); + if (this.leading) { + this.destination.next(value); + } + else if (this.trailing) { + this._trailingValue = value; + this._hasTrailingValue = true; + } } }; - SwitchFirstSubscriber.prototype._complete = function () { - this.hasCompleted = true; - if (!this.hasSubscription) { + ThrottleTimeSubscriber.prototype._complete = function () { + if (this._hasTrailingValue) { + this.destination.next(this._trailingValue); this.destination.complete(); } - }; - SwitchFirstSubscriber.prototype.notifyComplete = function (innerSub) { - this.remove(innerSub); - this.hasSubscription = false; - if (this.hasCompleted) { + else { this.destination.complete(); } }; - return SwitchFirstSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=exhaust.js.map + ThrottleTimeSubscriber.prototype.clearThrottle = function () { + var throttled = this.throttled; + if (throttled) { + if (this.trailing && this._hasTrailingValue) { + this.destination.next(this._trailingValue); + this._trailingValue = null; + this._hasTrailingValue = false; + } + throttled.unsubscribe(); + this.remove(throttled); + this.throttled = null; + } + }; + return ThrottleTimeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +function dispatchNext(arg) { + var subscriber = arg.subscriber; + subscriber.clearThrottle(); +} +//# sourceMappingURL=throttleTime.js.map /***/ }), -/* 301 */ +/* 326 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "exhaustMap", function() { return exhaustMap; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(229); -/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(231); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(230); -/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(226); -/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(243); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult,_map,_observable_from PURE_IMPORTS_END */ - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeInterval", function() { return timeInterval; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TimeInterval", function() { return TimeInterval; }); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(186); +/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(286); +/* harmony import */ var _observable_defer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(221); +/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(197); +/** PURE_IMPORTS_START _scheduler_async,_scan,_observable_defer,_map PURE_IMPORTS_END */ -function exhaustMap(project, resultSelector) { - if (resultSelector) { - return function (source) { return source.pipe(exhaustMap(function (a, i) { return Object(_observable_from__WEBPACK_IMPORTED_MODULE_5__["from"])(project(a, i)).pipe(Object(_map__WEBPACK_IMPORTED_MODULE_4__["map"])(function (b, ii) { return resultSelector(a, b, i, ii); })); })); }; - } - return function (source) { - return source.lift(new ExhaustMapOperator(project)); +function timeInterval(scheduler) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; + } + return function (source) { + return Object(_observable_defer__WEBPACK_IMPORTED_MODULE_2__["defer"])(function () { + return source.pipe(Object(_scan__WEBPACK_IMPORTED_MODULE_1__["scan"])(function (_a, value) { + var current = _a.current; + return ({ value: value, current: scheduler.now(), last: current }); + }, { current: scheduler.now(), value: undefined, last: undefined }), Object(_map__WEBPACK_IMPORTED_MODULE_3__["map"])(function (_a) { + var current = _a.current, last = _a.last, value = _a.value; + return new TimeInterval(value, current - last); + })); + }); }; } -var ExhaustMapOperator = /*@__PURE__*/ (function () { - function ExhaustMapOperator(project) { - this.project = project; +var TimeInterval = /*@__PURE__*/ (function () { + function TimeInterval(value, interval) { + this.value = value; + this.interval = interval; } - ExhaustMapOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ExhaustMapSubscriber(subscriber, this.project)); - }; - return ExhaustMapOperator; + return TimeInterval; }()); -var ExhaustMapSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ExhaustMapSubscriber, _super); - function ExhaustMapSubscriber(destination, project) { - var _this = _super.call(this, destination) || this; - _this.project = project; - _this.hasSubscription = false; - _this.hasCompleted = false; - _this.index = 0; - return _this; - } - ExhaustMapSubscriber.prototype._next = function (value) { - if (!this.hasSubscription) { - this.tryNext(value); - } - }; - ExhaustMapSubscriber.prototype.tryNext = function (value) { - var result; - var index = this.index++; - try { - result = this.project(value, index); - } - catch (err) { - this.destination.error(err); - return; - } - this.hasSubscription = true; - this._innerSub(result, value, index); - }; - ExhaustMapSubscriber.prototype._innerSub = function (result, value, index) { - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](this, undefined, undefined); - var destination = this.destination; - destination.add(innerSubscriber); - Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, result, value, index, innerSubscriber); - }; - ExhaustMapSubscriber.prototype._complete = function () { - this.hasCompleted = true; - if (!this.hasSubscription) { - this.destination.complete(); - } - this.unsubscribe(); - }; - ExhaustMapSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.destination.next(innerValue); - }; - ExhaustMapSubscriber.prototype.notifyError = function (err) { - this.destination.error(err); - }; - ExhaustMapSubscriber.prototype.notifyComplete = function (innerSub) { - var destination = this.destination; - destination.remove(innerSub); - this.hasSubscription = false; - if (this.hasCompleted) { - this.destination.complete(); - } - }; - return ExhaustMapSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=exhaustMap.js.map + +//# sourceMappingURL=timeInterval.js.map /***/ }), -/* 302 */ +/* 327 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "expand", function() { return expand; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExpandOperator", function() { return ExpandOperator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExpandSubscriber", function() { return ExpandSubscriber; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return timeout; }); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(186); +/* harmony import */ var _util_TimeoutError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(195); +/* harmony import */ var _timeoutWith__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(328); +/* harmony import */ var _observable_throwError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(180); +/** PURE_IMPORTS_START _scheduler_async,_util_TimeoutError,_timeoutWith,_observable_throwError PURE_IMPORTS_END */ -function expand(project, concurrent, scheduler) { - if (concurrent === void 0) { - concurrent = Number.POSITIVE_INFINITY; - } + +function timeout(due, scheduler) { if (scheduler === void 0) { - scheduler = undefined; + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; } - concurrent = (concurrent || 0) < 1 ? Number.POSITIVE_INFINITY : concurrent; - return function (source) { return source.lift(new ExpandOperator(project, concurrent, scheduler)); }; + return Object(_timeoutWith__WEBPACK_IMPORTED_MODULE_2__["timeoutWith"])(due, Object(_observable_throwError__WEBPACK_IMPORTED_MODULE_3__["throwError"])(new _util_TimeoutError__WEBPACK_IMPORTED_MODULE_1__["TimeoutError"]()), scheduler); } -var ExpandOperator = /*@__PURE__*/ (function () { - function ExpandOperator(project, concurrent, scheduler) { - this.project = project; - this.concurrent = concurrent; - this.scheduler = scheduler; - } - ExpandOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ExpandSubscriber(subscriber, this.project, this.concurrent, this.scheduler)); - }; - return ExpandOperator; -}()); - -var ExpandSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ExpandSubscriber, _super); - function ExpandSubscriber(destination, project, concurrent, scheduler) { - var _this = _super.call(this, destination) || this; - _this.project = project; - _this.concurrent = concurrent; - _this.scheduler = scheduler; - _this.index = 0; - _this.active = 0; - _this.hasCompleted = false; - if (concurrent < Number.POSITIVE_INFINITY) { - _this.buffer = []; - } - return _this; - } - ExpandSubscriber.dispatch = function (arg) { - var subscriber = arg.subscriber, result = arg.result, value = arg.value, index = arg.index; - subscriber.subscribeToProjection(result, value, index); - }; - ExpandSubscriber.prototype._next = function (value) { - var destination = this.destination; - if (destination.closed) { - this._complete(); - return; - } - var index = this.index++; - if (this.active < this.concurrent) { - destination.next(value); - try { - var project = this.project; - var result = project(value, index); - if (!this.scheduler) { - this.subscribeToProjection(result, value, index); - } - else { - var state = { subscriber: this, result: result, value: value, index: index }; - var destination_1 = this.destination; - destination_1.add(this.scheduler.schedule(ExpandSubscriber.dispatch, 0, state)); - } - } - catch (e) { - destination.error(e); - } - } - else { - this.buffer.push(value); - } - }; - ExpandSubscriber.prototype.subscribeToProjection = function (result, value, index) { - this.active++; - var destination = this.destination; - destination.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, result, value, index)); - }; - ExpandSubscriber.prototype._complete = function () { - this.hasCompleted = true; - if (this.hasCompleted && this.active === 0) { - this.destination.complete(); - } - this.unsubscribe(); - }; - ExpandSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this._next(innerValue); - }; - ExpandSubscriber.prototype.notifyComplete = function (innerSub) { - var buffer = this.buffer; - var destination = this.destination; - destination.remove(innerSub); - this.active--; - if (buffer && buffer.length > 0) { - this._next(buffer.shift()); - } - if (this.hasCompleted && this.active === 0) { - this.destination.complete(); - } - }; - return ExpandSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); - -//# sourceMappingURL=expand.js.map +//# sourceMappingURL=timeout.js.map /***/ }), -/* 303 */ +/* 328 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "finalize", function() { return finalize; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(177); -/** PURE_IMPORTS_START tslib,_Subscriber,_Subscription PURE_IMPORTS_END */ - - - -function finalize(callback) { - return function (source) { return source.lift(new FinallyOperator(callback)); }; -} -var FinallyOperator = /*@__PURE__*/ (function () { - function FinallyOperator(callback) { - this.callback = callback; - } - FinallyOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new FinallySubscriber(subscriber, this.callback)); - }; - return FinallyOperator; -}()); -var FinallySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FinallySubscriber, _super); - function FinallySubscriber(destination, callback) { - var _this = _super.call(this, destination) || this; - _this.add(new _Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"](callback)); - return _this; - } - return FinallySubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=finalize.js.map +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeoutWith", function() { return timeoutWith; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(186); +/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(260); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -/***/ }), -/* 304 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "find", function() { return find; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FindValueOperator", function() { return FindValueOperator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FindValueSubscriber", function() { return FindValueSubscriber; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function find(predicate, thisArg) { - if (typeof predicate !== 'function') { - throw new TypeError('predicate is not a function'); +function timeoutWith(due, withObservable, scheduler) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; } - return function (source) { return source.lift(new FindValueOperator(predicate, source, false, thisArg)); }; + return function (source) { + var absoluteTimeout = Object(_util_isDate__WEBPACK_IMPORTED_MODULE_2__["isDate"])(due); + var waitFor = absoluteTimeout ? (+due - scheduler.now()) : Math.abs(due); + return source.lift(new TimeoutWithOperator(waitFor, absoluteTimeout, withObservable, scheduler)); + }; } -var FindValueOperator = /*@__PURE__*/ (function () { - function FindValueOperator(predicate, source, yieldIndex, thisArg) { - this.predicate = predicate; - this.source = source; - this.yieldIndex = yieldIndex; - this.thisArg = thisArg; +var TimeoutWithOperator = /*@__PURE__*/ (function () { + function TimeoutWithOperator(waitFor, absoluteTimeout, withObservable, scheduler) { + this.waitFor = waitFor; + this.absoluteTimeout = absoluteTimeout; + this.withObservable = withObservable; + this.scheduler = scheduler; } - FindValueOperator.prototype.call = function (observer, source) { - return source.subscribe(new FindValueSubscriber(observer, this.predicate, this.source, this.yieldIndex, this.thisArg)); + TimeoutWithOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TimeoutWithSubscriber(subscriber, this.absoluteTimeout, this.waitFor, this.withObservable, this.scheduler)); }; - return FindValueOperator; + return TimeoutWithOperator; }()); - -var FindValueSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FindValueSubscriber, _super); - function FindValueSubscriber(destination, predicate, source, yieldIndex, thisArg) { +var TimeoutWithSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TimeoutWithSubscriber, _super); + function TimeoutWithSubscriber(destination, absoluteTimeout, waitFor, withObservable, scheduler) { var _this = _super.call(this, destination) || this; - _this.predicate = predicate; - _this.source = source; - _this.yieldIndex = yieldIndex; - _this.thisArg = thisArg; - _this.index = 0; + _this.absoluteTimeout = absoluteTimeout; + _this.waitFor = waitFor; + _this.withObservable = withObservable; + _this.scheduler = scheduler; + _this.action = null; + _this.scheduleTimeout(); return _this; } - FindValueSubscriber.prototype.notifyComplete = function (value) { - var destination = this.destination; - destination.next(value); - destination.complete(); - this.unsubscribe(); + TimeoutWithSubscriber.dispatchTimeout = function (subscriber) { + var withObservable = subscriber.withObservable; + subscriber._unsubscribeAndRecycle(); + subscriber.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(subscriber, withObservable)); }; - FindValueSubscriber.prototype._next = function (value) { - var _a = this, predicate = _a.predicate, thisArg = _a.thisArg; - var index = this.index++; - try { - var result = predicate.call(thisArg || this, value, index, this.source); - if (result) { - this.notifyComplete(this.yieldIndex ? index : value); - } + TimeoutWithSubscriber.prototype.scheduleTimeout = function () { + var action = this.action; + if (action) { + this.action = action.schedule(this, this.waitFor); } - catch (err) { - this.destination.error(err); + else { + this.add(this.action = this.scheduler.schedule(TimeoutWithSubscriber.dispatchTimeout, this.waitFor, this)); } }; - FindValueSubscriber.prototype._complete = function () { - this.notifyComplete(this.yieldIndex ? -1 : undefined); + TimeoutWithSubscriber.prototype._next = function (value) { + if (!this.absoluteTimeout) { + this.scheduleTimeout(); + } + _super.prototype._next.call(this, value); }; - return FindValueSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); - -//# sourceMappingURL=find.js.map + TimeoutWithSubscriber.prototype._unsubscribe = function () { + this.action = null; + this.scheduler = null; + this.withObservable = null; + }; + return TimeoutWithSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); +//# sourceMappingURL=timeoutWith.js.map /***/ }), -/* 305 */ +/* 329 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findIndex", function() { return findIndex; }); -/* harmony import */ var _operators_find__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(304); -/** PURE_IMPORTS_START _operators_find PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timestamp", function() { return timestamp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Timestamp", function() { return Timestamp; }); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(186); +/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(197); +/** PURE_IMPORTS_START _scheduler_async,_map PURE_IMPORTS_END */ -function findIndex(predicate, thisArg) { - return function (source) { return source.lift(new _operators_find__WEBPACK_IMPORTED_MODULE_0__["FindValueOperator"](predicate, source, true, thisArg)); }; + +function timestamp(scheduler) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; + } + return Object(_map__WEBPACK_IMPORTED_MODULE_1__["map"])(function (value) { return new Timestamp(value, scheduler.now()); }); } -//# sourceMappingURL=findIndex.js.map +var Timestamp = /*@__PURE__*/ (function () { + function Timestamp(value, timestamp) { + this.value = value; + this.timestamp = timestamp; + } + return Timestamp; +}()); + +//# sourceMappingURL=timestamp.js.map /***/ }), -/* 306 */ +/* 330 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "first", function() { return first; }); -/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(223); -/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(264); -/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(297); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(287); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(296); -/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(220); -/** PURE_IMPORTS_START _util_EmptyError,_filter,_take,_defaultIfEmpty,_throwIfEmpty,_util_identity PURE_IMPORTS_END */ - - - - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return toArray; }); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(285); +/** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ -function first(predicate, defaultValue) { - var hasDefaultValue = arguments.length >= 2; - return function (source) { return source.pipe(predicate ? Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(function (v, i) { return predicate(v, i, source); }) : _util_identity__WEBPACK_IMPORTED_MODULE_5__["identity"], Object(_take__WEBPACK_IMPORTED_MODULE_2__["take"])(1), hasDefaultValue ? Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__["defaultIfEmpty"])(defaultValue) : Object(_throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__["throwIfEmpty"])(function () { return new _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__["EmptyError"](); })); }; +function toArrayReducer(arr, item, index) { + if (index === 0) { + return [item]; + } + arr.push(item); + return arr; } -//# sourceMappingURL=first.js.map +function toArray() { + return Object(_reduce__WEBPACK_IMPORTED_MODULE_0__["reduce"])(toArrayReducer, []); +} +//# sourceMappingURL=toArray.js.map /***/ }), -/* 307 */ +/* 331 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ignoreElements", function() { return ignoreElements; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "window", function() { return window; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(158); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_Subject,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function ignoreElements() { - return function ignoreElementsOperatorFunction(source) { - return source.lift(new IgnoreElementsOperator()); + + +function window(windowBoundaries) { + return function windowOperatorFunction(source) { + return source.lift(new WindowOperator(windowBoundaries)); }; } -var IgnoreElementsOperator = /*@__PURE__*/ (function () { - function IgnoreElementsOperator() { +var WindowOperator = /*@__PURE__*/ (function () { + function WindowOperator(windowBoundaries) { + this.windowBoundaries = windowBoundaries; } - IgnoreElementsOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new IgnoreElementsSubscriber(subscriber)); + WindowOperator.prototype.call = function (subscriber, source) { + var windowSubscriber = new WindowSubscriber(subscriber); + var sourceSubscription = source.subscribe(windowSubscriber); + if (!sourceSubscription.closed) { + windowSubscriber.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(windowSubscriber, this.windowBoundaries)); + } + return sourceSubscription; }; - return IgnoreElementsOperator; + return WindowOperator; }()); -var IgnoreElementsSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](IgnoreElementsSubscriber, _super); - function IgnoreElementsSubscriber() { - return _super !== null && _super.apply(this, arguments) || this; +var WindowSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowSubscriber, _super); + function WindowSubscriber(destination) { + var _this = _super.call(this, destination) || this; + _this.window = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); + destination.next(_this.window); + return _this; } - IgnoreElementsSubscriber.prototype._next = function (unused) { + WindowSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.openWindow(); }; - return IgnoreElementsSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=ignoreElements.js.map - - -/***/ }), -/* 308 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isEmpty", function() { return isEmpty; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ - - -function isEmpty() { - return function (source) { return source.lift(new IsEmptyOperator()); }; -} -var IsEmptyOperator = /*@__PURE__*/ (function () { - function IsEmptyOperator() { - } - IsEmptyOperator.prototype.call = function (observer, source) { - return source.subscribe(new IsEmptySubscriber(observer)); + WindowSubscriber.prototype.notifyError = function (error, innerSub) { + this._error(error); }; - return IsEmptyOperator; -}()); -var IsEmptySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](IsEmptySubscriber, _super); - function IsEmptySubscriber(destination) { - return _super.call(this, destination) || this; - } - IsEmptySubscriber.prototype.notifyComplete = function (isEmpty) { - var destination = this.destination; - destination.next(isEmpty); - destination.complete(); + WindowSubscriber.prototype.notifyComplete = function (innerSub) { + this._complete(); }; - IsEmptySubscriber.prototype._next = function (value) { - this.notifyComplete(false); + WindowSubscriber.prototype._next = function (value) { + this.window.next(value); }; - IsEmptySubscriber.prototype._complete = function () { - this.notifyComplete(true); + WindowSubscriber.prototype._error = function (err) { + this.window.error(err); + this.destination.error(err); }; - return IsEmptySubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=isEmpty.js.map + WindowSubscriber.prototype._complete = function () { + this.window.complete(); + this.destination.complete(); + }; + WindowSubscriber.prototype._unsubscribe = function () { + this.window = null; + }; + WindowSubscriber.prototype.openWindow = function () { + var prevWindow = this.window; + if (prevWindow) { + prevWindow.complete(); + } + var destination = this.destination; + var newWindow = this.window = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); + destination.next(newWindow); + }; + return WindowSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); +//# sourceMappingURL=window.js.map /***/ }), -/* 309 */ +/* 332 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "last", function() { return last; }); -/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(223); -/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(264); -/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(310); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(296); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(287); -/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(220); -/** PURE_IMPORTS_START _util_EmptyError,_filter,_takeLast,_throwIfEmpty,_defaultIfEmpty,_util_identity PURE_IMPORTS_END */ - - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windowCount", function() { return windowCount; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(158); +/** PURE_IMPORTS_START tslib,_Subscriber,_Subject PURE_IMPORTS_END */ -function last(predicate, defaultValue) { - var hasDefaultValue = arguments.length >= 2; - return function (source) { return source.pipe(predicate ? Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(function (v, i) { return predicate(v, i, source); }) : _util_identity__WEBPACK_IMPORTED_MODULE_5__["identity"], Object(_takeLast__WEBPACK_IMPORTED_MODULE_2__["takeLast"])(1), hasDefaultValue ? Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__["defaultIfEmpty"])(defaultValue) : Object(_throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__["throwIfEmpty"])(function () { return new _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__["EmptyError"](); })); }; +function windowCount(windowSize, startWindowEvery) { + if (startWindowEvery === void 0) { + startWindowEvery = 0; + } + return function windowCountOperatorFunction(source) { + return source.lift(new WindowCountOperator(windowSize, startWindowEvery)); + }; } -//# sourceMappingURL=last.js.map - - -/***/ }), -/* 310 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "takeLast", function() { return takeLast; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(222); -/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(203); -/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError,_observable_empty PURE_IMPORTS_END */ - - - - -function takeLast(count) { - return function takeLastOperatorFunction(source) { - if (count === 0) { - return Object(_observable_empty__WEBPACK_IMPORTED_MODULE_3__["empty"])(); - } - else { - return source.lift(new TakeLastOperator(count)); - } - }; -} -var TakeLastOperator = /*@__PURE__*/ (function () { - function TakeLastOperator(total) { - this.total = total; - if (this.total < 0) { - throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__["ArgumentOutOfRangeError"]; - } +var WindowCountOperator = /*@__PURE__*/ (function () { + function WindowCountOperator(windowSize, startWindowEvery) { + this.windowSize = windowSize; + this.startWindowEvery = startWindowEvery; } - TakeLastOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new TakeLastSubscriber(subscriber, this.total)); + WindowCountOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new WindowCountSubscriber(subscriber, this.windowSize, this.startWindowEvery)); }; - return TakeLastOperator; + return WindowCountOperator; }()); -var TakeLastSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeLastSubscriber, _super); - function TakeLastSubscriber(destination, total) { +var WindowCountSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowCountSubscriber, _super); + function WindowCountSubscriber(destination, windowSize, startWindowEvery) { var _this = _super.call(this, destination) || this; - _this.total = total; - _this.ring = new Array(); + _this.destination = destination; + _this.windowSize = windowSize; + _this.startWindowEvery = startWindowEvery; + _this.windows = [new _Subject__WEBPACK_IMPORTED_MODULE_2__["Subject"]()]; _this.count = 0; + destination.next(_this.windows[0]); return _this; } - TakeLastSubscriber.prototype._next = function (value) { - var ring = this.ring; - var total = this.total; - var count = this.count++; - if (ring.length < total) { - ring.push(value); + WindowCountSubscriber.prototype._next = function (value) { + var startWindowEvery = (this.startWindowEvery > 0) ? this.startWindowEvery : this.windowSize; + var destination = this.destination; + var windowSize = this.windowSize; + var windows = this.windows; + var len = windows.length; + for (var i = 0; i < len && !this.closed; i++) { + windows[i].next(value); } - else { - var index = count % total; - ring[index] = value; + var c = this.count - windowSize + 1; + if (c >= 0 && c % startWindowEvery === 0 && !this.closed) { + windows.shift().complete(); + } + if (++this.count % startWindowEvery === 0 && !this.closed) { + var window_1 = new _Subject__WEBPACK_IMPORTED_MODULE_2__["Subject"](); + windows.push(window_1); + destination.next(window_1); } }; - TakeLastSubscriber.prototype._complete = function () { - var destination = this.destination; - var count = this.count; - if (count > 0) { - var total = this.count >= this.total ? this.total : this.count; - var ring = this.ring; - for (var i = 0; i < total; i++) { - var idx = (count++) % total; - destination.next(ring[idx]); + WindowCountSubscriber.prototype._error = function (err) { + var windows = this.windows; + if (windows) { + while (windows.length > 0 && !this.closed) { + windows.shift().error(err); } } - destination.complete(); - }; - return TakeLastSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=takeLast.js.map - - -/***/ }), -/* 311 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapTo", function() { return mapTo; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ - - -function mapTo(value) { - return function (source) { return source.lift(new MapToOperator(value)); }; -} -var MapToOperator = /*@__PURE__*/ (function () { - function MapToOperator(value) { - this.value = value; - } - MapToOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new MapToSubscriber(subscriber, this.value)); - }; - return MapToOperator; -}()); -var MapToSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MapToSubscriber, _super); - function MapToSubscriber(destination, value) { - var _this = _super.call(this, destination) || this; - _this.value = value; - return _this; - } - MapToSubscriber.prototype._next = function (x) { - this.destination.next(this.value); - }; - return MapToSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=mapTo.js.map - - -/***/ }), -/* 312 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "materialize", function() { return materialize; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/* harmony import */ var _Notification__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(202); -/** PURE_IMPORTS_START tslib,_Subscriber,_Notification PURE_IMPORTS_END */ - - - -function materialize() { - return function materializeOperatorFunction(source) { - return source.lift(new MaterializeOperator()); - }; -} -var MaterializeOperator = /*@__PURE__*/ (function () { - function MaterializeOperator() { - } - MaterializeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new MaterializeSubscriber(subscriber)); - }; - return MaterializeOperator; -}()); -var MaterializeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MaterializeSubscriber, _super); - function MaterializeSubscriber(destination) { - return _super.call(this, destination) || this; - } - MaterializeSubscriber.prototype._next = function (value) { - this.destination.next(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createNext(value)); + this.destination.error(err); }; - MaterializeSubscriber.prototype._error = function (err) { - var destination = this.destination; - destination.next(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createError(err)); - destination.complete(); + WindowCountSubscriber.prototype._complete = function () { + var windows = this.windows; + if (windows) { + while (windows.length > 0 && !this.closed) { + windows.shift().complete(); + } + } + this.destination.complete(); }; - MaterializeSubscriber.prototype._complete = function () { - var destination = this.destination; - destination.next(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createComplete()); - destination.complete(); + WindowCountSubscriber.prototype._unsubscribe = function () { + this.count = 0; + this.windows = null; }; - return MaterializeSubscriber; + return WindowCountSubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=materialize.js.map +//# sourceMappingURL=windowCount.js.map /***/ }), -/* 313 */ +/* 333 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "max", function() { return max; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(314); -/** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ - -function max(comparer) { - var max = (typeof comparer === 'function') - ? function (x, y) { return comparer(x, y) > 0 ? x : y; } - : function (x, y) { return x > y ? x : y; }; - return Object(_reduce__WEBPACK_IMPORTED_MODULE_0__["reduce"])(max); -} -//# sourceMappingURL=max.js.map - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windowTime", function() { return windowTime; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(158); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(186); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(143); +/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(228); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(176); +/** PURE_IMPORTS_START tslib,_Subject,_scheduler_async,_Subscriber,_util_isNumeric,_util_isScheduler PURE_IMPORTS_END */ -/***/ }), -/* 314 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return reduce; }); -/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(315); -/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(310); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(287); -/* harmony import */ var _util_pipe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(184); -/** PURE_IMPORTS_START _scan,_takeLast,_defaultIfEmpty,_util_pipe PURE_IMPORTS_END */ -function reduce(accumulator, seed) { - if (arguments.length >= 2) { - return function reduceOperatorFunctionWithSeed(source) { - return Object(_util_pipe__WEBPACK_IMPORTED_MODULE_3__["pipe"])(Object(_scan__WEBPACK_IMPORTED_MODULE_0__["scan"])(accumulator, seed), Object(_takeLast__WEBPACK_IMPORTED_MODULE_1__["takeLast"])(1), Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__["defaultIfEmpty"])(seed))(source); - }; +function windowTime(windowTimeSpan) { + var scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; + var windowCreationInterval = null; + var maxWindowSize = Number.POSITIVE_INFINITY; + if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_5__["isScheduler"])(arguments[3])) { + scheduler = arguments[3]; } - return function reduceOperatorFunction(source) { - return Object(_util_pipe__WEBPACK_IMPORTED_MODULE_3__["pipe"])(Object(_scan__WEBPACK_IMPORTED_MODULE_0__["scan"])(function (acc, value, index) { return accumulator(acc, value, index + 1); }), Object(_takeLast__WEBPACK_IMPORTED_MODULE_1__["takeLast"])(1))(source); - }; -} -//# sourceMappingURL=reduce.js.map - - -/***/ }), -/* 315 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scan", function() { return scan; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ - - -function scan(accumulator, seed) { - var hasSeed = false; - if (arguments.length >= 2) { - hasSeed = true; + if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_5__["isScheduler"])(arguments[2])) { + scheduler = arguments[2]; } - return function scanOperatorFunction(source) { - return source.lift(new ScanOperator(accumulator, seed, hasSeed)); + else if (Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_4__["isNumeric"])(arguments[2])) { + maxWindowSize = arguments[2]; + } + if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_5__["isScheduler"])(arguments[1])) { + scheduler = arguments[1]; + } + else if (Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_4__["isNumeric"])(arguments[1])) { + windowCreationInterval = arguments[1]; + } + return function windowTimeOperatorFunction(source) { + return source.lift(new WindowTimeOperator(windowTimeSpan, windowCreationInterval, maxWindowSize, scheduler)); }; } -var ScanOperator = /*@__PURE__*/ (function () { - function ScanOperator(accumulator, seed, hasSeed) { - if (hasSeed === void 0) { - hasSeed = false; - } - this.accumulator = accumulator; - this.seed = seed; - this.hasSeed = hasSeed; +var WindowTimeOperator = /*@__PURE__*/ (function () { + function WindowTimeOperator(windowTimeSpan, windowCreationInterval, maxWindowSize, scheduler) { + this.windowTimeSpan = windowTimeSpan; + this.windowCreationInterval = windowCreationInterval; + this.maxWindowSize = maxWindowSize; + this.scheduler = scheduler; } - ScanOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ScanSubscriber(subscriber, this.accumulator, this.seed, this.hasSeed)); + WindowTimeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new WindowTimeSubscriber(subscriber, this.windowTimeSpan, this.windowCreationInterval, this.maxWindowSize, this.scheduler)); }; - return ScanOperator; + return WindowTimeOperator; }()); -var ScanSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ScanSubscriber, _super); - function ScanSubscriber(destination, accumulator, _seed, hasSeed) { - var _this = _super.call(this, destination) || this; - _this.accumulator = accumulator; - _this._seed = _seed; - _this.hasSeed = hasSeed; - _this.index = 0; +var CountedSubject = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CountedSubject, _super); + function CountedSubject() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this._numberOfNextedValues = 0; return _this; } - Object.defineProperty(ScanSubscriber.prototype, "seed", { + CountedSubject.prototype.next = function (value) { + this._numberOfNextedValues++; + _super.prototype.next.call(this, value); + }; + Object.defineProperty(CountedSubject.prototype, "numberOfNextedValues", { get: function () { - return this._seed; - }, - set: function (value) { - this.hasSeed = true; - this._seed = value; + return this._numberOfNextedValues; }, enumerable: true, configurable: true }); - ScanSubscriber.prototype._next = function (value) { - if (!this.hasSeed) { - this.seed = value; - this.destination.next(value); + return CountedSubject; +}(_Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"])); +var WindowTimeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowTimeSubscriber, _super); + function WindowTimeSubscriber(destination, windowTimeSpan, windowCreationInterval, maxWindowSize, scheduler) { + var _this = _super.call(this, destination) || this; + _this.destination = destination; + _this.windowTimeSpan = windowTimeSpan; + _this.windowCreationInterval = windowCreationInterval; + _this.maxWindowSize = maxWindowSize; + _this.scheduler = scheduler; + _this.windows = []; + var window = _this.openWindow(); + if (windowCreationInterval !== null && windowCreationInterval >= 0) { + var closeState = { subscriber: _this, window: window, context: null }; + var creationState = { windowTimeSpan: windowTimeSpan, windowCreationInterval: windowCreationInterval, subscriber: _this, scheduler: scheduler }; + _this.add(scheduler.schedule(dispatchWindowClose, windowTimeSpan, closeState)); + _this.add(scheduler.schedule(dispatchWindowCreation, windowCreationInterval, creationState)); } else { - return this._tryNext(value); + var timeSpanOnlyState = { subscriber: _this, window: window, windowTimeSpan: windowTimeSpan }; + _this.add(scheduler.schedule(dispatchWindowTimeSpanOnly, windowTimeSpan, timeSpanOnlyState)); + } + return _this; + } + WindowTimeSubscriber.prototype._next = function (value) { + var windows = this.windows; + var len = windows.length; + for (var i = 0; i < len; i++) { + var window_1 = windows[i]; + if (!window_1.closed) { + window_1.next(value); + if (window_1.numberOfNextedValues >= this.maxWindowSize) { + this.closeWindow(window_1); + } + } } }; - ScanSubscriber.prototype._tryNext = function (value) { - var index = this.index++; - var result; - try { - result = this.accumulator(this.seed, value, index); + WindowTimeSubscriber.prototype._error = function (err) { + var windows = this.windows; + while (windows.length > 0) { + windows.shift().error(err); } - catch (err) { - this.destination.error(err); + this.destination.error(err); + }; + WindowTimeSubscriber.prototype._complete = function () { + var windows = this.windows; + while (windows.length > 0) { + var window_2 = windows.shift(); + if (!window_2.closed) { + window_2.complete(); + } } - this.seed = result; - this.destination.next(result); + this.destination.complete(); }; - return ScanSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=scan.js.map - - -/***/ }), -/* 316 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return merge; }); -/* harmony import */ var _observable_merge__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(258); -/** PURE_IMPORTS_START _observable_merge PURE_IMPORTS_END */ - -function merge() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; + WindowTimeSubscriber.prototype.openWindow = function () { + var window = new CountedSubject(); + this.windows.push(window); + var destination = this.destination; + destination.next(window); + return window; + }; + WindowTimeSubscriber.prototype.closeWindow = function (window) { + window.complete(); + var windows = this.windows; + windows.splice(windows.indexOf(window), 1); + }; + return WindowTimeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__["Subscriber"])); +function dispatchWindowTimeSpanOnly(state) { + var subscriber = state.subscriber, windowTimeSpan = state.windowTimeSpan, window = state.window; + if (window) { + subscriber.closeWindow(window); } - return function (source) { return source.lift.call(_observable_merge__WEBPACK_IMPORTED_MODULE_0__["merge"].apply(void 0, [source].concat(observables))); }; + state.window = subscriber.openWindow(); + this.schedule(state, windowTimeSpan); } -//# sourceMappingURL=merge.js.map - - -/***/ }), -/* 317 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeMapTo", function() { return mergeMapTo; }); -/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(242); -/** PURE_IMPORTS_START _mergeMap PURE_IMPORTS_END */ - -function mergeMapTo(innerObservable, resultSelector, concurrent) { - if (concurrent === void 0) { - concurrent = Number.POSITIVE_INFINITY; - } - if (typeof resultSelector === 'function') { - return Object(_mergeMap__WEBPACK_IMPORTED_MODULE_0__["mergeMap"])(function () { return innerObservable; }, resultSelector, concurrent); - } - if (typeof resultSelector === 'number') { - concurrent = resultSelector; +function dispatchWindowCreation(state) { + var windowTimeSpan = state.windowTimeSpan, subscriber = state.subscriber, scheduler = state.scheduler, windowCreationInterval = state.windowCreationInterval; + var window = subscriber.openWindow(); + var action = this; + var context = { action: action, subscription: null }; + var timeSpanState = { subscriber: subscriber, window: window, context: context }; + context.subscription = scheduler.schedule(dispatchWindowClose, windowTimeSpan, timeSpanState); + action.add(context.subscription); + action.schedule(state, windowCreationInterval); +} +function dispatchWindowClose(state) { + var subscriber = state.subscriber, window = state.window, context = state.context; + if (context && context.action && context.subscription) { + context.action.remove(context.subscription); } - return Object(_mergeMap__WEBPACK_IMPORTED_MODULE_0__["mergeMap"])(function () { return innerObservable; }, concurrent); + subscriber.closeWindow(window); } -//# sourceMappingURL=mergeMapTo.js.map +//# sourceMappingURL=windowTime.js.map /***/ }), -/* 318 */ +/* 334 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeScan", function() { return mergeScan; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MergeScanOperator", function() { return MergeScanOperator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MergeScanSubscriber", function() { return MergeScanSubscriber; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(230); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(229); -/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(231); -/** PURE_IMPORTS_START tslib,_util_subscribeToResult,_OuterSubscriber,_InnerSubscriber PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windowToggle", function() { return windowToggle; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(158); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(148); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_Subject,_Subscription,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function mergeScan(accumulator, seed, concurrent) { - if (concurrent === void 0) { - concurrent = Number.POSITIVE_INFINITY; - } - return function (source) { return source.lift(new MergeScanOperator(accumulator, seed, concurrent)); }; + +function windowToggle(openings, closingSelector) { + return function (source) { return source.lift(new WindowToggleOperator(openings, closingSelector)); }; } -var MergeScanOperator = /*@__PURE__*/ (function () { - function MergeScanOperator(accumulator, seed, concurrent) { - this.accumulator = accumulator; - this.seed = seed; - this.concurrent = concurrent; +var WindowToggleOperator = /*@__PURE__*/ (function () { + function WindowToggleOperator(openings, closingSelector) { + this.openings = openings; + this.closingSelector = closingSelector; } - MergeScanOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new MergeScanSubscriber(subscriber, this.accumulator, this.seed, this.concurrent)); + WindowToggleOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new WindowToggleSubscriber(subscriber, this.openings, this.closingSelector)); }; - return MergeScanOperator; + return WindowToggleOperator; }()); - -var MergeScanSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MergeScanSubscriber, _super); - function MergeScanSubscriber(destination, accumulator, acc, concurrent) { +var WindowToggleSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowToggleSubscriber, _super); + function WindowToggleSubscriber(destination, openings, closingSelector) { var _this = _super.call(this, destination) || this; - _this.accumulator = accumulator; - _this.acc = acc; - _this.concurrent = concurrent; - _this.hasValue = false; - _this.hasCompleted = false; - _this.buffer = []; - _this.active = 0; - _this.index = 0; + _this.openings = openings; + _this.closingSelector = closingSelector; + _this.contexts = []; + _this.add(_this.openSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(_this, openings, openings)); return _this; } - MergeScanSubscriber.prototype._next = function (value) { - if (this.active < this.concurrent) { - var index = this.index++; - var destination = this.destination; - var ish = void 0; - try { - var accumulator = this.accumulator; - ish = accumulator(this.acc, value, index); + WindowToggleSubscriber.prototype._next = function (value) { + var contexts = this.contexts; + if (contexts) { + var len = contexts.length; + for (var i = 0; i < len; i++) { + contexts[i].window.next(value); } - catch (e) { - return destination.error(e); - } - this.active++; - this._innerSub(ish, value, index); - } - else { - this.buffer.push(value); } }; - MergeScanSubscriber.prototype._innerSub = function (ish, value, index) { - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_3__["InnerSubscriber"](this, undefined, undefined); - var destination = this.destination; - destination.add(innerSubscriber); - Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_1__["subscribeToResult"])(this, ish, value, index, innerSubscriber); - }; - MergeScanSubscriber.prototype._complete = function () { - this.hasCompleted = true; - if (this.active === 0 && this.buffer.length === 0) { - if (this.hasValue === false) { - this.destination.next(this.acc); + WindowToggleSubscriber.prototype._error = function (err) { + var contexts = this.contexts; + this.contexts = null; + if (contexts) { + var len = contexts.length; + var index = -1; + while (++index < len) { + var context_1 = contexts[index]; + context_1.window.error(err); + context_1.subscription.unsubscribe(); } - this.destination.complete(); } - this.unsubscribe(); - }; - MergeScanSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - var destination = this.destination; - this.acc = innerValue; - this.hasValue = true; - destination.next(innerValue); + _super.prototype._error.call(this, err); }; - MergeScanSubscriber.prototype.notifyComplete = function (innerSub) { - var buffer = this.buffer; - var destination = this.destination; - destination.remove(innerSub); - this.active--; - if (buffer.length > 0) { - this._next(buffer.shift()); + WindowToggleSubscriber.prototype._complete = function () { + var contexts = this.contexts; + this.contexts = null; + if (contexts) { + var len = contexts.length; + var index = -1; + while (++index < len) { + var context_2 = contexts[index]; + context_2.window.complete(); + context_2.subscription.unsubscribe(); + } } - else if (this.active === 0 && this.hasCompleted) { - if (this.hasValue === false) { - this.destination.next(this.acc); + _super.prototype._complete.call(this); + }; + WindowToggleSubscriber.prototype._unsubscribe = function () { + var contexts = this.contexts; + this.contexts = null; + if (contexts) { + var len = contexts.length; + var index = -1; + while (++index < len) { + var context_3 = contexts[index]; + context_3.window.unsubscribe(); + context_3.subscription.unsubscribe(); } - this.destination.complete(); } }; - return MergeScanSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); - -//# sourceMappingURL=mergeScan.js.map - - -/***/ }), -/* 319 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "min", function() { return min; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(314); -/** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ - -function min(comparer) { - var min = (typeof comparer === 'function') - ? function (x, y) { return comparer(x, y) < 0 ? x : y; } - : function (x, y) { return x < y ? x : y; }; - return Object(_reduce__WEBPACK_IMPORTED_MODULE_0__["reduce"])(min); -} -//# sourceMappingURL=min.js.map - - -/***/ }), -/* 320 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "multicast", function() { return multicast; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MulticastOperator", function() { return MulticastOperator; }); -/* harmony import */ var _observable_ConnectableObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(186); -/** PURE_IMPORTS_START _observable_ConnectableObservable PURE_IMPORTS_END */ - -function multicast(subjectOrSubjectFactory, selector) { - return function multicastOperatorFunction(source) { - var subjectFactory; - if (typeof subjectOrSubjectFactory === 'function') { - subjectFactory = subjectOrSubjectFactory; + WindowToggleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + if (outerValue === this.openings) { + var closingNotifier = void 0; + try { + var closingSelector = this.closingSelector; + closingNotifier = closingSelector(innerValue); + } + catch (e) { + return this.error(e); + } + var window_1 = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); + var subscription = new _Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"](); + var context_4 = { window: window_1, subscription: subscription }; + this.contexts.push(context_4); + var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, closingNotifier, context_4); + if (innerSubscription.closed) { + this.closeWindow(this.contexts.length - 1); + } + else { + innerSubscription.context = context_4; + subscription.add(innerSubscription); + } + this.destination.next(window_1); } else { - subjectFactory = function subjectFactory() { - return subjectOrSubjectFactory; - }; + this.closeWindow(this.contexts.indexOf(outerValue)); } - if (typeof selector === 'function') { - return source.lift(new MulticastOperator(subjectFactory, selector)); + }; + WindowToggleSubscriber.prototype.notifyError = function (err) { + this.error(err); + }; + WindowToggleSubscriber.prototype.notifyComplete = function (inner) { + if (inner !== this.openSubscription) { + this.closeWindow(this.contexts.indexOf(inner.context)); } - var connectable = Object.create(source, _observable_ConnectableObservable__WEBPACK_IMPORTED_MODULE_0__["connectableObservableDescriptor"]); - connectable.source = source; - connectable.subjectFactory = subjectFactory; - return connectable; }; -} -var MulticastOperator = /*@__PURE__*/ (function () { - function MulticastOperator(subjectFactory, selector) { - this.subjectFactory = subjectFactory; - this.selector = selector; - } - MulticastOperator.prototype.call = function (subscriber, source) { - var selector = this.selector; - var subject = this.subjectFactory(); - var subscription = selector(subject).subscribe(subscriber); - subscription.add(source.subscribe(subject)); - return subscription; + WindowToggleSubscriber.prototype.closeWindow = function (index) { + if (index === -1) { + return; + } + var contexts = this.contexts; + var context = contexts[index]; + var window = context.window, subscription = context.subscription; + contexts.splice(index, 1); + window.complete(); + subscription.unsubscribe(); }; - return MulticastOperator; -}()); - -//# sourceMappingURL=multicast.js.map + return WindowToggleSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); +//# sourceMappingURL=windowToggle.js.map /***/ }), -/* 321 */ +/* 335 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return onErrorResumeNext; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNextStatic", function() { return onErrorResumeNextStatic; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(243); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(178); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(229); -/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(231); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_observable_from,_util_isArray,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windowWhen", function() { return windowWhen; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(158); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_Subject,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function onErrorResumeNext() { - var nextSources = []; - for (var _i = 0; _i < arguments.length; _i++) { - nextSources[_i] = arguments[_i]; - } - if (nextSources.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_2__["isArray"])(nextSources[0])) { - nextSources = nextSources[0]; - } - return function (source) { return source.lift(new OnErrorResumeNextOperator(nextSources)); }; -} -function onErrorResumeNextStatic() { - var nextSources = []; - for (var _i = 0; _i < arguments.length; _i++) { - nextSources[_i] = arguments[_i]; - } - var source = null; - if (nextSources.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_2__["isArray"])(nextSources[0])) { - nextSources = nextSources[0]; - } - source = nextSources.shift(); - return Object(_observable_from__WEBPACK_IMPORTED_MODULE_1__["from"])(source, null).lift(new OnErrorResumeNextOperator(nextSources)); +function windowWhen(closingSelector) { + return function windowWhenOperatorFunction(source) { + return source.lift(new WindowOperator(closingSelector)); + }; } -var OnErrorResumeNextOperator = /*@__PURE__*/ (function () { - function OnErrorResumeNextOperator(nextSources) { - this.nextSources = nextSources; +var WindowOperator = /*@__PURE__*/ (function () { + function WindowOperator(closingSelector) { + this.closingSelector = closingSelector; } - OnErrorResumeNextOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new OnErrorResumeNextSubscriber(subscriber, this.nextSources)); + WindowOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new WindowSubscriber(subscriber, this.closingSelector)); }; - return OnErrorResumeNextOperator; + return WindowOperator; }()); -var OnErrorResumeNextSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](OnErrorResumeNextSubscriber, _super); - function OnErrorResumeNextSubscriber(destination, nextSources) { +var WindowSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowSubscriber, _super); + function WindowSubscriber(destination, closingSelector) { var _this = _super.call(this, destination) || this; _this.destination = destination; - _this.nextSources = nextSources; + _this.closingSelector = closingSelector; + _this.openWindow(); return _this; } - OnErrorResumeNextSubscriber.prototype.notifyError = function (error, innerSub) { - this.subscribeToNextSource(); + WindowSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.openWindow(innerSub); }; - OnErrorResumeNextSubscriber.prototype.notifyComplete = function (innerSub) { - this.subscribeToNextSource(); + WindowSubscriber.prototype.notifyError = function (error, innerSub) { + this._error(error); }; - OnErrorResumeNextSubscriber.prototype._error = function (err) { - this.subscribeToNextSource(); - this.unsubscribe(); + WindowSubscriber.prototype.notifyComplete = function (innerSub) { + this.openWindow(innerSub); }; - OnErrorResumeNextSubscriber.prototype._complete = function () { - this.subscribeToNextSource(); - this.unsubscribe(); + WindowSubscriber.prototype._next = function (value) { + this.window.next(value); }; - OnErrorResumeNextSubscriber.prototype.subscribeToNextSource = function () { - var next = this.nextSources.shift(); - if (!!next) { - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_4__["InnerSubscriber"](this, undefined, undefined); - var destination = this.destination; - destination.add(innerSubscriber); - Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_5__["subscribeToResult"])(this, next, undefined, undefined, innerSubscriber); + WindowSubscriber.prototype._error = function (err) { + this.window.error(err); + this.destination.error(err); + this.unsubscribeClosingNotification(); + }; + WindowSubscriber.prototype._complete = function () { + this.window.complete(); + this.destination.complete(); + this.unsubscribeClosingNotification(); + }; + WindowSubscriber.prototype.unsubscribeClosingNotification = function () { + if (this.closingNotification) { + this.closingNotification.unsubscribe(); } - else { - this.destination.complete(); + }; + WindowSubscriber.prototype.openWindow = function (innerSub) { + if (innerSub === void 0) { + innerSub = null; + } + if (innerSub) { + this.remove(innerSub); + innerSub.unsubscribe(); + } + var prevWindow = this.window; + if (prevWindow) { + prevWindow.complete(); + } + var window = this.window = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); + this.destination.next(window); + var closingNotifier; + try { + var closingSelector = this.closingSelector; + closingNotifier = closingSelector(); + } + catch (e) { + this.destination.error(e); + this.window.error(e); + return; } + this.add(this.closingNotification = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, closingNotifier)); }; - return OnErrorResumeNextSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); -//# sourceMappingURL=onErrorResumeNext.js.map + return WindowSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); +//# sourceMappingURL=windowWhen.js.map /***/ }), -/* 322 */ +/* 336 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pairwise", function() { return pairwise; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "withLatestFrom", function() { return withLatestFrom; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(200); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(201); +/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function pairwise() { - return function (source) { return source.lift(new PairwiseOperator()); }; + +function withLatestFrom() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return function (source) { + var project; + if (typeof args[args.length - 1] === 'function') { + project = args.pop(); + } + var observables = args; + return source.lift(new WithLatestFromOperator(observables, project)); + }; } -var PairwiseOperator = /*@__PURE__*/ (function () { - function PairwiseOperator() { +var WithLatestFromOperator = /*@__PURE__*/ (function () { + function WithLatestFromOperator(observables, project) { + this.observables = observables; + this.project = project; } - PairwiseOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new PairwiseSubscriber(subscriber)); + WithLatestFromOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new WithLatestFromSubscriber(subscriber, this.observables, this.project)); }; - return PairwiseOperator; + return WithLatestFromOperator; }()); -var PairwiseSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PairwiseSubscriber, _super); - function PairwiseSubscriber(destination) { +var WithLatestFromSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WithLatestFromSubscriber, _super); + function WithLatestFromSubscriber(destination, observables, project) { var _this = _super.call(this, destination) || this; - _this.hasPrev = false; + _this.observables = observables; + _this.project = project; + _this.toRespond = []; + var len = observables.length; + _this.values = new Array(len); + for (var i = 0; i < len; i++) { + _this.toRespond.push(i); + } + for (var i = 0; i < len; i++) { + var observable = observables[i]; + _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, observable, observable, i)); + } return _this; } - PairwiseSubscriber.prototype._next = function (value) { - var pair; - if (this.hasPrev) { - pair = [this.prev, value]; - } - else { - this.hasPrev = true; + WithLatestFromSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.values[outerIndex] = innerValue; + var toRespond = this.toRespond; + if (toRespond.length > 0) { + var found = toRespond.indexOf(outerIndex); + if (found !== -1) { + toRespond.splice(found, 1); + } } - this.prev = value; - if (pair) { - this.destination.next(pair); + }; + WithLatestFromSubscriber.prototype.notifyComplete = function () { + }; + WithLatestFromSubscriber.prototype._next = function (value) { + if (this.toRespond.length === 0) { + var args = [value].concat(this.values); + if (this.project) { + this._tryProject(args); + } + else { + this.destination.next(args); + } } }; - return PairwiseSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=pairwise.js.map - - -/***/ }), -/* 323 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return partition; }); -/* harmony import */ var _util_not__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(263); -/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(264); -/** PURE_IMPORTS_START _util_not,_filter PURE_IMPORTS_END */ - - -function partition(predicate, thisArg) { - return function (source) { - return [ - Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(predicate, thisArg)(source), - Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(Object(_util_not__WEBPACK_IMPORTED_MODULE_0__["not"])(predicate, thisArg))(source) - ]; + WithLatestFromSubscriber.prototype._tryProject = function (args) { + var result; + try { + result = this.project.apply(this, args); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.next(result); }; -} -//# sourceMappingURL=partition.js.map + return WithLatestFromSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +//# sourceMappingURL=withLatestFrom.js.map /***/ }), -/* 324 */ +/* 337 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pluck", function() { return pluck; }); -/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(226); -/** PURE_IMPORTS_START _map PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return zip; }); +/* harmony import */ var _observable_zip__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(240); +/** PURE_IMPORTS_START _observable_zip PURE_IMPORTS_END */ -function pluck() { - var properties = []; +function zip() { + var observables = []; for (var _i = 0; _i < arguments.length; _i++) { - properties[_i] = arguments[_i]; - } - var length = properties.length; - if (length === 0) { - throw new Error('list of properties cannot be empty.'); + observables[_i] = arguments[_i]; } - return function (source) { return Object(_map__WEBPACK_IMPORTED_MODULE_0__["map"])(plucker(properties, length))(source); }; -} -function plucker(props, length) { - var mapper = function (x) { - var currentProp = x; - for (var i = 0; i < length; i++) { - var p = currentProp[props[i]]; - if (typeof p !== 'undefined') { - currentProp = p; - } - else { - return undefined; - } - } - return currentProp; + return function zipOperatorFunction(source) { + return source.lift.call(_observable_zip__WEBPACK_IMPORTED_MODULE_0__["zip"].apply(void 0, [source].concat(observables))); }; - return mapper; } -//# sourceMappingURL=pluck.js.map +//# sourceMappingURL=zip.js.map /***/ }), -/* 325 */ +/* 338 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publish", function() { return publish; }); -/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(187); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(320); -/** PURE_IMPORTS_START _Subject,_multicast PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "zipAll", function() { return zipAll; }); +/* harmony import */ var _observable_zip__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(240); +/** PURE_IMPORTS_START _observable_zip PURE_IMPORTS_END */ -function publish(selector) { - return selector ? - Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(function () { return new _Subject__WEBPACK_IMPORTED_MODULE_0__["Subject"](); }, selector) : - Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(new _Subject__WEBPACK_IMPORTED_MODULE_0__["Subject"]()); +function zipAll(project) { + return function (source) { return source.lift(new _observable_zip__WEBPACK_IMPORTED_MODULE_0__["ZipOperator"](project)); }; } -//# sourceMappingURL=publish.js.map +//# sourceMappingURL=zipAll.js.map /***/ }), -/* 326 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 339 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishBehavior", function() { return publishBehavior; }); -/* harmony import */ var _BehaviorSubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(192); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(320); -/** PURE_IMPORTS_START _BehaviorSubject,_multicast PURE_IMPORTS_END */ - -function publishBehavior(value) { - return function (source) { return Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(new _BehaviorSubject__WEBPACK_IMPORTED_MODULE_0__["BehaviorSubject"](value))(source); }; -} -//# sourceMappingURL=publishBehavior.js.map +const callbacks = new Set(); +let called = false; -/***/ }), -/* 327 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +function exit(exit, signal) { + if (called) { + return; + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishLast", function() { return publishLast; }); -/* harmony import */ var _AsyncSubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(210); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(320); -/** PURE_IMPORTS_START _AsyncSubject,_multicast PURE_IMPORTS_END */ + called = true; + for (const callback of callbacks) { + callback(); + } -function publishLast() { - return function (source) { return Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(new _AsyncSubject__WEBPACK_IMPORTED_MODULE_0__["AsyncSubject"]())(source); }; + if (exit === true) { + process.exit(128 + signal); // eslint-disable-line unicorn/no-process-exit + } } -//# sourceMappingURL=publishLast.js.map +module.exports = callback => { + callbacks.add(callback); -/***/ }), -/* 328 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishReplay", function() { return publishReplay; }); -/* harmony import */ var _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(193); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(320); -/** PURE_IMPORTS_START _ReplaySubject,_multicast PURE_IMPORTS_END */ + if (callbacks.size === 1) { + process.once('exit', exit); + process.once('SIGINT', exit.bind(null, true, 2)); + process.once('SIGTERM', exit.bind(null, true, 15)); + // PM2 Cluster shutdown message. Caught to support async handlers with pm2, needed because + // explicitly calling process.exit() doesn't trigger the beforeExit event, and the exit + // event cannot support async handlers, since the event loop is never called after it. + process.on('message', message => { + if (message === 'shutdown') { + exit(true, -128); + } + }); + } -function publishReplay(bufferSize, windowTime, selectorOrScheduler, scheduler) { - if (selectorOrScheduler && typeof selectorOrScheduler !== 'function') { - scheduler = selectorOrScheduler; - } - var selector = typeof selectorOrScheduler === 'function' ? selectorOrScheduler : undefined; - var subject = new _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__["ReplaySubject"](bufferSize, windowTime, scheduler); - return function (source) { return Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(function () { return subject; }, selector)(source); }; -} -//# sourceMappingURL=publishReplay.js.map + return () => { + callbacks.delete(callback); + }; +}; /***/ }), -/* 329 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 340 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "race", function() { return race; }); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(178); -/* harmony import */ var _observable_race__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(265); -/** PURE_IMPORTS_START _util_isArray,_observable_race PURE_IMPORTS_END */ - -function race() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; - } - return function raceOperatorFunction(source) { - if (observables.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_0__["isArray"])(observables[0])) { - observables = observables[0]; - } - return source.lift.call(_observable_race__WEBPACK_IMPORTED_MODULE_1__["race"].apply(void 0, [source].concat(observables))); - }; +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const $isCliError = Symbol('isCliError'); +function createCliError(message) { + const error = new Error(message); + error[$isCliError] = true; + return error; } -//# sourceMappingURL=race.js.map +exports.createCliError = createCliError; +function isCliError(error) { + return error && !!error[$isCliError]; +} +exports.isCliError = isCliError; /***/ }), -/* 330 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 341 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "repeat", function() { return repeat; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(203); -/** PURE_IMPORTS_START tslib,_Subscriber,_observable_empty PURE_IMPORTS_END */ - - -function repeat(count) { - if (count === void 0) { - count = -1; +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(6); +const execa_1 = tslib_1.__importDefault(__webpack_require__(342)); +const fs_1 = __webpack_require__(349); +const Rx = tslib_1.__importStar(__webpack_require__(140)); +const operators_1 = __webpack_require__(241); +const chalk_1 = tslib_1.__importDefault(__webpack_require__(386)); +const tree_kill_1 = tslib_1.__importDefault(__webpack_require__(396)); +const util_1 = __webpack_require__(397); +const treeKillAsync = util_1.promisify((...args) => tree_kill_1.default(...args)); +const observe_lines_1 = __webpack_require__(398); +const errors_1 = __webpack_require__(340); +const SECOND = 1000; +const STOP_TIMEOUT = 30 * SECOND; +async function withTimeout(attempt, ms, onTimeout) { + const TIMEOUT = Symbol('timeout'); + try { + await Promise.race([ + attempt(), + new Promise((_, reject) => setTimeout(() => reject(TIMEOUT), ms)), + ]); } - return function (source) { - if (count === 0) { - return Object(_observable_empty__WEBPACK_IMPORTED_MODULE_2__["empty"])(); - } - else if (count < 0) { - return source.lift(new RepeatOperator(-1, source)); + catch (error) { + if (error === TIMEOUT) { + await onTimeout(); } else { - return source.lift(new RepeatOperator(count - 1, source)); + throw error; } - }; -} -var RepeatOperator = /*@__PURE__*/ (function () { - function RepeatOperator(count, source) { - this.count = count; - this.source = source; } - RepeatOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new RepeatSubscriber(subscriber, this.count, this.source)); - }; - return RepeatOperator; -}()); -var RepeatSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RepeatSubscriber, _super); - function RepeatSubscriber(destination, count, source) { - var _this = _super.call(this, destination) || this; - _this.count = count; - _this.source = source; - return _this; +} +function startProc(name, options, log) { + const { cmd, args, cwd, env, stdin } = options; + log.info('[%s] > %s', name, cmd, args.join(' ')); + // spawn fails with ENOENT when either the + // cmd or cwd don't exist, so we check for the cwd + // ahead of time so that the error is less ambiguous + try { + if (!fs_1.statSync(cwd).isDirectory()) { + throw new Error(`cwd "${cwd}" exists but is not a directory`); + } } - RepeatSubscriber.prototype.complete = function () { - if (!this.isStopped) { - var _a = this, source = _a.source, count = _a.count; - if (count === 0) { - return _super.prototype.complete.call(this); - } - else if (count > -1) { - this.count = count - 1; - } - source.subscribe(this._unsubscribeAndRecycle()); + catch (err) { + if (err.code === 'ENOENT') { + throw new Error(`cwd "${cwd}" does not exist`); } - }; - return RepeatSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=repeat.js.map - - -/***/ }), -/* 331 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "repeatWhen", function() { return repeatWhen; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(187); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_Subject,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - - - - -function repeatWhen(notifier) { - return function (source) { return source.lift(new RepeatWhenOperator(notifier)); }; -} -var RepeatWhenOperator = /*@__PURE__*/ (function () { - function RepeatWhenOperator(notifier) { - this.notifier = notifier; } - RepeatWhenOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new RepeatWhenSubscriber(subscriber, this.notifier, source)); - }; - return RepeatWhenOperator; -}()); -var RepeatWhenSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RepeatWhenSubscriber, _super); - function RepeatWhenSubscriber(destination, notifier, source) { - var _this = _super.call(this, destination) || this; - _this.notifier = notifier; - _this.source = source; - _this.sourceIsBeingSubscribedTo = true; - return _this; + const childProcess = execa_1.default(cmd, args, { + cwd, + env, + stdio: ['pipe', 'pipe', 'pipe'], + preferLocal: true, + }); + if (stdin) { + childProcess.stdin.end(stdin, 'utf8'); } - RepeatWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.sourceIsBeingSubscribedTo = true; - this.source.subscribe(this); - }; - RepeatWhenSubscriber.prototype.notifyComplete = function (innerSub) { - if (this.sourceIsBeingSubscribedTo === false) { - return _super.prototype.complete.call(this); - } - }; - RepeatWhenSubscriber.prototype.complete = function () { - this.sourceIsBeingSubscribedTo = false; - if (!this.isStopped) { - if (!this.retries) { - this.subscribeToRetries(); - } - if (!this.retriesSubscription || this.retriesSubscription.closed) { - return _super.prototype.complete.call(this); - } - this._unsubscribeAndRecycle(); - this.notifications.next(); - } - }; - RepeatWhenSubscriber.prototype._unsubscribe = function () { - var _a = this, notifications = _a.notifications, retriesSubscription = _a.retriesSubscription; - if (notifications) { - notifications.unsubscribe(); - this.notifications = null; - } - if (retriesSubscription) { - retriesSubscription.unsubscribe(); - this.retriesSubscription = null; + else { + childProcess.stdin.end(); + } + let stopCalled = false; + const outcome$ = Rx.race( + // observe first exit event + Rx.fromEvent(childProcess, 'exit').pipe(operators_1.take(1), operators_1.map(([code]) => { + if (stopCalled) { + return null; } - this.retries = null; - }; - RepeatWhenSubscriber.prototype._unsubscribeAndRecycle = function () { - var _unsubscribe = this._unsubscribe; - this._unsubscribe = null; - _super.prototype._unsubscribeAndRecycle.call(this); - this._unsubscribe = _unsubscribe; - return this; - }; - RepeatWhenSubscriber.prototype.subscribeToRetries = function () { - this.notifications = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); - var retries; - try { - var notifier = this.notifier; - retries = notifier(this.notifications); + // JVM exits with 143 on SIGTERM and 130 on SIGINT, dont' treat then as errors + if (code > 0 && !(code === 143 || code === 130)) { + throw errors_1.createCliError(`[${name}] exited with code ${code}`); } - catch (e) { - return _super.prototype.complete.call(this); + return code; + })), + // observe first error event + Rx.fromEvent(childProcess, 'error').pipe(operators_1.take(1), operators_1.mergeMap((err) => Rx.throwError(err)))).pipe(operators_1.share()); + const lines$ = Rx.merge(observe_lines_1.observeLines(childProcess.stdout), observe_lines_1.observeLines(childProcess.stderr)).pipe(operators_1.tap((line) => log.write(` ${chalk_1.default.gray('proc')} [${chalk_1.default.gray(name)}] ${line}`)), operators_1.share()); + const outcomePromise = Rx.merge(lines$.pipe(operators_1.ignoreElements()), outcome$).toPromise(); + async function stop(signal) { + if (stopCalled) { + return; } - this.retries = retries; - this.retriesSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, retries); + stopCalled = true; + await withTimeout(async () => { + log.debug(`Sending "${signal}" to proc "${name}"`); + await treeKillAsync(childProcess.pid, signal); + await outcomePromise; + }, STOP_TIMEOUT, async () => { + log.warning(`Proc "${name}" was sent "${signal}" didn't emit the "exit" or "error" events after ${STOP_TIMEOUT} ms, sending SIGKILL`); + await treeKillAsync(childProcess.pid, 'SIGKILL'); + }); + await withTimeout(async () => { + try { + await outcomePromise; + } + catch (error) { + // ignore + } + }, STOP_TIMEOUT, async () => { + throw new Error(`Proc "${name}" was stopped but never emitted either the "exit" or "error" event after ${STOP_TIMEOUT} ms`); + }); + } + return { + name, + lines$, + outcome$, + outcomePromise, + stop, }; - return RepeatWhenSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); -//# sourceMappingURL=repeatWhen.js.map +} +exports.startProc = startProc; /***/ }), -/* 332 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 342 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "retry", function() { return retry; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +const path = __webpack_require__(4); +const childProcess = __webpack_require__(343); +const crossSpawn = __webpack_require__(344); +const stripFinalNewline = __webpack_require__(358); +const npmRunPath = __webpack_require__(359); +const onetime = __webpack_require__(360); +const makeError = __webpack_require__(362); +const normalizeStdio = __webpack_require__(368); +const {spawnedKill, spawnedCancel, setupTimeout, setExitHandler} = __webpack_require__(369); +const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = __webpack_require__(374); +const {mergePromise, getSpawnedPromise} = __webpack_require__(384); +const {joinCommand, parseCommand} = __webpack_require__(385); -function retry(count) { - if (count === void 0) { - count = -1; - } - return function (source) { return source.lift(new RetryOperator(count, source)); }; -} -var RetryOperator = /*@__PURE__*/ (function () { - function RetryOperator(count, source) { - this.count = count; - this.source = source; - } - RetryOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new RetrySubscriber(subscriber, this.count, this.source)); - }; - return RetryOperator; -}()); -var RetrySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RetrySubscriber, _super); - function RetrySubscriber(destination, count, source) { - var _this = _super.call(this, destination) || this; - _this.count = count; - _this.source = source; - return _this; - } - RetrySubscriber.prototype.error = function (err) { - if (!this.isStopped) { - var _a = this, source = _a.source, count = _a.count; - if (count === 0) { - return _super.prototype.error.call(this, err); - } - else if (count > -1) { - this.count = count - 1; - } - source.subscribe(this._unsubscribeAndRecycle()); - } - }; - return RetrySubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=retry.js.map +const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100; +const getEnv = ({env: envOption, extendEnv, preferLocal, localDir, execPath}) => { + const env = extendEnv ? {...process.env, ...envOption} : envOption; -/***/ }), -/* 333 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + if (preferLocal) { + return npmRunPath.env({env, cwd: localDir, execPath}); + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "retryWhen", function() { return retryWhen; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(187); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_Subject,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ + return env; +}; +const handleArgs = (file, args, options = {}) => { + const parsed = crossSpawn._parse(file, args, options); + file = parsed.command; + args = parsed.args; + options = parsed.options; + options = { + maxBuffer: DEFAULT_MAX_BUFFER, + buffer: true, + stripFinalNewline: true, + extendEnv: true, + preferLocal: false, + localDir: options.cwd || process.cwd(), + execPath: process.execPath, + encoding: 'utf8', + reject: true, + cleanup: true, + all: false, + windowsHide: true, + ...options + }; + options.env = getEnv(options); -function retryWhen(notifier) { - return function (source) { return source.lift(new RetryWhenOperator(notifier, source)); }; -} -var RetryWhenOperator = /*@__PURE__*/ (function () { - function RetryWhenOperator(notifier, source) { - this.notifier = notifier; - this.source = source; - } - RetryWhenOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new RetryWhenSubscriber(subscriber, this.notifier, this.source)); - }; - return RetryWhenOperator; -}()); -var RetryWhenSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RetryWhenSubscriber, _super); - function RetryWhenSubscriber(destination, notifier, source) { - var _this = _super.call(this, destination) || this; - _this.notifier = notifier; - _this.source = source; - return _this; - } - RetryWhenSubscriber.prototype.error = function (err) { - if (!this.isStopped) { - var errors = this.errors; - var retries = this.retries; - var retriesSubscription = this.retriesSubscription; - if (!retries) { - errors = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); - try { - var notifier = this.notifier; - retries = notifier(errors); - } - catch (e) { - return _super.prototype.error.call(this, e); - } - retriesSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, retries); - } - else { - this.errors = null; - this.retriesSubscription = null; - } - this._unsubscribeAndRecycle(); - this.errors = errors; - this.retries = retries; - this.retriesSubscription = retriesSubscription; - errors.next(err); - } - }; - RetryWhenSubscriber.prototype._unsubscribe = function () { - var _a = this, errors = _a.errors, retriesSubscription = _a.retriesSubscription; - if (errors) { - errors.unsubscribe(); - this.errors = null; - } - if (retriesSubscription) { - retriesSubscription.unsubscribe(); - this.retriesSubscription = null; - } - this.retries = null; - }; - RetryWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - var _unsubscribe = this._unsubscribe; - this._unsubscribe = null; - this._unsubscribeAndRecycle(); - this._unsubscribe = _unsubscribe; - this.source.subscribe(this); - }; - return RetryWhenSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); -//# sourceMappingURL=retryWhen.js.map + options.stdio = normalizeStdio(options); + if (process.platform === 'win32' && path.basename(file, '.exe') === 'cmd') { + // #116 + args.unshift('/q'); + } -/***/ }), -/* 334 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + return {file, args, options, parsed}; +}; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sample", function() { return sample; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ +const handleOutput = (options, value, error) => { + if (typeof value !== 'string' && !Buffer.isBuffer(value)) { + // When `execa.sync()` errors, we normalize it to '' to mimic `execa()` + return error === undefined ? undefined : ''; + } + if (options.stripFinalNewline) { + return stripFinalNewline(value); + } + return value; +}; -function sample(notifier) { - return function (source) { return source.lift(new SampleOperator(notifier)); }; -} -var SampleOperator = /*@__PURE__*/ (function () { - function SampleOperator(notifier) { - this.notifier = notifier; - } - SampleOperator.prototype.call = function (subscriber, source) { - var sampleSubscriber = new SampleSubscriber(subscriber); - var subscription = source.subscribe(sampleSubscriber); - subscription.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(sampleSubscriber, this.notifier)); - return subscription; - }; - return SampleOperator; -}()); -var SampleSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SampleSubscriber, _super); - function SampleSubscriber() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.hasValue = false; - return _this; - } - SampleSubscriber.prototype._next = function (value) { - this.value = value; - this.hasValue = true; - }; - SampleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.emitValue(); - }; - SampleSubscriber.prototype.notifyComplete = function () { - this.emitValue(); - }; - SampleSubscriber.prototype.emitValue = function () { - if (this.hasValue) { - this.hasValue = false; - this.destination.next(this.value); - } - }; - return SampleSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=sample.js.map +const execa = (file, args, options) => { + const parsed = handleArgs(file, args, options); + const command = joinCommand(file, args); + let spawned; + try { + spawned = childProcess.spawn(parsed.file, parsed.args, parsed.options); + } catch (error) { + // Ensure the returned error is always both a promise and a child process + const dummySpawned = new childProcess.ChildProcess(); + const errorPromise = Promise.reject(makeError({ + error, + stdout: '', + stderr: '', + all: '', + command, + parsed, + timedOut: false, + isCanceled: false, + killed: false + })); + return mergePromise(dummySpawned, errorPromise); + } -/***/ }), -/* 335 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + const spawnedPromise = getSpawnedPromise(spawned); + const timedPromise = setupTimeout(spawned, parsed.options, spawnedPromise); + const processDone = setExitHandler(spawned, parsed.options, timedPromise); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sampleTime", function() { return sampleTime; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(215); -/** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async PURE_IMPORTS_END */ + const context = {isCanceled: false}; + spawned.kill = spawnedKill.bind(null, spawned.kill.bind(spawned)); + spawned.cancel = spawnedCancel.bind(null, spawned, context); + const handlePromise = async () => { + const [{error, exitCode, signal, timedOut}, stdoutResult, stderrResult, allResult] = await getSpawnedResult(spawned, parsed.options, processDone); + const stdout = handleOutput(parsed.options, stdoutResult); + const stderr = handleOutput(parsed.options, stderrResult); + const all = handleOutput(parsed.options, allResult); -function sampleTime(period, scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; - } - return function (source) { return source.lift(new SampleTimeOperator(period, scheduler)); }; -} -var SampleTimeOperator = /*@__PURE__*/ (function () { - function SampleTimeOperator(period, scheduler) { - this.period = period; - this.scheduler = scheduler; - } - SampleTimeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SampleTimeSubscriber(subscriber, this.period, this.scheduler)); - }; - return SampleTimeOperator; -}()); -var SampleTimeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SampleTimeSubscriber, _super); - function SampleTimeSubscriber(destination, period, scheduler) { - var _this = _super.call(this, destination) || this; - _this.period = period; - _this.scheduler = scheduler; - _this.hasValue = false; - _this.add(scheduler.schedule(dispatchNotification, period, { subscriber: _this, period: period })); - return _this; - } - SampleTimeSubscriber.prototype._next = function (value) { - this.lastValue = value; - this.hasValue = true; - }; - SampleTimeSubscriber.prototype.notifyNext = function () { - if (this.hasValue) { - this.hasValue = false; - this.destination.next(this.lastValue); - } - }; - return SampleTimeSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -function dispatchNotification(state) { - var subscriber = state.subscriber, period = state.period; - subscriber.notifyNext(); - this.schedule(state, period); -} -//# sourceMappingURL=sampleTime.js.map + if (error || exitCode !== 0 || signal !== null) { + const returnedError = makeError({ + error, + exitCode, + signal, + stdout, + stderr, + all, + command, + parsed, + timedOut, + isCanceled: context.isCanceled, + killed: spawned.killed + }); + if (!parsed.options.reject) { + return returnedError; + } -/***/ }), -/* 336 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + throw returnedError; + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sequenceEqual", function() { return sequenceEqual; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SequenceEqualOperator", function() { return SequenceEqualOperator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SequenceEqualSubscriber", function() { return SequenceEqualSubscriber; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + return { + command, + exitCode: 0, + stdout, + stderr, + all, + failed: false, + timedOut: false, + isCanceled: false, + killed: false + }; + }; + const handlePromiseOnce = onetime(handlePromise); -function sequenceEqual(compareTo, comparator) { - return function (source) { return source.lift(new SequenceEqualOperator(compareTo, comparator)); }; -} -var SequenceEqualOperator = /*@__PURE__*/ (function () { - function SequenceEqualOperator(compareTo, comparator) { - this.compareTo = compareTo; - this.comparator = comparator; - } - SequenceEqualOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SequenceEqualSubscriber(subscriber, this.compareTo, this.comparator)); - }; - return SequenceEqualOperator; -}()); + crossSpawn._enoent.hookChildProcess(spawned, parsed.parsed); -var SequenceEqualSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SequenceEqualSubscriber, _super); - function SequenceEqualSubscriber(destination, compareTo, comparator) { - var _this = _super.call(this, destination) || this; - _this.compareTo = compareTo; - _this.comparator = comparator; - _this._a = []; - _this._b = []; - _this._oneComplete = false; - _this.destination.add(compareTo.subscribe(new SequenceEqualCompareToSubscriber(destination, _this))); - return _this; - } - SequenceEqualSubscriber.prototype._next = function (value) { - if (this._oneComplete && this._b.length === 0) { - this.emit(false); - } - else { - this._a.push(value); - this.checkValues(); - } - }; - SequenceEqualSubscriber.prototype._complete = function () { - if (this._oneComplete) { - this.emit(this._a.length === 0 && this._b.length === 0); - } - else { - this._oneComplete = true; - } - this.unsubscribe(); - }; - SequenceEqualSubscriber.prototype.checkValues = function () { - var _c = this, _a = _c._a, _b = _c._b, comparator = _c.comparator; - while (_a.length > 0 && _b.length > 0) { - var a = _a.shift(); - var b = _b.shift(); - var areEqual = false; - try { - areEqual = comparator ? comparator(a, b) : a === b; - } - catch (e) { - this.destination.error(e); - } - if (!areEqual) { - this.emit(false); - } - } - }; - SequenceEqualSubscriber.prototype.emit = function (value) { - var destination = this.destination; - destination.next(value); - destination.complete(); - }; - SequenceEqualSubscriber.prototype.nextB = function (value) { - if (this._oneComplete && this._a.length === 0) { - this.emit(false); - } - else { - this._b.push(value); - this.checkValues(); - } - }; - SequenceEqualSubscriber.prototype.completeB = function () { - if (this._oneComplete) { - this.emit(this._a.length === 0 && this._b.length === 0); - } - else { - this._oneComplete = true; - } - }; - return SequenceEqualSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); + handleInput(spawned, parsed.options.input); -var SequenceEqualCompareToSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SequenceEqualCompareToSubscriber, _super); - function SequenceEqualCompareToSubscriber(destination, parent) { - var _this = _super.call(this, destination) || this; - _this.parent = parent; - return _this; - } - SequenceEqualCompareToSubscriber.prototype._next = function (value) { - this.parent.nextB(value); - }; - SequenceEqualCompareToSubscriber.prototype._error = function (err) { - this.parent.error(err); - this.unsubscribe(); - }; - SequenceEqualCompareToSubscriber.prototype._complete = function () { - this.parent.completeB(); - this.unsubscribe(); - }; - return SequenceEqualCompareToSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=sequenceEqual.js.map + spawned.all = makeAllStream(spawned, parsed.options); + return mergePromise(spawned, handlePromiseOnce); +}; -/***/ }), -/* 337 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +module.exports = execa; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "share", function() { return share; }); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(320); -/* harmony import */ var _refCount__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(190); -/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(187); -/** PURE_IMPORTS_START _multicast,_refCount,_Subject PURE_IMPORTS_END */ +module.exports.sync = (file, args, options) => { + const parsed = handleArgs(file, args, options); + const command = joinCommand(file, args); + + validateInputSync(parsed.options); + + let result; + try { + result = childProcess.spawnSync(parsed.file, parsed.args, parsed.options); + } catch (error) { + throw makeError({ + error, + stdout: '', + stderr: '', + all: '', + command, + parsed, + timedOut: false, + isCanceled: false, + killed: false + }); + } + + const stdout = handleOutput(parsed.options, result.stdout, result.error); + const stderr = handleOutput(parsed.options, result.stderr, result.error); + if (result.error || result.status !== 0 || result.signal !== null) { + const error = makeError({ + stdout, + stderr, + error: result.error, + signal: result.signal, + exitCode: result.status, + command, + parsed, + timedOut: result.error && result.error.code === 'ETIMEDOUT', + isCanceled: false, + killed: result.signal !== null + }); + if (!parsed.options.reject) { + return error; + } -function shareSubjectFactory() { - return new _Subject__WEBPACK_IMPORTED_MODULE_2__["Subject"](); -} -function share() { - return function (source) { return Object(_refCount__WEBPACK_IMPORTED_MODULE_1__["refCount"])()(Object(_multicast__WEBPACK_IMPORTED_MODULE_0__["multicast"])(shareSubjectFactory)(source)); }; -} -//# sourceMappingURL=share.js.map + throw error; + } + + return { + command, + exitCode: 0, + stdout, + stderr, + failed: false, + timedOut: false, + isCanceled: false, + killed: false + }; +}; + +module.exports.command = (command, options) => { + const [file, ...args] = parseCommand(command); + return execa(file, args, options); +}; + +module.exports.commandSync = (command, options) => { + const [file, ...args] = parseCommand(command); + return execa.sync(file, args, options); +}; + +module.exports.node = (scriptPath, args, options = {}) => { + if (args && !Array.isArray(args) && typeof args === 'object') { + options = args; + args = []; + } + + const stdio = normalizeStdio.node(options); + + const {nodePath = process.execPath, nodeOptions = process.execArgv} = options; + + return execa( + nodePath, + [ + ...nodeOptions, + scriptPath, + ...(Array.isArray(args) ? args : []) + ], + { + ...options, + stdin: undefined, + stdout: undefined, + stderr: undefined, + stdio, + shell: false + } + ); +}; /***/ }), -/* 338 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 343 */ +/***/ (function(module, exports) { + +module.exports = require("child_process"); + +/***/ }), +/* 344 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shareReplay", function() { return shareReplay; }); -/* harmony import */ var _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(193); -/** PURE_IMPORTS_START _ReplaySubject PURE_IMPORTS_END */ -function shareReplay(configOrBufferSize, windowTime, scheduler) { - var config; - if (configOrBufferSize && typeof configOrBufferSize === 'object') { - config = configOrBufferSize; - } - else { - config = { - bufferSize: configOrBufferSize, - windowTime: windowTime, - refCount: false, - scheduler: scheduler - }; - } - return function (source) { return source.lift(shareReplayOperator(config)); }; + +const cp = __webpack_require__(343); +const parse = __webpack_require__(345); +const enoent = __webpack_require__(357); + +function spawn(command, args, options) { + // Parse the arguments + const parsed = parse(command, args, options); + + // Spawn the child process + const spawned = cp.spawn(parsed.command, parsed.args, parsed.options); + + // Hook into child process "exit" event to emit an error if the command + // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + enoent.hookChildProcess(spawned, parsed); + + return spawned; } -function shareReplayOperator(_a) { - var _b = _a.bufferSize, bufferSize = _b === void 0 ? Number.POSITIVE_INFINITY : _b, _c = _a.windowTime, windowTime = _c === void 0 ? Number.POSITIVE_INFINITY : _c, useRefCount = _a.refCount, scheduler = _a.scheduler; - var subject; - var refCount = 0; - var subscription; - var hasError = false; - var isComplete = false; - return function shareReplayOperation(source) { - refCount++; - if (!subject || hasError) { - hasError = false; - subject = new _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__["ReplaySubject"](bufferSize, windowTime, scheduler); - subscription = source.subscribe({ - next: function (value) { subject.next(value); }, - error: function (err) { - hasError = true; - subject.error(err); - }, - complete: function () { - isComplete = true; - subject.complete(); - }, - }); - } - var innerSub = subject.subscribe(this); - this.add(function () { - refCount--; - innerSub.unsubscribe(); - if (subscription && !isComplete && useRefCount && refCount === 0) { - subscription.unsubscribe(); - subscription = undefined; - subject = undefined; - } - }); - }; + +function spawnSync(command, args, options) { + // Parse the arguments + const parsed = parse(command, args, options); + + // Spawn the child process + const result = cp.spawnSync(parsed.command, parsed.args, parsed.options); + + // Analyze if the command does not exist, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + result.error = result.error || enoent.verifyENOENTSync(result.status, parsed); + + return result; } -//# sourceMappingURL=shareReplay.js.map + +module.exports = spawn; +module.exports.spawn = spawn; +module.exports.sync = spawnSync; + +module.exports._parse = parse; +module.exports._enoent = enoent; /***/ }), -/* 339 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 345 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "single", function() { return single; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(223); -/** PURE_IMPORTS_START tslib,_Subscriber,_util_EmptyError PURE_IMPORTS_END */ +const path = __webpack_require__(4); +const resolveCommand = __webpack_require__(346); +const escape = __webpack_require__(353); +const readShebang = __webpack_require__(354); -function single(predicate) { - return function (source) { return source.lift(new SingleOperator(predicate, source)); }; +const isWin = process.platform === 'win32'; +const isExecutableRegExp = /\.(?:com|exe)$/i; +const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i; + +function detectShebang(parsed) { + parsed.file = resolveCommand(parsed); + + const shebang = parsed.file && readShebang(parsed.file); + + if (shebang) { + parsed.args.unshift(parsed.file); + parsed.command = shebang; + + return resolveCommand(parsed); + } + + return parsed.file; } -var SingleOperator = /*@__PURE__*/ (function () { - function SingleOperator(predicate, source) { - this.predicate = predicate; - this.source = source; + +function parseNonShell(parsed) { + if (!isWin) { + return parsed; } - SingleOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SingleSubscriber(subscriber, this.predicate, this.source)); - }; - return SingleOperator; -}()); -var SingleSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SingleSubscriber, _super); - function SingleSubscriber(destination, predicate, source) { - var _this = _super.call(this, destination) || this; - _this.predicate = predicate; - _this.source = source; - _this.seenValue = false; - _this.index = 0; - return _this; - } - SingleSubscriber.prototype.applySingleValue = function (value) { - if (this.seenValue) { - this.destination.error('Sequence contains more than one element'); - } - else { - this.seenValue = true; - this.singleValue = value; - } - }; - SingleSubscriber.prototype._next = function (value) { - var index = this.index++; - if (this.predicate) { - this.tryNext(value, index); - } - else { - this.applySingleValue(value); - } - }; - SingleSubscriber.prototype.tryNext = function (value, index) { - try { - if (this.predicate(value, index, this.source)) { - this.applySingleValue(value); - } - } - catch (err) { - this.destination.error(err); - } - }; - SingleSubscriber.prototype._complete = function () { - var destination = this.destination; - if (this.index > 0) { - destination.next(this.seenValue ? this.singleValue : undefined); - destination.complete(); - } - else { - destination.error(new _util_EmptyError__WEBPACK_IMPORTED_MODULE_2__["EmptyError"]); - } - }; - return SingleSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=single.js.map + // Detect & add support for shebangs + const commandFile = detectShebang(parsed); -/***/ }), -/* 340 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + // We don't need a shell if the command filename is an executable + const needsShell = !isExecutableRegExp.test(commandFile); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skip", function() { return skip; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + // If a shell is required, use cmd.exe and take care of escaping everything correctly + // Note that `forceShell` is an hidden option used only in tests + if (parsed.options.forceShell || needsShell) { + // Need to double escape meta chars if the command is a cmd-shim located in `node_modules/.bin/` + // The cmd-shim simply calls execute the package bin file with NodeJS, proxying any argument + // Because the escape of metachars with ^ gets interpreted when the cmd.exe is first called, + // we need to double escape them + const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile); + // Normalize posix paths into OS compatible paths (e.g.: foo/bar -> foo\bar) + // This is necessary otherwise it will always fail with ENOENT in those cases + parsed.command = path.normalize(parsed.command); -function skip(count) { - return function (source) { return source.lift(new SkipOperator(count)); }; -} -var SkipOperator = /*@__PURE__*/ (function () { - function SkipOperator(total) { - this.total = total; + // Escape command & arguments + parsed.command = escape.command(parsed.command); + parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars)); + + const shellCommand = [parsed.command].concat(parsed.args).join(' '); + + parsed.args = ['/d', '/s', '/c', `"${shellCommand}"`]; + parsed.command = process.env.comspec || 'cmd.exe'; + parsed.options.windowsVerbatimArguments = true; // Tell node's spawn that the arguments are already escaped } - SkipOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SkipSubscriber(subscriber, this.total)); - }; - return SkipOperator; -}()); -var SkipSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipSubscriber, _super); - function SkipSubscriber(destination, total) { - var _this = _super.call(this, destination) || this; - _this.total = total; - _this.count = 0; - return _this; + + return parsed; +} + +function parse(command, args, options) { + // Normalize arguments, similar to nodejs + if (args && !Array.isArray(args)) { + options = args; + args = null; } - SkipSubscriber.prototype._next = function (x) { - if (++this.count > this.total) { - this.destination.next(x); - } + + args = args ? args.slice(0) : []; // Clone array to avoid changing the original + options = Object.assign({}, options); // Clone object to avoid changing the original + + // Build our parsed object + const parsed = { + command, + args, + options, + file: undefined, + original: { + command, + args, + }, }; - return SkipSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=skip.js.map + + // Delegate further parsing to shell or non-shell + return options.shell ? parsed : parseNonShell(parsed); +} + +module.exports = parse; /***/ }), -/* 341 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 346 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skipLast", function() { return skipLast; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(222); -/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError PURE_IMPORTS_END */ +const path = __webpack_require__(4); +const which = __webpack_require__(347); +const pathKey = __webpack_require__(352)(); -function skipLast(count) { - return function (source) { return source.lift(new SkipLastOperator(count)); }; -} -var SkipLastOperator = /*@__PURE__*/ (function () { - function SkipLastOperator(_skipCount) { - this._skipCount = _skipCount; - if (this._skipCount < 0) { - throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__["ArgumentOutOfRangeError"]; +function resolveCommandAttempt(parsed, withoutPathExt) { + const cwd = process.cwd(); + const hasCustomCwd = parsed.options.cwd != null; + // Worker threads do not have process.chdir() + const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined; + + // If a custom `cwd` was specified, we need to change the process cwd + // because `which` will do stat calls but does not support a custom cwd + if (shouldSwitchCwd) { + try { + process.chdir(parsed.options.cwd); + } catch (err) { + /* Empty */ } } - SkipLastOperator.prototype.call = function (subscriber, source) { - if (this._skipCount === 0) { - return source.subscribe(new _Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"](subscriber)); - } - else { - return source.subscribe(new SkipLastSubscriber(subscriber, this._skipCount)); + + let resolved; + + try { + resolved = which.sync(parsed.command, { + path: (parsed.options.env || process.env)[pathKey], + pathExt: withoutPathExt ? path.delimiter : undefined, + }); + } catch (e) { + /* Empty */ + } finally { + if (shouldSwitchCwd) { + process.chdir(cwd); } - }; - return SkipLastOperator; -}()); -var SkipLastSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipLastSubscriber, _super); - function SkipLastSubscriber(destination, _skipCount) { - var _this = _super.call(this, destination) || this; - _this._skipCount = _skipCount; - _this._count = 0; - _this._ring = new Array(_skipCount); - return _this; } - SkipLastSubscriber.prototype._next = function (value) { - var skipCount = this._skipCount; - var count = this._count++; - if (count < skipCount) { - this._ring[count] = value; - } - else { - var currentIndex = count % skipCount; - var ring = this._ring; - var oldValue = ring[currentIndex]; - ring[currentIndex] = value; - this.destination.next(oldValue); - } - }; - return SkipLastSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=skipLast.js.map + // If we successfully resolved, ensure that an absolute path is returned + // Note that when a custom `cwd` was used, we need to resolve to an absolute path based on it + if (resolved) { + resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : '', resolved); + } -/***/ }), -/* 342 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + return resolved; +} -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skipUntil", function() { return skipUntil; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(229); -/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(231); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ +function resolveCommand(parsed) { + return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true); +} +module.exports = resolveCommand; +/***/ }), +/* 347 */ +/***/ (function(module, exports, __webpack_require__) { -function skipUntil(notifier) { - return function (source) { return source.lift(new SkipUntilOperator(notifier)); }; -} -var SkipUntilOperator = /*@__PURE__*/ (function () { - function SkipUntilOperator(notifier) { - this.notifier = notifier; - } - SkipUntilOperator.prototype.call = function (destination, source) { - return source.subscribe(new SkipUntilSubscriber(destination, this.notifier)); - }; - return SkipUntilOperator; -}()); -var SkipUntilSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipUntilSubscriber, _super); - function SkipUntilSubscriber(destination, notifier) { - var _this = _super.call(this, destination) || this; - _this.hasValue = false; - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](_this, undefined, undefined); - _this.add(innerSubscriber); - _this.innerSubscription = innerSubscriber; - Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(_this, notifier, undefined, undefined, innerSubscriber); - return _this; - } - SkipUntilSubscriber.prototype._next = function (value) { - if (this.hasValue) { - _super.prototype._next.call(this, value); - } - }; - SkipUntilSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.hasValue = true; - if (this.innerSubscription) { - this.innerSubscription.unsubscribe(); - } - }; - SkipUntilSubscriber.prototype.notifyComplete = function () { - }; - return SkipUntilSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=skipUntil.js.map +const isWindows = process.platform === 'win32' || + process.env.OSTYPE === 'cygwin' || + process.env.OSTYPE === 'msys' +const path = __webpack_require__(4) +const COLON = isWindows ? ';' : ':' +const isexe = __webpack_require__(348) -/***/ }), -/* 343 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +const getNotFoundError = (cmd) => + Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }) -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skipWhile", function() { return skipWhile; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +const getPathInfo = (cmd, opt) => { + const colon = opt.colon || COLON + + // If it has a slash, then we don't bother searching the pathenv. + // just check the file itself, and that's it. + const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [''] + : ( + [ + // windows always checks the cwd first + ...(isWindows ? [process.cwd()] : []), + ...(opt.path || process.env.PATH || + /* istanbul ignore next: very unusual */ '').split(colon), + ] + ) + const pathExtExe = isWindows + ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM' + : '' + const pathExt = isWindows ? pathExtExe.split(colon) : [''] + if (isWindows) { + if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') + pathExt.unshift('') + } -function skipWhile(predicate) { - return function (source) { return source.lift(new SkipWhileOperator(predicate)); }; + return { + pathEnv, + pathExt, + pathExtExe, + } } -var SkipWhileOperator = /*@__PURE__*/ (function () { - function SkipWhileOperator(predicate) { - this.predicate = predicate; - } - SkipWhileOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SkipWhileSubscriber(subscriber, this.predicate)); - }; - return SkipWhileOperator; -}()); -var SkipWhileSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipWhileSubscriber, _super); - function SkipWhileSubscriber(destination, predicate) { - var _this = _super.call(this, destination) || this; - _this.predicate = predicate; - _this.skipping = true; - _this.index = 0; - return _this; - } - SkipWhileSubscriber.prototype._next = function (value) { - var destination = this.destination; - if (this.skipping) { - this.tryCallPredicate(value); - } - if (!this.skipping) { - destination.next(value); - } - }; - SkipWhileSubscriber.prototype.tryCallPredicate = function (value) { - try { - var result = this.predicate(value, this.index++); - this.skipping = Boolean(result); - } - catch (err) { - this.destination.error(err); - } - }; - return SkipWhileSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=skipWhile.js.map +const which = (cmd, opt, cb) => { + if (typeof opt === 'function') { + cb = opt + opt = {} + } + if (!opt) + opt = {} -/***/ }), -/* 344 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) + const found = [] -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "startWith", function() { return startWith; }); -/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(239); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(205); -/** PURE_IMPORTS_START _observable_concat,_util_isScheduler PURE_IMPORTS_END */ + const step = i => new Promise((resolve, reject) => { + if (i === pathEnv.length) + return opt.all && found.length ? resolve(found) + : reject(getNotFoundError(cmd)) + const ppRaw = pathEnv[i] + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw -function startWith() { - var array = []; - for (var _i = 0; _i < arguments.length; _i++) { - array[_i] = arguments[_i]; - } - var scheduler = array[array.length - 1]; - if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_1__["isScheduler"])(scheduler)) { - array.pop(); - return function (source) { return Object(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"])(array, source, scheduler); }; - } - else { - return function (source) { return Object(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"])(array, source); }; - } + const pCmd = path.join(pathPart, cmd) + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd + + resolve(subStep(p, i, 0)) + }) + + const subStep = (p, i, ii) => new Promise((resolve, reject) => { + if (ii === pathExt.length) + return resolve(step(i + 1)) + const ext = pathExt[ii] + isexe(p + ext, { pathExt: pathExtExe }, (er, is) => { + if (!er && is) { + if (opt.all) + found.push(p + ext) + else + return resolve(p + ext) + } + return resolve(subStep(p, i, ii + 1)) + }) + }) + + return cb ? step(0).then(res => cb(null, res), cb) : step(0) } -//# sourceMappingURL=startWith.js.map +const whichSync = (cmd, opt) => { + opt = opt || {} -/***/ }), -/* 345 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) + const found = [] -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return subscribeOn; }); -/* harmony import */ var _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(346); -/** PURE_IMPORTS_START _observable_SubscribeOnObservable PURE_IMPORTS_END */ + for (let i = 0; i < pathEnv.length; i ++) { + const ppRaw = pathEnv[i] + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw -function subscribeOn(scheduler, delay) { - if (delay === void 0) { - delay = 0; + const pCmd = path.join(pathPart, cmd) + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd + + for (let j = 0; j < pathExt.length; j ++) { + const cur = p + pathExt[j] + try { + const is = isexe.sync(cur, { pathExt: pathExtExe }) + if (is) { + if (opt.all) + found.push(cur) + else + return cur + } + } catch (ex) {} } - return function subscribeOnOperatorFunction(source) { - return source.lift(new SubscribeOnOperator(scheduler, delay)); - }; + } + + if (opt.all && found.length) + return found + + if (opt.nothrow) + return null + + throw getNotFoundError(cmd) } -var SubscribeOnOperator = /*@__PURE__*/ (function () { - function SubscribeOnOperator(scheduler, delay) { - this.scheduler = scheduler; - this.delay = delay; - } - SubscribeOnOperator.prototype.call = function (subscriber, source) { - return new _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__["SubscribeOnObservable"](source, this.delay, this.scheduler).subscribe(subscriber); - }; - return SubscribeOnOperator; -}()); -//# sourceMappingURL=subscribeOn.js.map + +module.exports = which +which.sync = whichSync /***/ }), -/* 346 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 348 */ +/***/ (function(module, exports, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubscribeOnObservable", function() { return SubscribeOnObservable; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(170); -/* harmony import */ var _scheduler_asap__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(211); -/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(257); -/** PURE_IMPORTS_START tslib,_Observable,_scheduler_asap,_util_isNumeric PURE_IMPORTS_END */ +var fs = __webpack_require__(349) +var core +if (process.platform === 'win32' || global.TESTING_WINDOWS) { + core = __webpack_require__(350) +} else { + core = __webpack_require__(351) +} +module.exports = isexe +isexe.sync = sync +function isexe (path, options, cb) { + if (typeof options === 'function') { + cb = options + options = {} + } + if (!cb) { + if (typeof Promise !== 'function') { + throw new TypeError('callback not provided') + } -var SubscribeOnObservable = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubscribeOnObservable, _super); - function SubscribeOnObservable(source, delayTime, scheduler) { - if (delayTime === void 0) { - delayTime = 0; - } - if (scheduler === void 0) { - scheduler = _scheduler_asap__WEBPACK_IMPORTED_MODULE_2__["asap"]; - } - var _this = _super.call(this) || this; - _this.source = source; - _this.delayTime = delayTime; - _this.scheduler = scheduler; - if (!Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_3__["isNumeric"])(delayTime) || delayTime < 0) { - _this.delayTime = 0; - } - if (!scheduler || typeof scheduler.schedule !== 'function') { - _this.scheduler = _scheduler_asap__WEBPACK_IMPORTED_MODULE_2__["asap"]; + return new Promise(function (resolve, reject) { + isexe(path, options || {}, function (er, is) { + if (er) { + reject(er) + } else { + resolve(is) } - return _this; - } - SubscribeOnObservable.create = function (source, delay, scheduler) { - if (delay === void 0) { - delay = 0; - } - if (scheduler === void 0) { - scheduler = _scheduler_asap__WEBPACK_IMPORTED_MODULE_2__["asap"]; - } - return new SubscribeOnObservable(source, delay, scheduler); - }; - SubscribeOnObservable.dispatch = function (arg) { - var source = arg.source, subscriber = arg.subscriber; - return this.add(source.subscribe(subscriber)); - }; - SubscribeOnObservable.prototype._subscribe = function (subscriber) { - var delay = this.delayTime; - var source = this.source; - var scheduler = this.scheduler; - return scheduler.schedule(SubscribeOnObservable.dispatch, delay, { - source: source, subscriber: subscriber - }); - }; - return SubscribeOnObservable; -}(_Observable__WEBPACK_IMPORTED_MODULE_1__["Observable"])); + }) + }) + } -//# sourceMappingURL=SubscribeOnObservable.js.map + core(path, options || {}, function (er, is) { + // ignore EACCES because that just means we aren't allowed to run it + if (er) { + if (er.code === 'EACCES' || options && options.ignoreErrors) { + er = null + is = false + } + } + cb(er, is) + }) +} + +function sync (path, options) { + // my kingdom for a filtered catch + try { + return core.sync(path, options || {}) + } catch (er) { + if (options && options.ignoreErrors || er.code === 'EACCES') { + return false + } else { + throw er + } + } +} /***/ }), -/* 347 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 349 */ +/***/ (function(module, exports) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return switchAll; }); -/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(348); -/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(220); -/** PURE_IMPORTS_START _switchMap,_util_identity PURE_IMPORTS_END */ +module.exports = require("fs"); +/***/ }), +/* 350 */ +/***/ (function(module, exports, __webpack_require__) { -function switchAll() { - return Object(_switchMap__WEBPACK_IMPORTED_MODULE_0__["switchMap"])(_util_identity__WEBPACK_IMPORTED_MODULE_1__["identity"]); +module.exports = isexe +isexe.sync = sync + +var fs = __webpack_require__(349) + +function checkPathExt (path, options) { + var pathext = options.pathExt !== undefined ? + options.pathExt : process.env.PATHEXT + + if (!pathext) { + return true + } + + pathext = pathext.split(';') + if (pathext.indexOf('') !== -1) { + return true + } + for (var i = 0; i < pathext.length; i++) { + var p = pathext[i].toLowerCase() + if (p && path.substr(-p.length).toLowerCase() === p) { + return true + } + } + return false +} + +function checkStat (stat, path, options) { + if (!stat.isSymbolicLink() && !stat.isFile()) { + return false + } + return checkPathExt(path, options) +} + +function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, path, options)) + }) +} + +function sync (path, options) { + return checkStat(fs.statSync(path), path, options) } -//# sourceMappingURL=switchAll.js.map /***/ }), -/* 348 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 351 */ +/***/ (function(module, exports, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchMap", function() { return switchMap; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(229); -/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(231); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(230); -/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(226); -/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(243); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult,_map,_observable_from PURE_IMPORTS_END */ +module.exports = isexe +isexe.sync = sync + +var fs = __webpack_require__(349) + +function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, options)) + }) +} + +function sync (path, options) { + return checkStat(fs.statSync(path), options) +} +function checkStat (stat, options) { + return stat.isFile() && checkMode(stat, options) +} +function checkMode (stat, options) { + var mod = stat.mode + var uid = stat.uid + var gid = stat.gid + var myUid = options.uid !== undefined ? + options.uid : process.getuid && process.getuid() + var myGid = options.gid !== undefined ? + options.gid : process.getgid && process.getgid() + var u = parseInt('100', 8) + var g = parseInt('010', 8) + var o = parseInt('001', 8) + var ug = u | g + var ret = (mod & o) || + (mod & g) && gid === myGid || + (mod & u) && uid === myUid || + (mod & ug) && myUid === 0 -function switchMap(project, resultSelector) { - if (typeof resultSelector === 'function') { - return function (source) { return source.pipe(switchMap(function (a, i) { return Object(_observable_from__WEBPACK_IMPORTED_MODULE_5__["from"])(project(a, i)).pipe(Object(_map__WEBPACK_IMPORTED_MODULE_4__["map"])(function (b, ii) { return resultSelector(a, b, i, ii); })); })); }; - } - return function (source) { return source.lift(new SwitchMapOperator(project)); }; + return ret } -var SwitchMapOperator = /*@__PURE__*/ (function () { - function SwitchMapOperator(project) { - this.project = project; - } - SwitchMapOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SwitchMapSubscriber(subscriber, this.project)); - }; - return SwitchMapOperator; -}()); -var SwitchMapSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SwitchMapSubscriber, _super); - function SwitchMapSubscriber(destination, project) { - var _this = _super.call(this, destination) || this; - _this.project = project; - _this.index = 0; - return _this; - } - SwitchMapSubscriber.prototype._next = function (value) { - var result; - var index = this.index++; - try { - result = this.project(value, index); - } - catch (error) { - this.destination.error(error); - return; - } - this._innerSub(result, value, index); - }; - SwitchMapSubscriber.prototype._innerSub = function (result, value, index) { - var innerSubscription = this.innerSubscription; - if (innerSubscription) { - innerSubscription.unsubscribe(); - } - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](this, undefined, undefined); - var destination = this.destination; - destination.add(innerSubscriber); - this.innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, result, value, index, innerSubscriber); - }; - SwitchMapSubscriber.prototype._complete = function () { - var innerSubscription = this.innerSubscription; - if (!innerSubscription || innerSubscription.closed) { - _super.prototype._complete.call(this); - } - this.unsubscribe(); - }; - SwitchMapSubscriber.prototype._unsubscribe = function () { - this.innerSubscription = null; - }; - SwitchMapSubscriber.prototype.notifyComplete = function (innerSub) { - var destination = this.destination; - destination.remove(innerSub); - this.innerSubscription = null; - if (this.isStopped) { - _super.prototype._complete.call(this); - } - }; - SwitchMapSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.destination.next(innerValue); - }; - return SwitchMapSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=switchMap.js.map /***/ }), -/* 349 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 352 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return switchMapTo; }); -/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(348); -/** PURE_IMPORTS_START _switchMap PURE_IMPORTS_END */ -function switchMapTo(innerObservable, resultSelector) { - return resultSelector ? Object(_switchMap__WEBPACK_IMPORTED_MODULE_0__["switchMap"])(function () { return innerObservable; }, resultSelector) : Object(_switchMap__WEBPACK_IMPORTED_MODULE_0__["switchMap"])(function () { return innerObservable; }); -} -//# sourceMappingURL=switchMapTo.js.map + +const pathKey = (options = {}) => { + const environment = options.env || process.env; + const platform = options.platform || process.platform; + + if (platform !== 'win32') { + return 'PATH'; + } + + return Object.keys(environment).find(key => key.toUpperCase() === 'PATH') || 'Path'; +}; + +module.exports = pathKey; +// TODO: Remove this for the next major release +module.exports.default = pathKey; /***/ }), -/* 350 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 353 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "takeUntil", function() { return takeUntil; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ +// See http://www.robvanderwoude.com/escapechars.php +const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g; -function takeUntil(notifier) { - return function (source) { return source.lift(new TakeUntilOperator(notifier)); }; +function escapeCommand(arg) { + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); + + return arg; } -var TakeUntilOperator = /*@__PURE__*/ (function () { - function TakeUntilOperator(notifier) { - this.notifier = notifier; - } - TakeUntilOperator.prototype.call = function (subscriber, source) { - var takeUntilSubscriber = new TakeUntilSubscriber(subscriber); - var notifierSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(takeUntilSubscriber, this.notifier); - if (notifierSubscription && !takeUntilSubscriber.seenValue) { - takeUntilSubscriber.add(notifierSubscription); - return source.subscribe(takeUntilSubscriber); - } - return takeUntilSubscriber; - }; - return TakeUntilOperator; -}()); -var TakeUntilSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeUntilSubscriber, _super); - function TakeUntilSubscriber(destination) { - var _this = _super.call(this, destination) || this; - _this.seenValue = false; - return _this; - } - TakeUntilSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.seenValue = true; - this.complete(); - }; - TakeUntilSubscriber.prototype.notifyComplete = function () { - }; - return TakeUntilSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=takeUntil.js.map +function escapeArgument(arg, doubleEscapeMetaChars) { + // Convert to string + arg = `${arg}`; -/***/ }), -/* 351 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + // Algorithm below is based on https://qntm.org/cmd -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "takeWhile", function() { return takeWhile; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + // Sequence of backslashes followed by a double quote: + // double up all the backslashes and escape the double quote + arg = arg.replace(/(\\*)"/g, '$1$1\\"'); + + // Sequence of backslashes followed by the end of the string + // (which will become a double quote later): + // double up all the backslashes + arg = arg.replace(/(\\*)$/, '$1$1'); + // All other backslashes occur literally -function takeWhile(predicate, inclusive) { - if (inclusive === void 0) { - inclusive = false; + // Quote the whole thing: + arg = `"${arg}"`; + + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); + + // Double escape meta chars if necessary + if (doubleEscapeMetaChars) { + arg = arg.replace(metaCharsRegExp, '^$1'); } - return function (source) { - return source.lift(new TakeWhileOperator(predicate, inclusive)); - }; + + return arg; } -var TakeWhileOperator = /*@__PURE__*/ (function () { - function TakeWhileOperator(predicate, inclusive) { - this.predicate = predicate; - this.inclusive = inclusive; - } - TakeWhileOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new TakeWhileSubscriber(subscriber, this.predicate, this.inclusive)); - }; - return TakeWhileOperator; -}()); -var TakeWhileSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeWhileSubscriber, _super); - function TakeWhileSubscriber(destination, predicate, inclusive) { - var _this = _super.call(this, destination) || this; - _this.predicate = predicate; - _this.inclusive = inclusive; - _this.index = 0; - return _this; - } - TakeWhileSubscriber.prototype._next = function (value) { - var destination = this.destination; - var result; - try { - result = this.predicate(value, this.index++); - } - catch (err) { - destination.error(err); - return; - } - this.nextOrComplete(value, result); - }; - TakeWhileSubscriber.prototype.nextOrComplete = function (value, predicateResult) { - var destination = this.destination; - if (Boolean(predicateResult)) { - destination.next(value); - } - else { - if (this.inclusive) { - destination.next(value); - } - destination.complete(); - } - }; - return TakeWhileSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=takeWhile.js.map + +module.exports.command = escapeCommand; +module.exports.argument = escapeArgument; /***/ }), -/* 352 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 354 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tap", function() { return tap; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(185); -/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(173); -/** PURE_IMPORTS_START tslib,_Subscriber,_util_noop,_util_isFunction PURE_IMPORTS_END */ +const fs = __webpack_require__(349); +const shebangCommand = __webpack_require__(355); + +function readShebang(command) { + // Read the first 150 bytes from the file + const size = 150; + const buffer = Buffer.alloc(size); + + let fd; + try { + fd = fs.openSync(command, 'r'); + fs.readSync(fd, buffer, 0, size, 0); + fs.closeSync(fd); + } catch (e) { /* Empty */ } -function tap(nextOrObserver, error, complete) { - return function tapOperatorFunction(source) { - return source.lift(new DoOperator(nextOrObserver, error, complete)); - }; + // Attempt to extract shebang (null is returned if not a shebang) + return shebangCommand(buffer.toString()); } -var DoOperator = /*@__PURE__*/ (function () { - function DoOperator(nextOrObserver, error, complete) { - this.nextOrObserver = nextOrObserver; - this.error = error; - this.complete = complete; - } - DoOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new TapSubscriber(subscriber, this.nextOrObserver, this.error, this.complete)); - }; - return DoOperator; -}()); -var TapSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TapSubscriber, _super); - function TapSubscriber(destination, observerOrNext, error, complete) { - var _this = _super.call(this, destination) || this; - _this._tapNext = _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - _this._tapError = _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - _this._tapComplete = _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - _this._tapError = error || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - _this._tapComplete = complete || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - if (Object(_util_isFunction__WEBPACK_IMPORTED_MODULE_3__["isFunction"])(observerOrNext)) { - _this._context = _this; - _this._tapNext = observerOrNext; - } - else if (observerOrNext) { - _this._context = observerOrNext; - _this._tapNext = observerOrNext.next || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - _this._tapError = observerOrNext.error || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - _this._tapComplete = observerOrNext.complete || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - } - return _this; - } - TapSubscriber.prototype._next = function (value) { - try { - this._tapNext.call(this._context, value); - } - catch (err) { - this.destination.error(err); - return; - } - this.destination.next(value); - }; - TapSubscriber.prototype._error = function (err) { - try { - this._tapError.call(this._context, err); - } - catch (err) { - this.destination.error(err); - return; - } - this.destination.error(err); - }; - TapSubscriber.prototype._complete = function () { - try { - this._tapComplete.call(this._context); - } - catch (err) { - this.destination.error(err); - return; - } - return this.destination.complete(); - }; - return TapSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=tap.js.map + +module.exports = readShebang; /***/ }), -/* 353 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 355 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultThrottleConfig", function() { return defaultThrottleConfig; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "throttle", function() { return throttle; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ +const shebangRegex = __webpack_require__(356); +module.exports = (string = '') => { + const match = string.match(shebangRegex); -var defaultThrottleConfig = { - leading: true, - trailing: false + if (!match) { + return null; + } + + const [path, argument] = match[0].replace(/#! ?/, '').split(' '); + const binary = path.split('/').pop(); + + if (binary === 'env') { + return argument; + } + + return argument ? `${binary} ${argument}` : binary; }; -function throttle(durationSelector, config) { - if (config === void 0) { - config = defaultThrottleConfig; - } - return function (source) { return source.lift(new ThrottleOperator(durationSelector, config.leading, config.trailing)); }; -} -var ThrottleOperator = /*@__PURE__*/ (function () { - function ThrottleOperator(durationSelector, leading, trailing) { - this.durationSelector = durationSelector; - this.leading = leading; - this.trailing = trailing; - } - ThrottleOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ThrottleSubscriber(subscriber, this.durationSelector, this.leading, this.trailing)); - }; - return ThrottleOperator; -}()); -var ThrottleSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ThrottleSubscriber, _super); - function ThrottleSubscriber(destination, durationSelector, _leading, _trailing) { - var _this = _super.call(this, destination) || this; - _this.destination = destination; - _this.durationSelector = durationSelector; - _this._leading = _leading; - _this._trailing = _trailing; - _this._hasValue = false; - return _this; - } - ThrottleSubscriber.prototype._next = function (value) { - this._hasValue = true; - this._sendValue = value; - if (!this._throttled) { - if (this._leading) { - this.send(); - } - else { - this.throttle(value); - } - } - }; - ThrottleSubscriber.prototype.send = function () { - var _a = this, _hasValue = _a._hasValue, _sendValue = _a._sendValue; - if (_hasValue) { - this.destination.next(_sendValue); - this.throttle(_sendValue); - } - this._hasValue = false; - this._sendValue = null; - }; - ThrottleSubscriber.prototype.throttle = function (value) { - var duration = this.tryDurationSelector(value); - if (!!duration) { - this.add(this._throttled = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, duration)); - } - }; - ThrottleSubscriber.prototype.tryDurationSelector = function (value) { - try { - return this.durationSelector(value); - } - catch (err) { - this.destination.error(err); - return null; - } - }; - ThrottleSubscriber.prototype.throttlingDone = function () { - var _a = this, _throttled = _a._throttled, _trailing = _a._trailing; - if (_throttled) { - _throttled.unsubscribe(); - } - this._throttled = null; - if (_trailing) { - this.send(); - } - }; - ThrottleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.throttlingDone(); - }; - ThrottleSubscriber.prototype.notifyComplete = function () { - this.throttlingDone(); - }; - return ThrottleSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=throttle.js.map /***/ }), -/* 354 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 356 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "throttleTime", function() { return throttleTime; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(215); -/* harmony import */ var _throttle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(353); -/** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async,_throttle PURE_IMPORTS_END */ +module.exports = /^#!(.*)/; +/***/ }), +/* 357 */ +/***/ (function(module, exports, __webpack_require__) { -function throttleTime(duration, scheduler, config) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; - } - if (config === void 0) { - config = _throttle__WEBPACK_IMPORTED_MODULE_3__["defaultThrottleConfig"]; - } - return function (source) { return source.lift(new ThrottleTimeOperator(duration, scheduler, config.leading, config.trailing)); }; +"use strict"; + + +const isWin = process.platform === 'win32'; + +function notFoundError(original, syscall) { + return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), { + code: 'ENOENT', + errno: 'ENOENT', + syscall: `${syscall} ${original.command}`, + path: original.command, + spawnargs: original.args, + }); } -var ThrottleTimeOperator = /*@__PURE__*/ (function () { - function ThrottleTimeOperator(duration, scheduler, leading, trailing) { - this.duration = duration; - this.scheduler = scheduler; - this.leading = leading; - this.trailing = trailing; - } - ThrottleTimeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ThrottleTimeSubscriber(subscriber, this.duration, this.scheduler, this.leading, this.trailing)); - }; - return ThrottleTimeOperator; -}()); -var ThrottleTimeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ThrottleTimeSubscriber, _super); - function ThrottleTimeSubscriber(destination, duration, scheduler, leading, trailing) { - var _this = _super.call(this, destination) || this; - _this.duration = duration; - _this.scheduler = scheduler; - _this.leading = leading; - _this.trailing = trailing; - _this._hasTrailingValue = false; - _this._trailingValue = null; - return _this; + +function hookChildProcess(cp, parsed) { + if (!isWin) { + return; } - ThrottleTimeSubscriber.prototype._next = function (value) { - if (this.throttled) { - if (this.trailing) { - this._trailingValue = value; - this._hasTrailingValue = true; - } - } - else { - this.add(this.throttled = this.scheduler.schedule(dispatchNext, this.duration, { subscriber: this })); - if (this.leading) { - this.destination.next(value); - } - else if (this.trailing) { - this._trailingValue = value; - this._hasTrailingValue = true; - } - } - }; - ThrottleTimeSubscriber.prototype._complete = function () { - if (this._hasTrailingValue) { - this.destination.next(this._trailingValue); - this.destination.complete(); - } - else { - this.destination.complete(); - } - }; - ThrottleTimeSubscriber.prototype.clearThrottle = function () { - var throttled = this.throttled; - if (throttled) { - if (this.trailing && this._hasTrailingValue) { - this.destination.next(this._trailingValue); - this._trailingValue = null; - this._hasTrailingValue = false; + + const originalEmit = cp.emit; + + cp.emit = function (name, arg1) { + // If emitting "exit" event and exit code is 1, we need to check if + // the command exists and emit an "error" instead + // See https://github.com/IndigoUnited/node-cross-spawn/issues/16 + if (name === 'exit') { + const err = verifyENOENT(arg1, parsed, 'spawn'); + + if (err) { + return originalEmit.call(cp, 'error', err); } - throttled.unsubscribe(); - this.remove(throttled); - this.throttled = null; } + + return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params }; - return ThrottleTimeSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -function dispatchNext(arg) { - var subscriber = arg.subscriber; - subscriber.clearThrottle(); } -//# sourceMappingURL=throttleTime.js.map + +function verifyENOENT(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawn'); + } + + return null; +} + +function verifyENOENTSync(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawnSync'); + } + + return null; +} + +module.exports = { + hookChildProcess, + verifyENOENT, + verifyENOENTSync, + notFoundError, +}; /***/ }), -/* 355 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 358 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeInterval", function() { return timeInterval; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TimeInterval", function() { return TimeInterval; }); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(215); -/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(315); -/* harmony import */ var _observable_defer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(250); -/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(226); -/** PURE_IMPORTS_START _scheduler_async,_scan,_observable_defer,_map PURE_IMPORTS_END */ +module.exports = input => { + const LF = typeof input === 'string' ? '\n' : '\n'.charCodeAt(); + const CR = typeof input === 'string' ? '\r' : '\r'.charCodeAt(); + if (input[input.length - 1] === LF) { + input = input.slice(0, input.length - 1); + } -function timeInterval(scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; - } - return function (source) { - return Object(_observable_defer__WEBPACK_IMPORTED_MODULE_2__["defer"])(function () { - return source.pipe(Object(_scan__WEBPACK_IMPORTED_MODULE_1__["scan"])(function (_a, value) { - var current = _a.current; - return ({ value: value, current: scheduler.now(), last: current }); - }, { current: scheduler.now(), value: undefined, last: undefined }), Object(_map__WEBPACK_IMPORTED_MODULE_3__["map"])(function (_a) { - var current = _a.current, last = _a.last, value = _a.value; - return new TimeInterval(value, current - last); - })); - }); - }; -} -var TimeInterval = /*@__PURE__*/ (function () { - function TimeInterval(value, interval) { - this.value = value; - this.interval = interval; - } - return TimeInterval; -}()); + if (input[input.length - 1] === CR) { + input = input.slice(0, input.length - 1); + } -//# sourceMappingURL=timeInterval.js.map + return input; +}; /***/ }), -/* 356 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 359 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return timeout; }); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(215); -/* harmony import */ var _util_TimeoutError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(224); -/* harmony import */ var _timeoutWith__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(357); -/* harmony import */ var _observable_throwError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(209); -/** PURE_IMPORTS_START _scheduler_async,_util_TimeoutError,_timeoutWith,_observable_throwError PURE_IMPORTS_END */ - +const path = __webpack_require__(4); +const pathKey = __webpack_require__(352); +const npmRunPath = options => { + options = { + cwd: process.cwd(), + path: process.env[pathKey()], + execPath: process.execPath, + ...options + }; -function timeout(due, scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; - } - return Object(_timeoutWith__WEBPACK_IMPORTED_MODULE_2__["timeoutWith"])(due, Object(_observable_throwError__WEBPACK_IMPORTED_MODULE_3__["throwError"])(new _util_TimeoutError__WEBPACK_IMPORTED_MODULE_1__["TimeoutError"]()), scheduler); -} -//# sourceMappingURL=timeout.js.map + let previous; + let cwdPath = path.resolve(options.cwd); + const result = []; + while (previous !== cwdPath) { + result.push(path.join(cwdPath, 'node_modules/.bin')); + previous = cwdPath; + cwdPath = path.resolve(cwdPath, '..'); + } -/***/ }), -/* 357 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + // Ensure the running `node` binary is used + const execPathDir = path.resolve(options.cwd, options.execPath, '..'); + result.push(execPathDir); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeoutWith", function() { return timeoutWith; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(215); -/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(289); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ + return result.concat(options.path).join(path.delimiter); +}; +module.exports = npmRunPath; +// TODO: Remove this for the next major release +module.exports.default = npmRunPath; +module.exports.env = options => { + options = { + env: process.env, + ...options + }; + const env = {...options.env}; + const path = pathKey({env}); + options.path = env[path]; + env[path] = module.exports(options); -function timeoutWith(due, withObservable, scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; - } - return function (source) { - var absoluteTimeout = Object(_util_isDate__WEBPACK_IMPORTED_MODULE_2__["isDate"])(due); - var waitFor = absoluteTimeout ? (+due - scheduler.now()) : Math.abs(due); - return source.lift(new TimeoutWithOperator(waitFor, absoluteTimeout, withObservable, scheduler)); - }; -} -var TimeoutWithOperator = /*@__PURE__*/ (function () { - function TimeoutWithOperator(waitFor, absoluteTimeout, withObservable, scheduler) { - this.waitFor = waitFor; - this.absoluteTimeout = absoluteTimeout; - this.withObservable = withObservable; - this.scheduler = scheduler; - } - TimeoutWithOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new TimeoutWithSubscriber(subscriber, this.absoluteTimeout, this.waitFor, this.withObservable, this.scheduler)); - }; - return TimeoutWithOperator; -}()); -var TimeoutWithSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TimeoutWithSubscriber, _super); - function TimeoutWithSubscriber(destination, absoluteTimeout, waitFor, withObservable, scheduler) { - var _this = _super.call(this, destination) || this; - _this.absoluteTimeout = absoluteTimeout; - _this.waitFor = waitFor; - _this.withObservable = withObservable; - _this.scheduler = scheduler; - _this.action = null; - _this.scheduleTimeout(); - return _this; - } - TimeoutWithSubscriber.dispatchTimeout = function (subscriber) { - var withObservable = subscriber.withObservable; - subscriber._unsubscribeAndRecycle(); - subscriber.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(subscriber, withObservable)); - }; - TimeoutWithSubscriber.prototype.scheduleTimeout = function () { - var action = this.action; - if (action) { - this.action = action.schedule(this, this.waitFor); - } - else { - this.add(this.action = this.scheduler.schedule(TimeoutWithSubscriber.dispatchTimeout, this.waitFor, this)); - } - }; - TimeoutWithSubscriber.prototype._next = function (value) { - if (!this.absoluteTimeout) { - this.scheduleTimeout(); - } - _super.prototype._next.call(this, value); - }; - TimeoutWithSubscriber.prototype._unsubscribe = function () { - this.action = null; - this.scheduler = null; - this.withObservable = null; - }; - return TimeoutWithSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); -//# sourceMappingURL=timeoutWith.js.map + return env; +}; /***/ }), -/* 358 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 360 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timestamp", function() { return timestamp; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Timestamp", function() { return Timestamp; }); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(215); -/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(226); -/** PURE_IMPORTS_START _scheduler_async,_map PURE_IMPORTS_END */ +const mimicFn = __webpack_require__(361); -function timestamp(scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; - } - return Object(_map__WEBPACK_IMPORTED_MODULE_1__["map"])(function (value) { return new Timestamp(value, scheduler.now()); }); -} -var Timestamp = /*@__PURE__*/ (function () { - function Timestamp(value, timestamp) { - this.value = value; - this.timestamp = timestamp; - } - return Timestamp; -}()); +const calledFunctions = new WeakMap(); -//# sourceMappingURL=timestamp.js.map +const oneTime = (fn, options = {}) => { + if (typeof fn !== 'function') { + throw new TypeError('Expected a function'); + } + let ret; + let isCalled = false; + let callCount = 0; + const functionName = fn.displayName || fn.name || ''; -/***/ }), -/* 359 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + const onetime = function (...args) { + calledFunctions.set(onetime, ++callCount); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return toArray; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(314); -/** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ + if (isCalled) { + if (options.throw === true) { + throw new Error(`Function \`${functionName}\` can only be called once`); + } -function toArrayReducer(arr, item, index) { - if (index === 0) { - return [item]; - } - arr.push(item); - return arr; -} -function toArray() { - return Object(_reduce__WEBPACK_IMPORTED_MODULE_0__["reduce"])(toArrayReducer, []); -} -//# sourceMappingURL=toArray.js.map + return ret; + } + isCalled = true; + ret = fn.apply(this, args); + fn = null; -/***/ }), -/* 360 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + return ret; + }; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "window", function() { return window; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(187); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_Subject,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ + mimicFn(onetime, fn); + calledFunctions.set(onetime, callCount); + return onetime; +}; +module.exports = oneTime; +// TODO: Remove this for the next major release +module.exports.default = oneTime; +module.exports.callCount = fn => { + if (!calledFunctions.has(fn)) { + throw new Error(`The given function \`${fn.name}\` is not wrapped by the \`onetime\` package`); + } -function window(windowBoundaries) { - return function windowOperatorFunction(source) { - return source.lift(new WindowOperator(windowBoundaries)); - }; -} -var WindowOperator = /*@__PURE__*/ (function () { - function WindowOperator(windowBoundaries) { - this.windowBoundaries = windowBoundaries; - } - WindowOperator.prototype.call = function (subscriber, source) { - var windowSubscriber = new WindowSubscriber(subscriber); - var sourceSubscription = source.subscribe(windowSubscriber); - if (!sourceSubscription.closed) { - windowSubscriber.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(windowSubscriber, this.windowBoundaries)); - } - return sourceSubscription; - }; - return WindowOperator; -}()); -var WindowSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowSubscriber, _super); - function WindowSubscriber(destination) { - var _this = _super.call(this, destination) || this; - _this.window = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); - destination.next(_this.window); - return _this; - } - WindowSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.openWindow(); - }; - WindowSubscriber.prototype.notifyError = function (error, innerSub) { - this._error(error); - }; - WindowSubscriber.prototype.notifyComplete = function (innerSub) { - this._complete(); - }; - WindowSubscriber.prototype._next = function (value) { - this.window.next(value); - }; - WindowSubscriber.prototype._error = function (err) { - this.window.error(err); - this.destination.error(err); - }; - WindowSubscriber.prototype._complete = function () { - this.window.complete(); - this.destination.complete(); - }; - WindowSubscriber.prototype._unsubscribe = function () { - this.window = null; - }; - WindowSubscriber.prototype.openWindow = function () { - var prevWindow = this.window; - if (prevWindow) { - prevWindow.complete(); - } - var destination = this.destination; - var newWindow = this.window = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); - destination.next(newWindow); - }; - return WindowSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); -//# sourceMappingURL=window.js.map + return calledFunctions.get(fn); +}; /***/ }), /* 361 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windowCount", function() { return windowCount; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(172); -/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(187); -/** PURE_IMPORTS_START tslib,_Subscriber,_Subject PURE_IMPORTS_END */ +const mimicFn = (to, from) => { + for (const prop of Reflect.ownKeys(from)) { + Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop)); + } + + return to; +}; + +module.exports = mimicFn; +// TODO: Remove this for the next major release +module.exports.default = mimicFn; -function windowCount(windowSize, startWindowEvery) { - if (startWindowEvery === void 0) { - startWindowEvery = 0; - } - return function windowCountOperatorFunction(source) { - return source.lift(new WindowCountOperator(windowSize, startWindowEvery)); - }; -} -var WindowCountOperator = /*@__PURE__*/ (function () { - function WindowCountOperator(windowSize, startWindowEvery) { - this.windowSize = windowSize; - this.startWindowEvery = startWindowEvery; - } - WindowCountOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new WindowCountSubscriber(subscriber, this.windowSize, this.startWindowEvery)); - }; - return WindowCountOperator; -}()); -var WindowCountSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowCountSubscriber, _super); - function WindowCountSubscriber(destination, windowSize, startWindowEvery) { - var _this = _super.call(this, destination) || this; - _this.destination = destination; - _this.windowSize = windowSize; - _this.startWindowEvery = startWindowEvery; - _this.windows = [new _Subject__WEBPACK_IMPORTED_MODULE_2__["Subject"]()]; - _this.count = 0; - destination.next(_this.windows[0]); - return _this; - } - WindowCountSubscriber.prototype._next = function (value) { - var startWindowEvery = (this.startWindowEvery > 0) ? this.startWindowEvery : this.windowSize; - var destination = this.destination; - var windowSize = this.windowSize; - var windows = this.windows; - var len = windows.length; - for (var i = 0; i < len && !this.closed; i++) { - windows[i].next(value); - } - var c = this.count - windowSize + 1; - if (c >= 0 && c % startWindowEvery === 0 && !this.closed) { - windows.shift().complete(); - } - if (++this.count % startWindowEvery === 0 && !this.closed) { - var window_1 = new _Subject__WEBPACK_IMPORTED_MODULE_2__["Subject"](); - windows.push(window_1); - destination.next(window_1); - } - }; - WindowCountSubscriber.prototype._error = function (err) { - var windows = this.windows; - if (windows) { - while (windows.length > 0 && !this.closed) { - windows.shift().error(err); - } - } - this.destination.error(err); - }; - WindowCountSubscriber.prototype._complete = function () { - var windows = this.windows; - if (windows) { - while (windows.length > 0 && !this.closed) { - windows.shift().complete(); - } - } - this.destination.complete(); - }; - WindowCountSubscriber.prototype._unsubscribe = function () { - this.count = 0; - this.windows = null; - }; - return WindowCountSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=windowCount.js.map - /***/ }), /* 362 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windowTime", function() { return windowTime; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(187); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(215); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(172); -/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(257); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(205); -/** PURE_IMPORTS_START tslib,_Subject,_scheduler_async,_Subscriber,_util_isNumeric,_util_isScheduler PURE_IMPORTS_END */ +const {signalsByName} = __webpack_require__(363); +const getErrorPrefix = ({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}) => { + if (timedOut) { + return `timed out after ${timeout} milliseconds`; + } + if (isCanceled) { + return 'was canceled'; + } + if (errorCode !== undefined) { + return `failed with ${errorCode}`; + } + if (signal !== undefined) { + return `was killed with ${signal} (${signalDescription})`; + } -function windowTime(windowTimeSpan) { - var scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; - var windowCreationInterval = null; - var maxWindowSize = Number.POSITIVE_INFINITY; - if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_5__["isScheduler"])(arguments[3])) { - scheduler = arguments[3]; - } - if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_5__["isScheduler"])(arguments[2])) { - scheduler = arguments[2]; - } - else if (Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_4__["isNumeric"])(arguments[2])) { - maxWindowSize = arguments[2]; - } - if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_5__["isScheduler"])(arguments[1])) { - scheduler = arguments[1]; - } - else if (Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_4__["isNumeric"])(arguments[1])) { - windowCreationInterval = arguments[1]; - } - return function windowTimeOperatorFunction(source) { - return source.lift(new WindowTimeOperator(windowTimeSpan, windowCreationInterval, maxWindowSize, scheduler)); - }; -} -var WindowTimeOperator = /*@__PURE__*/ (function () { - function WindowTimeOperator(windowTimeSpan, windowCreationInterval, maxWindowSize, scheduler) { - this.windowTimeSpan = windowTimeSpan; - this.windowCreationInterval = windowCreationInterval; - this.maxWindowSize = maxWindowSize; - this.scheduler = scheduler; - } - WindowTimeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new WindowTimeSubscriber(subscriber, this.windowTimeSpan, this.windowCreationInterval, this.maxWindowSize, this.scheduler)); - }; - return WindowTimeOperator; -}()); -var CountedSubject = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CountedSubject, _super); - function CountedSubject() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this._numberOfNextedValues = 0; - return _this; - } - CountedSubject.prototype.next = function (value) { - this._numberOfNextedValues++; - _super.prototype.next.call(this, value); - }; - Object.defineProperty(CountedSubject.prototype, "numberOfNextedValues", { - get: function () { - return this._numberOfNextedValues; - }, - enumerable: true, - configurable: true - }); - return CountedSubject; -}(_Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"])); -var WindowTimeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowTimeSubscriber, _super); - function WindowTimeSubscriber(destination, windowTimeSpan, windowCreationInterval, maxWindowSize, scheduler) { - var _this = _super.call(this, destination) || this; - _this.destination = destination; - _this.windowTimeSpan = windowTimeSpan; - _this.windowCreationInterval = windowCreationInterval; - _this.maxWindowSize = maxWindowSize; - _this.scheduler = scheduler; - _this.windows = []; - var window = _this.openWindow(); - if (windowCreationInterval !== null && windowCreationInterval >= 0) { - var closeState = { subscriber: _this, window: window, context: null }; - var creationState = { windowTimeSpan: windowTimeSpan, windowCreationInterval: windowCreationInterval, subscriber: _this, scheduler: scheduler }; - _this.add(scheduler.schedule(dispatchWindowClose, windowTimeSpan, closeState)); - _this.add(scheduler.schedule(dispatchWindowCreation, windowCreationInterval, creationState)); - } - else { - var timeSpanOnlyState = { subscriber: _this, window: window, windowTimeSpan: windowTimeSpan }; - _this.add(scheduler.schedule(dispatchWindowTimeSpanOnly, windowTimeSpan, timeSpanOnlyState)); - } - return _this; - } - WindowTimeSubscriber.prototype._next = function (value) { - var windows = this.windows; - var len = windows.length; - for (var i = 0; i < len; i++) { - var window_1 = windows[i]; - if (!window_1.closed) { - window_1.next(value); - if (window_1.numberOfNextedValues >= this.maxWindowSize) { - this.closeWindow(window_1); - } - } - } - }; - WindowTimeSubscriber.prototype._error = function (err) { - var windows = this.windows; - while (windows.length > 0) { - windows.shift().error(err); - } - this.destination.error(err); - }; - WindowTimeSubscriber.prototype._complete = function () { - var windows = this.windows; - while (windows.length > 0) { - var window_2 = windows.shift(); - if (!window_2.closed) { - window_2.complete(); - } - } - this.destination.complete(); - }; - WindowTimeSubscriber.prototype.openWindow = function () { - var window = new CountedSubject(); - this.windows.push(window); - var destination = this.destination; - destination.next(window); - return window; - }; - WindowTimeSubscriber.prototype.closeWindow = function (window) { - window.complete(); - var windows = this.windows; - windows.splice(windows.indexOf(window), 1); - }; - return WindowTimeSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__["Subscriber"])); -function dispatchWindowTimeSpanOnly(state) { - var subscriber = state.subscriber, windowTimeSpan = state.windowTimeSpan, window = state.window; - if (window) { - subscriber.closeWindow(window); - } - state.window = subscriber.openWindow(); - this.schedule(state, windowTimeSpan); -} -function dispatchWindowCreation(state) { - var windowTimeSpan = state.windowTimeSpan, subscriber = state.subscriber, scheduler = state.scheduler, windowCreationInterval = state.windowCreationInterval; - var window = subscriber.openWindow(); - var action = this; - var context = { action: action, subscription: null }; - var timeSpanState = { subscriber: subscriber, window: window, context: context }; - context.subscription = scheduler.schedule(dispatchWindowClose, windowTimeSpan, timeSpanState); - action.add(context.subscription); - action.schedule(state, windowCreationInterval); -} -function dispatchWindowClose(state) { - var subscriber = state.subscriber, window = state.window, context = state.context; - if (context && context.action && context.subscription) { - context.action.remove(context.subscription); - } - subscriber.closeWindow(window); -} -//# sourceMappingURL=windowTime.js.map + if (exitCode !== undefined) { + return `failed with exit code ${exitCode}`; + } + + return 'failed'; +}; + +const makeError = ({ + stdout, + stderr, + all, + error, + signal, + exitCode, + command, + timedOut, + isCanceled, + killed, + parsed: {options: {timeout}} +}) => { + // `signal` and `exitCode` emitted on `spawned.on('exit')` event can be `null`. + // We normalize them to `undefined` + exitCode = exitCode === null ? undefined : exitCode; + signal = signal === null ? undefined : signal; + const signalDescription = signal === undefined ? undefined : signalsByName[signal].description; + + const errorCode = error && error.code; + + const prefix = getErrorPrefix({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}); + const execaMessage = `Command ${prefix}: ${command}`; + const isError = Object.prototype.toString.call(error) === '[object Error]'; + const shortMessage = isError ? `${execaMessage}\n${error.message}` : execaMessage; + const message = [shortMessage, stderr, stdout].filter(Boolean).join('\n'); + + if (isError) { + error.originalMessage = error.message; + error.message = message; + } else { + error = new Error(message); + } + + error.shortMessage = shortMessage; + error.command = command; + error.exitCode = exitCode; + error.signal = signal; + error.signalDescription = signalDescription; + error.stdout = stdout; + error.stderr = stderr; + + if (all !== undefined) { + error.all = all; + } + + if ('bufferedData' in error) { + delete error.bufferedData; + } + + error.failed = true; + error.timedOut = Boolean(timedOut); + error.isCanceled = isCanceled; + error.killed = killed && !timedOut; + + return error; +}; + +module.exports = makeError; /***/ }), /* 363 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windowToggle", function() { return windowToggle; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(187); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(177); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_Subject,_Subscription,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ +Object.defineProperty(exports,"__esModule",{value:true});exports.signalsByNumber=exports.signalsByName=void 0;var _os=__webpack_require__(364); +var _signals=__webpack_require__(365); +var _realtime=__webpack_require__(367); +const getSignalsByName=function(){ +const signals=(0,_signals.getSignals)(); +return signals.reduce(getSignalByName,{}); +}; -function windowToggle(openings, closingSelector) { - return function (source) { return source.lift(new WindowToggleOperator(openings, closingSelector)); }; +const getSignalByName=function( +signalByNameMemo, +{name,number,description,supported,action,forced,standard}) +{ +return{ +...signalByNameMemo, +[name]:{name,number,description,supported,action,forced,standard}}; + +}; + +const signalsByName=getSignalsByName();exports.signalsByName=signalsByName; + + + + +const getSignalsByNumber=function(){ +const signals=(0,_signals.getSignals)(); +const length=_realtime.SIGRTMAX+1; +const signalsA=Array.from({length},(value,number)=> +getSignalByNumber(number,signals)); + +return Object.assign({},...signalsA); +}; + +const getSignalByNumber=function(number,signals){ +const signal=findSignalByNumber(number,signals); + +if(signal===undefined){ +return{}; } -var WindowToggleOperator = /*@__PURE__*/ (function () { - function WindowToggleOperator(openings, closingSelector) { - this.openings = openings; - this.closingSelector = closingSelector; - } - WindowToggleOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new WindowToggleSubscriber(subscriber, this.openings, this.closingSelector)); - }; - return WindowToggleOperator; -}()); -var WindowToggleSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowToggleSubscriber, _super); - function WindowToggleSubscriber(destination, openings, closingSelector) { - var _this = _super.call(this, destination) || this; - _this.openings = openings; - _this.closingSelector = closingSelector; - _this.contexts = []; - _this.add(_this.openSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(_this, openings, openings)); - return _this; - } - WindowToggleSubscriber.prototype._next = function (value) { - var contexts = this.contexts; - if (contexts) { - var len = contexts.length; - for (var i = 0; i < len; i++) { - contexts[i].window.next(value); - } - } - }; - WindowToggleSubscriber.prototype._error = function (err) { - var contexts = this.contexts; - this.contexts = null; - if (contexts) { - var len = contexts.length; - var index = -1; - while (++index < len) { - var context_1 = contexts[index]; - context_1.window.error(err); - context_1.subscription.unsubscribe(); - } - } - _super.prototype._error.call(this, err); - }; - WindowToggleSubscriber.prototype._complete = function () { - var contexts = this.contexts; - this.contexts = null; - if (contexts) { - var len = contexts.length; - var index = -1; - while (++index < len) { - var context_2 = contexts[index]; - context_2.window.complete(); - context_2.subscription.unsubscribe(); - } - } - _super.prototype._complete.call(this); - }; - WindowToggleSubscriber.prototype._unsubscribe = function () { - var contexts = this.contexts; - this.contexts = null; - if (contexts) { - var len = contexts.length; - var index = -1; - while (++index < len) { - var context_3 = contexts[index]; - context_3.window.unsubscribe(); - context_3.subscription.unsubscribe(); - } - } - }; - WindowToggleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - if (outerValue === this.openings) { - var closingNotifier = void 0; - try { - var closingSelector = this.closingSelector; - closingNotifier = closingSelector(innerValue); - } - catch (e) { - return this.error(e); - } - var window_1 = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); - var subscription = new _Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"](); - var context_4 = { window: window_1, subscription: subscription }; - this.contexts.push(context_4); - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, closingNotifier, context_4); - if (innerSubscription.closed) { - this.closeWindow(this.contexts.length - 1); - } - else { - innerSubscription.context = context_4; - subscription.add(innerSubscription); - } - this.destination.next(window_1); - } - else { - this.closeWindow(this.contexts.indexOf(outerValue)); - } - }; - WindowToggleSubscriber.prototype.notifyError = function (err) { - this.error(err); - }; - WindowToggleSubscriber.prototype.notifyComplete = function (inner) { - if (inner !== this.openSubscription) { - this.closeWindow(this.contexts.indexOf(inner.context)); - } - }; - WindowToggleSubscriber.prototype.closeWindow = function (index) { - if (index === -1) { - return; - } - var contexts = this.contexts; - var context = contexts[index]; - var window = context.window, subscription = context.subscription; - contexts.splice(index, 1); - window.complete(); - subscription.unsubscribe(); - }; - return WindowToggleSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); -//# sourceMappingURL=windowToggle.js.map +const{name,description,supported,action,forced,standard}=signal; +return{ +[number]:{ +name, +number, +description, +supported, +action, +forced, +standard}}; -/***/ }), -/* 364 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windowWhen", function() { return windowWhen; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(187); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_Subject,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ +}; +const findSignalByNumber=function(number,signals){ +const signal=signals.find(({name})=>_os.constants.signals[name]===number); -function windowWhen(closingSelector) { - return function windowWhenOperatorFunction(source) { - return source.lift(new WindowOperator(closingSelector)); - }; +if(signal!==undefined){ +return signal; } -var WindowOperator = /*@__PURE__*/ (function () { - function WindowOperator(closingSelector) { - this.closingSelector = closingSelector; - } - WindowOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new WindowSubscriber(subscriber, this.closingSelector)); - }; - return WindowOperator; -}()); -var WindowSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowSubscriber, _super); - function WindowSubscriber(destination, closingSelector) { - var _this = _super.call(this, destination) || this; - _this.destination = destination; - _this.closingSelector = closingSelector; - _this.openWindow(); - return _this; - } - WindowSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.openWindow(innerSub); - }; - WindowSubscriber.prototype.notifyError = function (error, innerSub) { - this._error(error); - }; - WindowSubscriber.prototype.notifyComplete = function (innerSub) { - this.openWindow(innerSub); - }; - WindowSubscriber.prototype._next = function (value) { - this.window.next(value); - }; - WindowSubscriber.prototype._error = function (err) { - this.window.error(err); - this.destination.error(err); - this.unsubscribeClosingNotification(); - }; - WindowSubscriber.prototype._complete = function () { - this.window.complete(); - this.destination.complete(); - this.unsubscribeClosingNotification(); - }; - WindowSubscriber.prototype.unsubscribeClosingNotification = function () { - if (this.closingNotification) { - this.closingNotification.unsubscribe(); - } - }; - WindowSubscriber.prototype.openWindow = function (innerSub) { - if (innerSub === void 0) { - innerSub = null; - } - if (innerSub) { - this.remove(innerSub); - innerSub.unsubscribe(); - } - var prevWindow = this.window; - if (prevWindow) { - prevWindow.complete(); - } - var window = this.window = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); - this.destination.next(window); - var closingNotifier; - try { - var closingSelector = this.closingSelector; - closingNotifier = closingSelector(); - } - catch (e) { - this.destination.error(e); - this.window.error(e); - return; - } - this.add(this.closingNotification = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, closingNotifier)); - }; - return WindowSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); -//# sourceMappingURL=windowWhen.js.map - - -/***/ }), -/* 365 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "withLatestFrom", function() { return withLatestFrom; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(229); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(230); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - - - -function withLatestFrom() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - return function (source) { - var project; - if (typeof args[args.length - 1] === 'function') { - project = args.pop(); - } - var observables = args; - return source.lift(new WithLatestFromOperator(observables, project)); - }; -} -var WithLatestFromOperator = /*@__PURE__*/ (function () { - function WithLatestFromOperator(observables, project) { - this.observables = observables; - this.project = project; - } - WithLatestFromOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new WithLatestFromSubscriber(subscriber, this.observables, this.project)); - }; - return WithLatestFromOperator; -}()); -var WithLatestFromSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WithLatestFromSubscriber, _super); - function WithLatestFromSubscriber(destination, observables, project) { - var _this = _super.call(this, destination) || this; - _this.observables = observables; - _this.project = project; - _this.toRespond = []; - var len = observables.length; - _this.values = new Array(len); - for (var i = 0; i < len; i++) { - _this.toRespond.push(i); - } - for (var i = 0; i < len; i++) { - var observable = observables[i]; - _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, observable, observable, i)); - } - return _this; - } - WithLatestFromSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.values[outerIndex] = innerValue; - var toRespond = this.toRespond; - if (toRespond.length > 0) { - var found = toRespond.indexOf(outerIndex); - if (found !== -1) { - toRespond.splice(found, 1); - } - } - }; - WithLatestFromSubscriber.prototype.notifyComplete = function () { - }; - WithLatestFromSubscriber.prototype._next = function (value) { - if (this.toRespond.length === 0) { - var args = [value].concat(this.values); - if (this.project) { - this._tryProject(args); - } - else { - this.destination.next(args); - } - } - }; - WithLatestFromSubscriber.prototype._tryProject = function (args) { - var result; - try { - result = this.project.apply(this, args); - } - catch (err) { - this.destination.error(err); - return; - } - this.destination.next(result); - }; - return WithLatestFromSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=withLatestFrom.js.map - - -/***/ }), -/* 366 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return zip; }); -/* harmony import */ var _observable_zip__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(269); -/** PURE_IMPORTS_START _observable_zip PURE_IMPORTS_END */ -function zip() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; - } - return function zipOperatorFunction(source) { - return source.lift.call(_observable_zip__WEBPACK_IMPORTED_MODULE_0__["zip"].apply(void 0, [source].concat(observables))); - }; -} -//# sourceMappingURL=zip.js.map +return signals.find(signalA=>signalA.number===number); +}; +const signalsByNumber=getSignalsByNumber();exports.signalsByNumber=signalsByNumber; +//# sourceMappingURL=main.js.map /***/ }), -/* 367 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "zipAll", function() { return zipAll; }); -/* harmony import */ var _observable_zip__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(269); -/** PURE_IMPORTS_START _observable_zip PURE_IMPORTS_END */ - -function zipAll(project) { - return function (source) { return source.lift(new _observable_zip__WEBPACK_IMPORTED_MODULE_0__["ZipOperator"](project)); }; -} -//# sourceMappingURL=zipAll.js.map +/* 364 */ +/***/ (function(module, exports) { +module.exports = require("os"); /***/ }), -/* 368 */ +/* 365 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +Object.defineProperty(exports,"__esModule",{value:true});exports.getSignals=void 0;var _os=__webpack_require__(364); +var _core=__webpack_require__(366); +var _realtime=__webpack_require__(367); -const callbacks = new Set(); -let called = false; -function exit(exit, signal) { - if (called) { - return; - } - called = true; +const getSignals=function(){ +const realtimeSignals=(0,_realtime.getRealtimeSignals)(); +const signals=[..._core.SIGNALS,...realtimeSignals].map(normalizeSignal); +return signals; +};exports.getSignals=getSignals; - for (const callback of callbacks) { - callback(); - } - if (exit === true) { - process.exit(128 + signal); // eslint-disable-line unicorn/no-process-exit - } -} -module.exports = callback => { - callbacks.add(callback); - if (callbacks.size === 1) { - process.once('exit', exit); - process.once('SIGINT', exit.bind(null, true, 2)); - process.once('SIGTERM', exit.bind(null, true, 15)); - // PM2 Cluster shutdown message. Caught to support async handlers with pm2, needed because - // explicitly calling process.exit() doesn't trigger the beforeExit event, and the exit - // event cannot support async handlers, since the event loop is never called after it. - process.on('message', message => { - if (message === 'shutdown') { - exit(true, -128); - } - }); - } - return () => { - callbacks.delete(callback); - }; -}; +const normalizeSignal=function({ +name, +number:defaultNumber, +description, +action, +forced=false, +standard}) +{ +const{ +signals:{[name]:constantSignal}}= +_os.constants; +const supported=constantSignal!==undefined; +const number=supported?constantSignal:defaultNumber; +return{name,number,description,supported,action,forced,standard}; +}; +//# sourceMappingURL=signals.js.map /***/ }), -/* 369 */ +/* 366 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +Object.defineProperty(exports,"__esModule",{value:true});exports.SIGNALS=void 0; -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const $isCliError = Symbol('isCliError'); -function createCliError(message) { - const error = new Error(message); - error[$isCliError] = true; - return error; -} -exports.createCliError = createCliError; -function isCliError(error) { - return error && !!error[$isCliError]; -} -exports.isCliError = isCliError; +const SIGNALS=[ +{ +name:"SIGHUP", +number:1, +action:"terminate", +description:"Terminal closed", +standard:"posix"}, +{ +name:"SIGINT", +number:2, +action:"terminate", +description:"User interruption with CTRL-C", +standard:"ansi"}, -/***/ }), -/* 370 */ -/***/ (function(module, exports, __webpack_require__) { +{ +name:"SIGQUIT", +number:3, +action:"core", +description:"User interruption with CTRL-\\", +standard:"posix"}, -"use strict"; +{ +name:"SIGILL", +number:4, +action:"core", +description:"Invalid machine instruction", +standard:"ansi"}, -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const tslib_1 = __webpack_require__(36); -const execa_1 = tslib_1.__importDefault(__webpack_require__(371)); -const fs_1 = __webpack_require__(23); -const Rx = tslib_1.__importStar(__webpack_require__(169)); -const operators_1 = __webpack_require__(270); -const chalk_1 = tslib_1.__importDefault(__webpack_require__(2)); -const tree_kill_1 = tslib_1.__importDefault(__webpack_require__(411)); -const util_1 = __webpack_require__(29); -const treeKillAsync = util_1.promisify((...args) => tree_kill_1.default(...args)); -const observe_lines_1 = __webpack_require__(412); -const errors_1 = __webpack_require__(369); -const SECOND = 1000; -const STOP_TIMEOUT = 30 * SECOND; -async function withTimeout(attempt, ms, onTimeout) { - const TIMEOUT = Symbol('timeout'); - try { - await Promise.race([ - attempt(), - new Promise((_, reject) => setTimeout(() => reject(TIMEOUT), ms)), - ]); - } - catch (error) { - if (error === TIMEOUT) { - await onTimeout(); - } - else { - throw error; - } - } -} -function startProc(name, options, log) { - const { cmd, args, cwd, env, stdin } = options; - log.info('[%s] > %s', name, cmd, args.join(' ')); - // spawn fails with ENOENT when either the - // cmd or cwd don't exist, so we check for the cwd - // ahead of time so that the error is less ambiguous - try { - if (!fs_1.statSync(cwd).isDirectory()) { - throw new Error(`cwd "${cwd}" exists but is not a directory`); - } - } - catch (err) { - if (err.code === 'ENOENT') { - throw new Error(`cwd "${cwd}" does not exist`); - } - } - const childProcess = execa_1.default(cmd, args, { - cwd, - env, - stdio: ['pipe', 'pipe', 'pipe'], - preferLocal: true, - }); - if (stdin) { - childProcess.stdin.end(stdin, 'utf8'); - } - else { - childProcess.stdin.end(); - } - let stopCalled = false; - const outcome$ = Rx.race( - // observe first exit event - Rx.fromEvent(childProcess, 'exit').pipe(operators_1.take(1), operators_1.map(([code]) => { - if (stopCalled) { - return null; - } - // JVM exits with 143 on SIGTERM and 130 on SIGINT, dont' treat then as errors - if (code > 0 && !(code === 143 || code === 130)) { - throw errors_1.createCliError(`[${name}] exited with code ${code}`); - } - return code; - })), - // observe first error event - Rx.fromEvent(childProcess, 'error').pipe(operators_1.take(1), operators_1.mergeMap((err) => Rx.throwError(err)))).pipe(operators_1.share()); - const lines$ = Rx.merge(observe_lines_1.observeLines(childProcess.stdout), observe_lines_1.observeLines(childProcess.stderr)).pipe(operators_1.tap((line) => log.write(` ${chalk_1.default.gray('proc')} [${chalk_1.default.gray(name)}] ${line}`)), operators_1.share()); - const outcomePromise = Rx.merge(lines$.pipe(operators_1.ignoreElements()), outcome$).toPromise(); - async function stop(signal) { - if (stopCalled) { - return; - } - stopCalled = true; - await withTimeout(async () => { - log.debug(`Sending "${signal}" to proc "${name}"`); - await treeKillAsync(childProcess.pid, signal); - await outcomePromise; - }, STOP_TIMEOUT, async () => { - log.warning(`Proc "${name}" was sent "${signal}" didn't emit the "exit" or "error" events after ${STOP_TIMEOUT} ms, sending SIGKILL`); - await treeKillAsync(childProcess.pid, 'SIGKILL'); - }); - await withTimeout(async () => { - try { - await outcomePromise; - } - catch (error) { - // ignore - } - }, STOP_TIMEOUT, async () => { - throw new Error(`Proc "${name}" was stopped but never emitted either the "exit" or "error" event after ${STOP_TIMEOUT} ms`); - }); - } - return { - name, - lines$, - outcome$, - outcomePromise, - stop, - }; -} -exports.startProc = startProc; +{ +name:"SIGTRAP", +number:5, +action:"core", +description:"Debugger breakpoint", +standard:"posix"}, +{ +name:"SIGABRT", +number:6, +action:"core", +description:"Aborted", +standard:"ansi"}, -/***/ }), -/* 371 */ -/***/ (function(module, exports, __webpack_require__) { +{ +name:"SIGIOT", +number:6, +action:"core", +description:"Aborted", +standard:"bsd"}, -"use strict"; +{ +name:"SIGBUS", +number:7, +action:"core", +description: +"Bus error due to misaligned, non-existing address or paging error", +standard:"bsd"}, -const path = __webpack_require__(16); -const childProcess = __webpack_require__(372); -const crossSpawn = __webpack_require__(373); -const stripFinalNewline = __webpack_require__(386); -const npmRunPath = __webpack_require__(387); -const onetime = __webpack_require__(388); -const makeError = __webpack_require__(390); -const normalizeStdio = __webpack_require__(395); -const {spawnedKill, spawnedCancel, setupTimeout, setExitHandler} = __webpack_require__(396); -const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = __webpack_require__(400); -const {mergePromise, getSpawnedPromise} = __webpack_require__(409); -const {joinCommand, parseCommand} = __webpack_require__(410); +{ +name:"SIGEMT", +number:7, +action:"terminate", +description:"Command should be emulated but is not implemented", +standard:"other"}, -const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100; +{ +name:"SIGFPE", +number:8, +action:"core", +description:"Floating point arithmetic error", +standard:"ansi"}, -const getEnv = ({env: envOption, extendEnv, preferLocal, localDir, execPath}) => { - const env = extendEnv ? {...process.env, ...envOption} : envOption; +{ +name:"SIGKILL", +number:9, +action:"terminate", +description:"Forced termination", +standard:"posix", +forced:true}, - if (preferLocal) { - return npmRunPath.env({env, cwd: localDir, execPath}); - } +{ +name:"SIGUSR1", +number:10, +action:"terminate", +description:"Application-specific signal", +standard:"posix"}, - return env; -}; +{ +name:"SIGSEGV", +number:11, +action:"core", +description:"Segmentation fault", +standard:"ansi"}, -const handleArgs = (file, args, options = {}) => { - const parsed = crossSpawn._parse(file, args, options); - file = parsed.command; - args = parsed.args; - options = parsed.options; +{ +name:"SIGUSR2", +number:12, +action:"terminate", +description:"Application-specific signal", +standard:"posix"}, - options = { - maxBuffer: DEFAULT_MAX_BUFFER, - buffer: true, - stripFinalNewline: true, - extendEnv: true, - preferLocal: false, - localDir: options.cwd || process.cwd(), - execPath: process.execPath, - encoding: 'utf8', - reject: true, - cleanup: true, - all: false, - windowsHide: true, - ...options - }; +{ +name:"SIGPIPE", +number:13, +action:"terminate", +description:"Broken pipe or socket", +standard:"posix"}, - options.env = getEnv(options); +{ +name:"SIGALRM", +number:14, +action:"terminate", +description:"Timeout or timer", +standard:"posix"}, - options.stdio = normalizeStdio(options); +{ +name:"SIGTERM", +number:15, +action:"terminate", +description:"Termination", +standard:"ansi"}, - if (process.platform === 'win32' && path.basename(file, '.exe') === 'cmd') { - // #116 - args.unshift('/q'); - } +{ +name:"SIGSTKFLT", +number:16, +action:"terminate", +description:"Stack is empty or overflowed", +standard:"other"}, - return {file, args, options, parsed}; -}; +{ +name:"SIGCHLD", +number:17, +action:"ignore", +description:"Child process terminated, paused or unpaused", +standard:"posix"}, -const handleOutput = (options, value, error) => { - if (typeof value !== 'string' && !Buffer.isBuffer(value)) { - // When `execa.sync()` errors, we normalize it to '' to mimic `execa()` - return error === undefined ? undefined : ''; - } +{ +name:"SIGCLD", +number:17, +action:"ignore", +description:"Child process terminated, paused or unpaused", +standard:"other"}, - if (options.stripFinalNewline) { - return stripFinalNewline(value); - } +{ +name:"SIGCONT", +number:18, +action:"unpause", +description:"Unpaused", +standard:"posix", +forced:true}, - return value; -}; +{ +name:"SIGSTOP", +number:19, +action:"pause", +description:"Paused", +standard:"posix", +forced:true}, -const execa = (file, args, options) => { - const parsed = handleArgs(file, args, options); - const command = joinCommand(file, args); +{ +name:"SIGTSTP", +number:20, +action:"pause", +description:"Paused using CTRL-Z or \"suspend\"", +standard:"posix"}, - let spawned; - try { - spawned = childProcess.spawn(parsed.file, parsed.args, parsed.options); - } catch (error) { - // Ensure the returned error is always both a promise and a child process - const dummySpawned = new childProcess.ChildProcess(); - const errorPromise = Promise.reject(makeError({ - error, - stdout: '', - stderr: '', - all: '', - command, - parsed, - timedOut: false, - isCanceled: false, - killed: false - })); - return mergePromise(dummySpawned, errorPromise); - } +{ +name:"SIGTTIN", +number:21, +action:"pause", +description:"Background process cannot read terminal input", +standard:"posix"}, - const spawnedPromise = getSpawnedPromise(spawned); - const timedPromise = setupTimeout(spawned, parsed.options, spawnedPromise); - const processDone = setExitHandler(spawned, parsed.options, timedPromise); +{ +name:"SIGBREAK", +number:21, +action:"terminate", +description:"User interruption with CTRL-BREAK", +standard:"other"}, - const context = {isCanceled: false}; +{ +name:"SIGTTOU", +number:22, +action:"pause", +description:"Background process cannot write to terminal output", +standard:"posix"}, - spawned.kill = spawnedKill.bind(null, spawned.kill.bind(spawned)); - spawned.cancel = spawnedCancel.bind(null, spawned, context); +{ +name:"SIGURG", +number:23, +action:"ignore", +description:"Socket received out-of-band data", +standard:"bsd"}, - const handlePromise = async () => { - const [{error, exitCode, signal, timedOut}, stdoutResult, stderrResult, allResult] = await getSpawnedResult(spawned, parsed.options, processDone); - const stdout = handleOutput(parsed.options, stdoutResult); - const stderr = handleOutput(parsed.options, stderrResult); - const all = handleOutput(parsed.options, allResult); +{ +name:"SIGXCPU", +number:24, +action:"core", +description:"Process timed out", +standard:"bsd"}, - if (error || exitCode !== 0 || signal !== null) { - const returnedError = makeError({ - error, - exitCode, - signal, - stdout, - stderr, - all, - command, - parsed, - timedOut, - isCanceled: context.isCanceled, - killed: spawned.killed - }); +{ +name:"SIGXFSZ", +number:25, +action:"core", +description:"File too big", +standard:"bsd"}, - if (!parsed.options.reject) { - return returnedError; - } +{ +name:"SIGVTALRM", +number:26, +action:"terminate", +description:"Timeout or timer", +standard:"bsd"}, - throw returnedError; - } +{ +name:"SIGPROF", +number:27, +action:"terminate", +description:"Timeout or timer", +standard:"bsd"}, - return { - command, - exitCode: 0, - stdout, - stderr, - all, - failed: false, - timedOut: false, - isCanceled: false, - killed: false - }; - }; +{ +name:"SIGWINCH", +number:28, +action:"ignore", +description:"Terminal window size changed", +standard:"bsd"}, - const handlePromiseOnce = onetime(handlePromise); +{ +name:"SIGIO", +number:29, +action:"terminate", +description:"I/O is available", +standard:"other"}, - crossSpawn._enoent.hookChildProcess(spawned, parsed.parsed); +{ +name:"SIGPOLL", +number:29, +action:"terminate", +description:"Watched event", +standard:"other"}, - handleInput(spawned, parsed.options.input); +{ +name:"SIGINFO", +number:29, +action:"ignore", +description:"Request for process information", +standard:"other"}, - spawned.all = makeAllStream(spawned, parsed.options); +{ +name:"SIGPWR", +number:30, +action:"terminate", +description:"Device running out of power", +standard:"systemv"}, + +{ +name:"SIGSYS", +number:31, +action:"core", +description:"Invalid system call", +standard:"other"}, + +{ +name:"SIGUNUSED", +number:31, +action:"terminate", +description:"Invalid system call", +standard:"other"}];exports.SIGNALS=SIGNALS; +//# sourceMappingURL=core.js.map + +/***/ }), +/* 367 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +Object.defineProperty(exports,"__esModule",{value:true});exports.SIGRTMAX=exports.getRealtimeSignals=void 0; +const getRealtimeSignals=function(){ +const length=SIGRTMAX-SIGRTMIN+1; +return Array.from({length},getRealtimeSignal); +};exports.getRealtimeSignals=getRealtimeSignals; + +const getRealtimeSignal=function(value,index){ +return{ +name:`SIGRT${index+1}`, +number:SIGRTMIN+index, +action:"terminate", +description:"Application-specific signal (realtime)", +standard:"posix"}; - return mergePromise(spawned, handlePromiseOnce); }; -module.exports = execa; +const SIGRTMIN=34; +const SIGRTMAX=64;exports.SIGRTMAX=SIGRTMAX; +//# sourceMappingURL=realtime.js.map -module.exports.sync = (file, args, options) => { - const parsed = handleArgs(file, args, options); - const command = joinCommand(file, args); +/***/ }), +/* 368 */ +/***/ (function(module, exports, __webpack_require__) { - validateInputSync(parsed.options); +"use strict"; - let result; - try { - result = childProcess.spawnSync(parsed.file, parsed.args, parsed.options); - } catch (error) { - throw makeError({ - error, - stdout: '', - stderr: '', - all: '', - command, - parsed, - timedOut: false, - isCanceled: false, - killed: false - }); +const aliases = ['stdin', 'stdout', 'stderr']; + +const hasAlias = opts => aliases.some(alias => opts[alias] !== undefined); + +const normalizeStdio = opts => { + if (!opts) { + return; } - const stdout = handleOutput(parsed.options, result.stdout, result.error); - const stderr = handleOutput(parsed.options, result.stderr, result.error); + const {stdio} = opts; - if (result.error || result.status !== 0 || result.signal !== null) { - const error = makeError({ - stdout, - stderr, - error: result.error, - signal: result.signal, - exitCode: result.status, - command, - parsed, - timedOut: result.error && result.error.code === 'ETIMEDOUT', - isCanceled: false, - killed: result.signal !== null - }); + if (stdio === undefined) { + return aliases.map(alias => opts[alias]); + } - if (!parsed.options.reject) { - return error; - } + if (hasAlias(opts)) { + throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${aliases.map(alias => `\`${alias}\``).join(', ')}`); + } - throw error; + if (typeof stdio === 'string') { + return stdio; } - return { - command, - exitCode: 0, - stdout, - stderr, - failed: false, - timedOut: false, - isCanceled: false, - killed: false - }; -}; + if (!Array.isArray(stdio)) { + throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``); + } -module.exports.command = (command, options) => { - const [file, ...args] = parseCommand(command); - return execa(file, args, options); + const length = Math.max(stdio.length, aliases.length); + return Array.from({length}, (value, index) => stdio[index]); }; -module.exports.commandSync = (command, options) => { - const [file, ...args] = parseCommand(command); - return execa.sync(file, args, options); -}; +module.exports = normalizeStdio; -module.exports.node = (scriptPath, args, options = {}) => { - if (args && !Array.isArray(args) && typeof args === 'object') { - options = args; - args = []; +// `ipc` is pushed unless it is already present +module.exports.node = opts => { + const stdio = normalizeStdio(opts); + + if (stdio === 'ipc') { + return 'ipc'; } - const stdio = normalizeStdio.node(options); + if (stdio === undefined || typeof stdio === 'string') { + return [stdio, stdio, stdio, 'ipc']; + } - const {nodePath = process.execPath, nodeOptions = process.execArgv} = options; + if (stdio.includes('ipc')) { + return stdio; + } - return execa( - nodePath, - [ - ...nodeOptions, - scriptPath, - ...(Array.isArray(args) ? args : []) - ], - { - ...options, - stdin: undefined, - stdout: undefined, - stderr: undefined, - stdio, - shell: false - } - ); + return [...stdio, 'ipc']; }; /***/ }), -/* 372 */ -/***/ (function(module, exports) { - -module.exports = require("child_process"); - -/***/ }), -/* 373 */ +/* 369 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const os = __webpack_require__(364); +const onExit = __webpack_require__(370); -const cp = __webpack_require__(372); -const parse = __webpack_require__(374); -const enoent = __webpack_require__(385); +const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5; -function spawn(command, args, options) { - // Parse the arguments - const parsed = parse(command, args, options); +// Monkey-patches `childProcess.kill()` to add `forceKillAfterTimeout` behavior +const spawnedKill = (kill, signal = 'SIGTERM', options = {}) => { + const killResult = kill(signal); + setKillTimeout(kill, signal, options, killResult); + return killResult; +}; - // Spawn the child process - const spawned = cp.spawn(parsed.command, parsed.args, parsed.options); +const setKillTimeout = (kill, signal, options, killResult) => { + if (!shouldForceKill(signal, options, killResult)) { + return; + } - // Hook into child process "exit" event to emit an error if the command - // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 - enoent.hookChildProcess(spawned, parsed); + const timeout = getForceKillAfterTimeout(options); + const t = setTimeout(() => { + kill('SIGKILL'); + }, timeout); - return spawned; -} + // Guarded because there's no `.unref()` when `execa` is used in the renderer + // process in Electron. This cannot be tested since we don't run tests in + // Electron. + // istanbul ignore else + if (t.unref) { + t.unref(); + } +}; -function spawnSync(command, args, options) { - // Parse the arguments - const parsed = parse(command, args, options); +const shouldForceKill = (signal, {forceKillAfterTimeout}, killResult) => { + return isSigterm(signal) && forceKillAfterTimeout !== false && killResult; +}; - // Spawn the child process - const result = cp.spawnSync(parsed.command, parsed.args, parsed.options); +const isSigterm = signal => { + return signal === os.constants.signals.SIGTERM || + (typeof signal === 'string' && signal.toUpperCase() === 'SIGTERM'); +}; - // Analyze if the command does not exist, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 - result.error = result.error || enoent.verifyENOENTSync(result.status, parsed); +const getForceKillAfterTimeout = ({forceKillAfterTimeout = true}) => { + if (forceKillAfterTimeout === true) { + return DEFAULT_FORCE_KILL_TIMEOUT; + } - return result; -} + if (!Number.isInteger(forceKillAfterTimeout) || forceKillAfterTimeout < 0) { + throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${forceKillAfterTimeout}\` (${typeof forceKillAfterTimeout})`); + } -module.exports = spawn; -module.exports.spawn = spawn; -module.exports.sync = spawnSync; + return forceKillAfterTimeout; +}; -module.exports._parse = parse; -module.exports._enoent = enoent; +// `childProcess.cancel()` +const spawnedCancel = (spawned, context) => { + const killResult = spawned.kill(); + if (killResult) { + context.isCanceled = true; + } +}; -/***/ }), -/* 374 */ -/***/ (function(module, exports, __webpack_require__) { +const timeoutKill = (spawned, signal, reject) => { + spawned.kill(signal); + reject(Object.assign(new Error('Timed out'), {timedOut: true, signal})); +}; -"use strict"; +// `timeout` option handling +const setupTimeout = (spawned, {timeout, killSignal = 'SIGTERM'}, spawnedPromise) => { + if (timeout === 0 || timeout === undefined) { + return spawnedPromise; + } + if (!Number.isInteger(timeout) || timeout < 0) { + throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`); + } -const path = __webpack_require__(16); -const resolveCommand = __webpack_require__(375); -const escape = __webpack_require__(381); -const readShebang = __webpack_require__(382); + let timeoutId; + const timeoutPromise = new Promise((resolve, reject) => { + timeoutId = setTimeout(() => { + timeoutKill(spawned, killSignal, reject); + }, timeout); + }); -const isWin = process.platform === 'win32'; -const isExecutableRegExp = /\.(?:com|exe)$/i; -const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i; + const safeSpawnedPromise = spawnedPromise.finally(() => { + clearTimeout(timeoutId); + }); -function detectShebang(parsed) { - parsed.file = resolveCommand(parsed); + return Promise.race([timeoutPromise, safeSpawnedPromise]); +}; - const shebang = parsed.file && readShebang(parsed.file); +// `cleanup` option handling +const setExitHandler = async (spawned, {cleanup, detached}, timedPromise) => { + if (!cleanup || detached) { + return timedPromise; + } - if (shebang) { - parsed.args.unshift(parsed.file); - parsed.command = shebang; + const removeExitHandler = onExit(() => { + spawned.kill(); + }); - return resolveCommand(parsed); - } + return timedPromise.finally(() => { + removeExitHandler(); + }); +}; - return parsed.file; -} +module.exports = { + spawnedKill, + spawnedCancel, + setupTimeout, + setExitHandler +}; -function parseNonShell(parsed) { - if (!isWin) { - return parsed; - } - // Detect & add support for shebangs - const commandFile = detectShebang(parsed); +/***/ }), +/* 370 */ +/***/ (function(module, exports, __webpack_require__) { - // We don't need a shell if the command filename is an executable - const needsShell = !isExecutableRegExp.test(commandFile); +// Note: since nyc uses this module to output coverage, any lines +// that are in the direct sync flow of nyc's outputCoverage are +// ignored, since we can never get coverage for them. +var assert = __webpack_require__(371) +var signals = __webpack_require__(372) - // If a shell is required, use cmd.exe and take care of escaping everything correctly - // Note that `forceShell` is an hidden option used only in tests - if (parsed.options.forceShell || needsShell) { - // Need to double escape meta chars if the command is a cmd-shim located in `node_modules/.bin/` - // The cmd-shim simply calls execute the package bin file with NodeJS, proxying any argument - // Because the escape of metachars with ^ gets interpreted when the cmd.exe is first called, - // we need to double escape them - const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile); +var EE = __webpack_require__(373) +/* istanbul ignore if */ +if (typeof EE !== 'function') { + EE = EE.EventEmitter +} - // Normalize posix paths into OS compatible paths (e.g.: foo/bar -> foo\bar) - // This is necessary otherwise it will always fail with ENOENT in those cases - parsed.command = path.normalize(parsed.command); +var emitter +if (process.__signal_exit_emitter__) { + emitter = process.__signal_exit_emitter__ +} else { + emitter = process.__signal_exit_emitter__ = new EE() + emitter.count = 0 + emitter.emitted = {} +} - // Escape command & arguments - parsed.command = escape.command(parsed.command); - parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars)); +// Because this emitter is a global, we have to check to see if a +// previous version of this library failed to enable infinite listeners. +// I know what you're about to say. But literally everything about +// signal-exit is a compromise with evil. Get used to it. +if (!emitter.infinite) { + emitter.setMaxListeners(Infinity) + emitter.infinite = true +} - const shellCommand = [parsed.command].concat(parsed.args).join(' '); +module.exports = function (cb, opts) { + assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler') - parsed.args = ['/d', '/s', '/c', `"${shellCommand}"`]; - parsed.command = process.env.comspec || 'cmd.exe'; - parsed.options.windowsVerbatimArguments = true; // Tell node's spawn that the arguments are already escaped - } + if (loaded === false) { + load() + } - return parsed; -} + var ev = 'exit' + if (opts && opts.alwaysLast) { + ev = 'afterexit' + } -function parse(command, args, options) { - // Normalize arguments, similar to nodejs - if (args && !Array.isArray(args)) { - options = args; - args = null; + var remove = function () { + emitter.removeListener(ev, cb) + if (emitter.listeners('exit').length === 0 && + emitter.listeners('afterexit').length === 0) { + unload() } + } + emitter.on(ev, cb) - args = args ? args.slice(0) : []; // Clone array to avoid changing the original - options = Object.assign({}, options); // Clone object to avoid changing the original - - // Build our parsed object - const parsed = { - command, - args, - options, - file: undefined, - original: { - command, - args, - }, - }; - - // Delegate further parsing to shell or non-shell - return options.shell ? parsed : parseNonShell(parsed); + return remove } -module.exports = parse; +module.exports.unload = unload +function unload () { + if (!loaded) { + return + } + loaded = false + signals.forEach(function (sig) { + try { + process.removeListener(sig, sigListeners[sig]) + } catch (er) {} + }) + process.emit = originalProcessEmit + process.reallyExit = originalProcessReallyExit + emitter.count -= 1 +} -/***/ }), -/* 375 */ -/***/ (function(module, exports, __webpack_require__) { +function emit (event, code, signal) { + if (emitter.emitted[event]) { + return + } + emitter.emitted[event] = true + emitter.emit(event, code, signal) +} -"use strict"; +// { : , ... } +var sigListeners = {} +signals.forEach(function (sig) { + sigListeners[sig] = function listener () { + // If there are no other listeners, an exit is coming! + // Simplest way: remove us and then re-send the signal. + // We know that this will kill the process, so we can + // safely emit now. + var listeners = process.listeners(sig) + if (listeners.length === emitter.count) { + unload() + emit('exit', null, sig) + /* istanbul ignore next */ + emit('afterexit', null, sig) + /* istanbul ignore next */ + process.kill(process.pid, sig) + } + } +}) +module.exports.signals = function () { + return signals +} -const path = __webpack_require__(16); -const which = __webpack_require__(376); -const pathKey = __webpack_require__(380)(); +module.exports.load = load -function resolveCommandAttempt(parsed, withoutPathExt) { - const cwd = process.cwd(); - const hasCustomCwd = parsed.options.cwd != null; - // Worker threads do not have process.chdir() - const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined; +var loaded = false - // If a custom `cwd` was specified, we need to change the process cwd - // because `which` will do stat calls but does not support a custom cwd - if (shouldSwitchCwd) { - try { - process.chdir(parsed.options.cwd); - } catch (err) { - /* Empty */ - } - } +function load () { + if (loaded) { + return + } + loaded = true - let resolved; + // This is the number of onSignalExit's that are in play. + // It's important so that we can count the correct number of + // listeners on signals, and don't wait for the other one to + // handle it instead of us. + emitter.count += 1 + signals = signals.filter(function (sig) { try { - resolved = which.sync(parsed.command, { - path: (parsed.options.env || process.env)[pathKey], - pathExt: withoutPathExt ? path.delimiter : undefined, - }); - } catch (e) { - /* Empty */ - } finally { - if (shouldSwitchCwd) { - process.chdir(cwd); - } + process.on(sig, sigListeners[sig]) + return true + } catch (er) { + return false } + }) - // If we successfully resolved, ensure that an absolute path is returned - // Note that when a custom `cwd` was used, we need to resolve to an absolute path based on it - if (resolved) { - resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : '', resolved); - } + process.emit = processEmit + process.reallyExit = processReallyExit +} - return resolved; +var originalProcessReallyExit = process.reallyExit +function processReallyExit (code) { + process.exitCode = code || 0 + emit('exit', process.exitCode, null) + /* istanbul ignore next */ + emit('afterexit', process.exitCode, null) + /* istanbul ignore next */ + originalProcessReallyExit.call(process, process.exitCode) } -function resolveCommand(parsed) { - return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true); +var originalProcessEmit = process.emit +function processEmit (ev, arg) { + if (ev === 'exit') { + if (arg !== undefined) { + process.exitCode = arg + } + var ret = originalProcessEmit.apply(this, arguments) + emit('exit', process.exitCode, null) + /* istanbul ignore next */ + emit('afterexit', process.exitCode, null) + return ret + } else { + return originalProcessEmit.apply(this, arguments) + } } -module.exports = resolveCommand; +/***/ }), +/* 371 */ +/***/ (function(module, exports) { + +module.exports = require("assert"); /***/ }), -/* 376 */ -/***/ (function(module, exports, __webpack_require__) { +/* 372 */ +/***/ (function(module, exports) { -const isWindows = process.platform === 'win32' || - process.env.OSTYPE === 'cygwin' || - process.env.OSTYPE === 'msys' +// This is not the set of all possible signals. +// +// It IS, however, the set of all signals that trigger +// an exit on either Linux or BSD systems. Linux is a +// superset of the signal names supported on BSD, and +// the unknown signals just fail to register, so we can +// catch that easily enough. +// +// Don't bother with SIGKILL. It's uncatchable, which +// means that we can't fire any callbacks anyway. +// +// If a user does happen to register a handler on a non- +// fatal signal like SIGWINCH or something, and then +// exit, it'll end up firing `process.emit('exit')`, so +// the handler will be fired anyway. +// +// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised +// artificially, inherently leave the process in a +// state from which it is not safe to try and enter JS +// listeners. +module.exports = [ + 'SIGABRT', + 'SIGALRM', + 'SIGHUP', + 'SIGINT', + 'SIGTERM' +] -const path = __webpack_require__(16) -const COLON = isWindows ? ';' : ':' -const isexe = __webpack_require__(377) +if (process.platform !== 'win32') { + module.exports.push( + 'SIGVTALRM', + 'SIGXCPU', + 'SIGXFSZ', + 'SIGUSR2', + 'SIGTRAP', + 'SIGSYS', + 'SIGQUIT', + 'SIGIOT' + // should detect profiler and enable/disable accordingly. + // see #21 + // 'SIGPROF' + ) +} -const getNotFoundError = (cmd) => - Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }) +if (process.platform === 'linux') { + module.exports.push( + 'SIGIO', + 'SIGPOLL', + 'SIGPWR', + 'SIGSTKFLT', + 'SIGUNUSED' + ) +} -const getPathInfo = (cmd, opt) => { - const colon = opt.colon || COLON - // If it has a slash, then we don't bother searching the pathenv. - // just check the file itself, and that's it. - const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [''] - : ( - [ - // windows always checks the cwd first - ...(isWindows ? [process.cwd()] : []), - ...(opt.path || process.env.PATH || - /* istanbul ignore next: very unusual */ '').split(colon), - ] - ) - const pathExtExe = isWindows - ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM' - : '' - const pathExt = isWindows ? pathExtExe.split(colon) : [''] +/***/ }), +/* 373 */ +/***/ (function(module, exports) { - if (isWindows) { - if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') - pathExt.unshift('') - } +module.exports = require("events"); - return { - pathEnv, - pathExt, - pathExtExe, - } -} +/***/ }), +/* 374 */ +/***/ (function(module, exports, __webpack_require__) { -const which = (cmd, opt, cb) => { - if (typeof opt === 'function') { - cb = opt - opt = {} - } - if (!opt) - opt = {} +"use strict"; - const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) - const found = [] +const isStream = __webpack_require__(375); +const getStream = __webpack_require__(376); +const mergeStream = __webpack_require__(383); - const step = i => new Promise((resolve, reject) => { - if (i === pathEnv.length) - return opt.all && found.length ? resolve(found) - : reject(getNotFoundError(cmd)) +// `input` option +const handleInput = (spawned, input) => { + // Checking for stdin is workaround for https://github.com/nodejs/node/issues/26852 + // TODO: Remove `|| spawned.stdin === undefined` once we drop support for Node.js <=12.2.0 + if (input === undefined || spawned.stdin === undefined) { + return; + } - const ppRaw = pathEnv[i] - const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw + if (isStream(input)) { + input.pipe(spawned.stdin); + } else { + spawned.stdin.end(input); + } +}; - const pCmd = path.join(pathPart, cmd) - const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd - : pCmd +// `all` interleaves `stdout` and `stderr` +const makeAllStream = (spawned, {all}) => { + if (!all || (!spawned.stdout && !spawned.stderr)) { + return; + } - resolve(subStep(p, i, 0)) - }) + const mixed = mergeStream(); - const subStep = (p, i, ii) => new Promise((resolve, reject) => { - if (ii === pathExt.length) - return resolve(step(i + 1)) - const ext = pathExt[ii] - isexe(p + ext, { pathExt: pathExtExe }, (er, is) => { - if (!er && is) { - if (opt.all) - found.push(p + ext) - else - return resolve(p + ext) - } - return resolve(subStep(p, i, ii + 1)) - }) - }) + if (spawned.stdout) { + mixed.add(spawned.stdout); + } - return cb ? step(0).then(res => cb(null, res), cb) : step(0) -} + if (spawned.stderr) { + mixed.add(spawned.stderr); + } -const whichSync = (cmd, opt) => { - opt = opt || {} + return mixed; +}; - const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) - const found = [] +// On failure, `result.stdout|stderr|all` should contain the currently buffered stream +const getBufferedData = async (stream, streamPromise) => { + if (!stream) { + return; + } - for (let i = 0; i < pathEnv.length; i ++) { - const ppRaw = pathEnv[i] - const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw + stream.destroy(); - const pCmd = path.join(pathPart, cmd) - const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd - : pCmd + try { + return await streamPromise; + } catch (error) { + return error.bufferedData; + } +}; - for (let j = 0; j < pathExt.length; j ++) { - const cur = p + pathExt[j] - try { - const is = isexe.sync(cur, { pathExt: pathExtExe }) - if (is) { - if (opt.all) - found.push(cur) - else - return cur - } - } catch (ex) {} - } - } +const getStreamPromise = (stream, {encoding, buffer, maxBuffer}) => { + if (!stream || !buffer) { + return; + } - if (opt.all && found.length) - return found + if (encoding) { + return getStream(stream, {encoding, maxBuffer}); + } - if (opt.nothrow) - return null + return getStream.buffer(stream, {maxBuffer}); +}; - throw getNotFoundError(cmd) -} +// Retrieve result of child process: exit code, signal, error, streams (stdout/stderr/all) +const getSpawnedResult = async ({stdout, stderr, all}, {encoding, buffer, maxBuffer}, processDone) => { + const stdoutPromise = getStreamPromise(stdout, {encoding, buffer, maxBuffer}); + const stderrPromise = getStreamPromise(stderr, {encoding, buffer, maxBuffer}); + const allPromise = getStreamPromise(all, {encoding, buffer, maxBuffer: maxBuffer * 2}); + + try { + return await Promise.all([processDone, stdoutPromise, stderrPromise, allPromise]); + } catch (error) { + return Promise.all([ + {error, signal: error.signal, timedOut: error.timedOut}, + getBufferedData(stdout, stdoutPromise), + getBufferedData(stderr, stderrPromise), + getBufferedData(all, allPromise) + ]); + } +}; + +const validateInputSync = ({input}) => { + if (isStream(input)) { + throw new TypeError('The `input` option cannot be a stream in sync mode'); + } +}; + +module.exports = { + handleInput, + makeAllStream, + getSpawnedResult, + validateInputSync +}; -module.exports = which -which.sync = whichSync /***/ }), -/* 377 */ +/* 375 */ /***/ (function(module, exports, __webpack_require__) { -var fs = __webpack_require__(23) -var core -if (process.platform === 'win32' || global.TESTING_WINDOWS) { - core = __webpack_require__(378) -} else { - core = __webpack_require__(379) -} +"use strict"; -module.exports = isexe -isexe.sync = sync -function isexe (path, options, cb) { - if (typeof options === 'function') { - cb = options - options = {} - } +const isStream = stream => + stream !== null && + typeof stream === 'object' && + typeof stream.pipe === 'function'; - if (!cb) { - if (typeof Promise !== 'function') { - throw new TypeError('callback not provided') - } +isStream.writable = stream => + isStream(stream) && + stream.writable !== false && + typeof stream._write === 'function' && + typeof stream._writableState === 'object'; - return new Promise(function (resolve, reject) { - isexe(path, options || {}, function (er, is) { - if (er) { - reject(er) - } else { - resolve(is) - } - }) - }) - } +isStream.readable = stream => + isStream(stream) && + stream.readable !== false && + typeof stream._read === 'function' && + typeof stream._readableState === 'object'; - core(path, options || {}, function (er, is) { - // ignore EACCES because that just means we aren't allowed to run it - if (er) { - if (er.code === 'EACCES' || options && options.ignoreErrors) { - er = null - is = false - } - } - cb(er, is) - }) -} +isStream.duplex = stream => + isStream.writable(stream) && + isStream.readable(stream); -function sync (path, options) { - // my kingdom for a filtered catch - try { - return core.sync(path, options || {}) - } catch (er) { - if (options && options.ignoreErrors || er.code === 'EACCES') { - return false - } else { - throw er - } - } -} +isStream.transform = stream => + isStream.duplex(stream) && + typeof stream._transform === 'function' && + typeof stream._transformState === 'object'; + +module.exports = isStream; /***/ }), -/* 378 */ +/* 376 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = isexe -isexe.sync = sync +"use strict"; -var fs = __webpack_require__(23) +const pump = __webpack_require__(377); +const bufferStream = __webpack_require__(381); -function checkPathExt (path, options) { - var pathext = options.pathExt !== undefined ? - options.pathExt : process.env.PATHEXT +class MaxBufferError extends Error { + constructor() { + super('maxBuffer exceeded'); + this.name = 'MaxBufferError'; + } +} - if (!pathext) { - return true - } +async function getStream(inputStream, options) { + if (!inputStream) { + return Promise.reject(new Error('Expected a stream')); + } - pathext = pathext.split(';') - if (pathext.indexOf('') !== -1) { - return true - } - for (var i = 0; i < pathext.length; i++) { - var p = pathext[i].toLowerCase() - if (p && path.substr(-p.length).toLowerCase() === p) { - return true - } - } - return false -} + options = { + maxBuffer: Infinity, + ...options + }; -function checkStat (stat, path, options) { - if (!stat.isSymbolicLink() && !stat.isFile()) { - return false - } - return checkPathExt(path, options) -} + const {maxBuffer} = options; -function isexe (path, options, cb) { - fs.stat(path, function (er, stat) { - cb(er, er ? false : checkStat(stat, path, options)) - }) -} + let stream; + await new Promise((resolve, reject) => { + const rejectPromise = error => { + if (error) { // A null check + error.bufferedData = stream.getBufferedValue(); + } -function sync (path, options) { - return checkStat(fs.statSync(path), path, options) + reject(error); + }; + + stream = pump(inputStream, bufferStream(options), error => { + if (error) { + rejectPromise(error); + return; + } + + resolve(); + }); + + stream.on('data', () => { + if (stream.getBufferedLength() > maxBuffer) { + rejectPromise(new MaxBufferError()); + } + }); + }); + + return stream.getBufferedValue(); } +module.exports = getStream; +// TODO: Remove this for the next major release +module.exports.default = getStream; +module.exports.buffer = (stream, options) => getStream(stream, {...options, encoding: 'buffer'}); +module.exports.array = (stream, options) => getStream(stream, {...options, array: true}); +module.exports.MaxBufferError = MaxBufferError; + /***/ }), -/* 379 */ +/* 377 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = isexe -isexe.sync = sync +var once = __webpack_require__(378) +var eos = __webpack_require__(380) +var fs = __webpack_require__(349) // we only need fs to get the ReadStream and WriteStream prototypes -var fs = __webpack_require__(23) +var noop = function () {} +var ancient = /^v?\.0/.test(process.version) -function isexe (path, options, cb) { - fs.stat(path, function (er, stat) { - cb(er, er ? false : checkStat(stat, options)) - }) +var isFn = function (fn) { + return typeof fn === 'function' } -function sync (path, options) { - return checkStat(fs.statSync(path), options) +var isFS = function (stream) { + if (!ancient) return false // newer node version do not need to care about fs is a special way + if (!fs) return false // browser + return (stream instanceof (fs.ReadStream || noop) || stream instanceof (fs.WriteStream || noop)) && isFn(stream.close) } -function checkStat (stat, options) { - return stat.isFile() && checkMode(stat, options) +var isRequest = function (stream) { + return stream.setHeader && isFn(stream.abort) } -function checkMode (stat, options) { - var mod = stat.mode - var uid = stat.uid - var gid = stat.gid +var destroyer = function (stream, reading, writing, callback) { + callback = once(callback) - var myUid = options.uid !== undefined ? - options.uid : process.getuid && process.getuid() - var myGid = options.gid !== undefined ? - options.gid : process.getgid && process.getgid() + var closed = false + stream.on('close', function () { + closed = true + }) - var u = parseInt('100', 8) - var g = parseInt('010', 8) - var o = parseInt('001', 8) - var ug = u | g + eos(stream, {readable: reading, writable: writing}, function (err) { + if (err) return callback(err) + closed = true + callback() + }) - var ret = (mod & o) || - (mod & g) && gid === myGid || - (mod & u) && uid === myUid || - (mod & ug) && myUid === 0 + var destroyed = false + return function (err) { + if (closed) return + if (destroyed) return + destroyed = true - return ret -} + if (isFS(stream)) return stream.close(noop) // use close for fs streams to avoid fd leaks + if (isRequest(stream)) return stream.abort() // request.destroy just do .end - .abort is what we want + if (isFn(stream.destroy)) return stream.destroy() -/***/ }), -/* 380 */ -/***/ (function(module, exports, __webpack_require__) { + callback(err || new Error('stream was destroyed')) + } +} -"use strict"; +var call = function (fn) { + fn() +} +var pipe = function (from, to) { + return from.pipe(to) +} -const pathKey = (options = {}) => { - const environment = options.env || process.env; - const platform = options.platform || process.platform; +var pump = function () { + var streams = Array.prototype.slice.call(arguments) + var callback = isFn(streams[streams.length - 1] || noop) && streams.pop() || noop - if (platform !== 'win32') { - return 'PATH'; - } + if (Array.isArray(streams[0])) streams = streams[0] + if (streams.length < 2) throw new Error('pump requires two streams per minimum') - return Object.keys(environment).find(key => key.toUpperCase() === 'PATH') || 'Path'; -}; + var error + var destroys = streams.map(function (stream, i) { + var reading = i < streams.length - 1 + var writing = i > 0 + return destroyer(stream, reading, writing, function (err) { + if (!error) error = err + if (err) destroys.forEach(call) + if (reading) return + destroys.forEach(call) + callback(error) + }) + }) -module.exports = pathKey; -// TODO: Remove this for the next major release -module.exports.default = pathKey; + return streams.reduce(pipe) +} + +module.exports = pump /***/ }), -/* 381 */ +/* 378 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - +var wrappy = __webpack_require__(379) +module.exports = wrappy(once) +module.exports.strict = wrappy(onceStrict) -// See http://www.robvanderwoude.com/escapechars.php -const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g; +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) + }, + configurable: true + }) -function escapeCommand(arg) { - // Escape meta chars - arg = arg.replace(metaCharsRegExp, '^$1'); + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this) + }, + configurable: true + }) +}) - return arg; +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) + } + f.called = false + return f } -function escapeArgument(arg, doubleEscapeMetaChars) { - // Convert to string - arg = `${arg}`; +function onceStrict (fn) { + var f = function () { + if (f.called) + throw new Error(f.onceError) + f.called = true + return f.value = fn.apply(this, arguments) + } + var name = fn.name || 'Function wrapped with `once`' + f.onceError = name + " shouldn't be called more than once" + f.called = false + return f +} - // Algorithm below is based on https://qntm.org/cmd - // Sequence of backslashes followed by a double quote: - // double up all the backslashes and escape the double quote - arg = arg.replace(/(\\*)"/g, '$1$1\\"'); +/***/ }), +/* 379 */ +/***/ (function(module, exports) { - // Sequence of backslashes followed by the end of the string - // (which will become a double quote later): - // double up all the backslashes - arg = arg.replace(/(\\*)$/, '$1$1'); +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) - // All other backslashes occur literally + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') - // Quote the whole thing: - arg = `"${arg}"`; + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) - // Escape meta chars - arg = arg.replace(metaCharsRegExp, '^$1'); + return wrapper - // Double escape meta chars if necessary - if (doubleEscapeMetaChars) { - arg = arg.replace(metaCharsRegExp, '^$1'); + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] } - - return arg; + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } } -module.exports.command = escapeCommand; -module.exports.argument = escapeArgument; - /***/ }), -/* 382 */ +/* 380 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var once = __webpack_require__(378); +var noop = function() {}; -const fs = __webpack_require__(23); -const shebangCommand = __webpack_require__(383); +var isRequest = function(stream) { + return stream.setHeader && typeof stream.abort === 'function'; +}; -function readShebang(command) { - // Read the first 150 bytes from the file - const size = 150; - const buffer = Buffer.alloc(size); +var isChildProcess = function(stream) { + return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3 +}; - let fd; +var eos = function(stream, opts, callback) { + if (typeof opts === 'function') return eos(stream, null, opts); + if (!opts) opts = {}; - try { - fd = fs.openSync(command, 'r'); - fs.readSync(fd, buffer, 0, size, 0); - fs.closeSync(fd); - } catch (e) { /* Empty */ } + callback = once(callback || noop); - // Attempt to extract shebang (null is returned if not a shebang) - return shebangCommand(buffer.toString()); -} + var ws = stream._writableState; + var rs = stream._readableState; + var readable = opts.readable || (opts.readable !== false && stream.readable); + var writable = opts.writable || (opts.writable !== false && stream.writable); -module.exports = readShebang; + var onlegacyfinish = function() { + if (!stream.writable) onfinish(); + }; + var onfinish = function() { + writable = false; + if (!readable) callback.call(stream); + }; -/***/ }), -/* 383 */ -/***/ (function(module, exports, __webpack_require__) { + var onend = function() { + readable = false; + if (!writable) callback.call(stream); + }; -"use strict"; + var onexit = function(exitCode) { + callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null); + }; -const shebangRegex = __webpack_require__(384); + var onerror = function(err) { + callback.call(stream, err); + }; -module.exports = (string = '') => { - const match = string.match(shebangRegex); + var onclose = function() { + if (readable && !(rs && rs.ended)) return callback.call(stream, new Error('premature close')); + if (writable && !(ws && ws.ended)) return callback.call(stream, new Error('premature close')); + }; - if (!match) { - return null; + var onrequest = function() { + stream.req.on('finish', onfinish); + }; + + if (isRequest(stream)) { + stream.on('complete', onfinish); + stream.on('abort', onclose); + if (stream.req) onrequest(); + else stream.on('request', onrequest); + } else if (writable && !ws) { // legacy streams + stream.on('end', onlegacyfinish); + stream.on('close', onlegacyfinish); } - const [path, argument] = match[0].replace(/#! ?/, '').split(' '); - const binary = path.split('/').pop(); + if (isChildProcess(stream)) stream.on('exit', onexit); - if (binary === 'env') { - return argument; - } + stream.on('end', onend); + stream.on('finish', onfinish); + if (opts.error !== false) stream.on('error', onerror); + stream.on('close', onclose); - return argument ? `${binary} ${argument}` : binary; + return function() { + stream.removeListener('complete', onfinish); + stream.removeListener('abort', onclose); + stream.removeListener('request', onrequest); + if (stream.req) stream.req.removeListener('finish', onfinish); + stream.removeListener('end', onlegacyfinish); + stream.removeListener('close', onlegacyfinish); + stream.removeListener('finish', onfinish); + stream.removeListener('exit', onexit); + stream.removeListener('end', onend); + stream.removeListener('error', onerror); + stream.removeListener('close', onclose); + }; }; +module.exports = eos; + /***/ }), -/* 384 */ +/* 381 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = /^#!(.*)/; - +const {PassThrough: PassThroughStream} = __webpack_require__(382); -/***/ }), -/* 385 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports = options => { + options = {...options}; -"use strict"; + const {array} = options; + let {encoding} = options; + const isBuffer = encoding === 'buffer'; + let objectMode = false; + if (array) { + objectMode = !(encoding || isBuffer); + } else { + encoding = encoding || 'utf8'; + } -const isWin = process.platform === 'win32'; + if (isBuffer) { + encoding = null; + } -function notFoundError(original, syscall) { - return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), { - code: 'ENOENT', - errno: 'ENOENT', - syscall: `${syscall} ${original.command}`, - path: original.command, - spawnargs: original.args, - }); -} + const stream = new PassThroughStream({objectMode}); -function hookChildProcess(cp, parsed) { - if (!isWin) { - return; - } + if (encoding) { + stream.setEncoding(encoding); + } - const originalEmit = cp.emit; + let length = 0; + const chunks = []; - cp.emit = function (name, arg1) { - // If emitting "exit" event and exit code is 1, we need to check if - // the command exists and emit an "error" instead - // See https://github.com/IndigoUnited/node-cross-spawn/issues/16 - if (name === 'exit') { - const err = verifyENOENT(arg1, parsed, 'spawn'); + stream.on('data', chunk => { + chunks.push(chunk); - if (err) { - return originalEmit.call(cp, 'error', err); - } - } + if (objectMode) { + length = chunks.length; + } else { + length += chunk.length; + } + }); - return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params - }; -} + stream.getBufferedValue = () => { + if (array) { + return chunks; + } -function verifyENOENT(status, parsed) { - if (isWin && status === 1 && !parsed.file) { - return notFoundError(parsed.original, 'spawn'); - } + return isBuffer ? Buffer.concat(chunks, length) : chunks.join(''); + }; - return null; -} + stream.getBufferedLength = () => length; -function verifyENOENTSync(status, parsed) { - if (isWin && status === 1 && !parsed.file) { - return notFoundError(parsed.original, 'spawnSync'); - } + return stream; +}; - return null; -} -module.exports = { - hookChildProcess, - verifyENOENT, - verifyENOENTSync, - notFoundError, -}; +/***/ }), +/* 382 */ +/***/ (function(module, exports) { +module.exports = require("stream"); /***/ }), -/* 386 */ +/* 383 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = input => { - const LF = typeof input === 'string' ? '\n' : '\n'.charCodeAt(); - const CR = typeof input === 'string' ? '\r' : '\r'.charCodeAt(); +const { PassThrough } = __webpack_require__(382); - if (input[input.length - 1] === LF) { - input = input.slice(0, input.length - 1); - } +module.exports = function (/*streams...*/) { + var sources = [] + var output = new PassThrough({objectMode: true}) - if (input[input.length - 1] === CR) { - input = input.slice(0, input.length - 1); - } + output.setMaxListeners(0) - return input; -}; + output.add = add + output.isEmpty = isEmpty + + output.on('unpipe', remove) + + Array.prototype.slice.call(arguments).forEach(add) + + return output + + function add (source) { + if (Array.isArray(source)) { + source.forEach(add) + return this + } + + sources.push(source); + source.once('end', remove.bind(null, source)) + source.once('error', output.emit.bind(output, 'error')) + source.pipe(output, {end: false}) + return this + } + + function isEmpty () { + return sources.length == 0; + } + + function remove (source) { + sources = sources.filter(function (it) { return it !== source }) + if (!sources.length && output.readable) { output.end() } + } +} /***/ }), -/* 387 */ +/* 384 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const path = __webpack_require__(16); -const pathKey = __webpack_require__(380); -const npmRunPath = options => { - options = { - cwd: process.cwd(), - path: process.env[pathKey()], - execPath: process.execPath, - ...options - }; +const nativePromisePrototype = (async () => {})().constructor.prototype; +const descriptors = ['then', 'catch', 'finally'].map(property => [ + property, + Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property) +]); - let previous; - let cwdPath = path.resolve(options.cwd); - const result = []; +// The return value is a mixin of `childProcess` and `Promise` +const mergePromise = (spawned, promise) => { + for (const [property, descriptor] of descriptors) { + // Starting the main `promise` is deferred to avoid consuming streams + const value = typeof promise === 'function' ? + (...args) => Reflect.apply(descriptor.value, promise(), args) : + descriptor.value.bind(promise); - while (previous !== cwdPath) { - result.push(path.join(cwdPath, 'node_modules/.bin')); - previous = cwdPath; - cwdPath = path.resolve(cwdPath, '..'); + Reflect.defineProperty(spawned, property, {...descriptor, value}); } - // Ensure the running `node` binary is used - const execPathDir = path.resolve(options.cwd, options.execPath, '..'); - result.unshift(execPathDir); - - return result.concat(options.path).join(path.delimiter); + return spawned; }; -module.exports = npmRunPath; -// TODO: Remove this for the next major release -module.exports.default = npmRunPath; - -module.exports.env = options => { - options = { - env: process.env, - ...options - }; +// Use promises instead of `child_process` events +const getSpawnedPromise = spawned => { + return new Promise((resolve, reject) => { + spawned.on('exit', (exitCode, signal) => { + resolve({exitCode, signal}); + }); - const env = {...options.env}; - const path = pathKey({env}); + spawned.on('error', error => { + reject(error); + }); - options.path = env[path]; - env[path] = module.exports(options); + if (spawned.stdin) { + spawned.stdin.on('error', error => { + reject(error); + }); + } + }); +}; - return env; +module.exports = { + mergePromise, + getSpawnedPromise }; + /***/ }), -/* 388 */ +/* 385 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const mimicFn = __webpack_require__(389); - -const calledFunctions = new WeakMap(); +const SPACES_REGEXP = / +/g; -const oneTime = (fn, options = {}) => { - if (typeof fn !== 'function') { - throw new TypeError('Expected a function'); +const joinCommand = (file, args = []) => { + if (!Array.isArray(args)) { + return file; } - let ret; - let isCalled = false; - let callCount = 0; - const functionName = fn.displayName || fn.name || ''; - - const onetime = function (...args) { - calledFunctions.set(onetime, ++callCount); - - if (isCalled) { - if (options.throw === true) { - throw new Error(`Function \`${functionName}\` can only be called once`); - } - - return ret; - } + return [file, ...args].join(' '); +}; - isCalled = true; - ret = fn.apply(this, args); - fn = null; +// Allow spaces to be escaped by a backslash if not meant as a delimiter +const handleEscaping = (tokens, token, index) => { + if (index === 0) { + return [token]; + } - return ret; - }; + const previousToken = tokens[tokens.length - 1]; - mimicFn(onetime, fn); - calledFunctions.set(onetime, callCount); + if (previousToken.endsWith('\\')) { + return [...tokens.slice(0, -1), `${previousToken.slice(0, -1)} ${token}`]; + } - return onetime; + return [...tokens, token]; }; -module.exports = oneTime; -// TODO: Remove this for the next major release -module.exports.default = oneTime; - -module.exports.callCount = fn => { - if (!calledFunctions.has(fn)) { - throw new Error(`The given function \`${fn.name}\` is not wrapped by the \`onetime\` package`); - } +// Handle `execa.command()` +const parseCommand = command => { + return command + .trim() + .split(SPACES_REGEXP) + .reduce(handleEscaping, []); +}; - return calledFunctions.get(fn); +module.exports = { + joinCommand, + parseCommand }; /***/ }), -/* 389 */ +/* 386 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const escapeStringRegexp = __webpack_require__(387); +const ansiStyles = __webpack_require__(388); +const stdoutColor = __webpack_require__(393).stdout; -const mimicFn = (to, from) => { - for (const prop of Reflect.ownKeys(from)) { - Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop)); - } +const template = __webpack_require__(395); - return to; -}; +const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); -module.exports = mimicFn; -// TODO: Remove this for the next major release -module.exports.default = mimicFn; +// `supportsColor.level` → `ansiStyles.color[name]` mapping +const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; +// `color-convert` models to exclude from the Chalk API due to conflicts and such +const skipModels = new Set(['gray']); -/***/ }), -/* 390 */ -/***/ (function(module, exports, __webpack_require__) { +const styles = Object.create(null); -"use strict"; +function applyOptions(obj, options) { + options = options || {}; -const {signalsByName} = __webpack_require__(391); + // Detect level if not set manually + const scLevel = stdoutColor ? stdoutColor.level : 0; + obj.level = options.level === undefined ? scLevel : options.level; + obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; +} -const getErrorPrefix = ({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}) => { - if (timedOut) { - return `timed out after ${timeout} milliseconds`; - } +function Chalk(options) { + // We check for this.template here since calling `chalk.constructor()` + // by itself will have a `this` of a previously constructed chalk object + if (!this || !(this instanceof Chalk) || this.template) { + const chalk = {}; + applyOptions(chalk, options); - if (isCanceled) { - return 'was canceled'; - } + chalk.template = function () { + const args = [].slice.call(arguments); + return chalkTag.apply(null, [chalk.template].concat(args)); + }; - if (errorCode !== undefined) { - return `failed with ${errorCode}`; - } + Object.setPrototypeOf(chalk, Chalk.prototype); + Object.setPrototypeOf(chalk.template, chalk); - if (signal !== undefined) { - return `was killed with ${signal} (${signalDescription})`; - } + chalk.template.constructor = Chalk; - if (exitCode !== undefined) { - return `failed with exit code ${exitCode}`; + return chalk.template; } - return 'failed'; -}; + applyOptions(this, options); +} -const makeError = ({ - stdout, - stderr, - all, - error, - signal, - exitCode, - command, - timedOut, - isCanceled, - killed, - parsed: {options: {timeout}} -}) => { - // `signal` and `exitCode` emitted on `spawned.on('exit')` event can be `null`. - // We normalize them to `undefined` - exitCode = exitCode === null ? undefined : exitCode; - signal = signal === null ? undefined : signal; - const signalDescription = signal === undefined ? undefined : signalsByName[signal].description; +// Use bright blue on Windows as the normal blue color is illegible +if (isSimpleWindowsTerm) { + ansiStyles.blue.open = '\u001B[94m'; +} - const errorCode = error && error.code; +for (const key of Object.keys(ansiStyles)) { + ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); - const prefix = getErrorPrefix({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}); - const execaMessage = `Command ${prefix}: ${command}`; - const isError = Object.prototype.toString.call(error) === '[object Error]'; - const shortMessage = isError ? `${execaMessage}\n${error.message}` : execaMessage; - const message = [shortMessage, stderr, stdout].filter(Boolean).join('\n'); + styles[key] = { + get() { + const codes = ansiStyles[key]; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); + } + }; +} - if (isError) { - error.originalMessage = error.message; - error.message = message; - } else { - error = new Error(message); +styles.visible = { + get() { + return build.call(this, this._styles || [], true, 'visible'); } +}; - error.shortMessage = shortMessage; - error.command = command; - error.exitCode = exitCode; - error.signal = signal; - error.signalDescription = signalDescription; - error.stdout = stdout; - error.stderr = stderr; - - if (all !== undefined) { - error.all = all; +ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); +for (const model of Object.keys(ansiStyles.color.ansi)) { + if (skipModels.has(model)) { + continue; } - if ('bufferedData' in error) { - delete error.bufferedData; - } + styles[model] = { + get() { + const level = this.level; + return function () { + const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); + const codes = { + open, + close: ansiStyles.color.close, + closeRe: ansiStyles.color.closeRe + }; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + }; + } + }; +} - error.failed = true; - error.timedOut = Boolean(timedOut); - error.isCanceled = isCanceled; - error.killed = killed && !timedOut; +ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); +for (const model of Object.keys(ansiStyles.bgColor.ansi)) { + if (skipModels.has(model)) { + continue; + } - return error; -}; + const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); + styles[bgModel] = { + get() { + const level = this.level; + return function () { + const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); + const codes = { + open, + close: ansiStyles.bgColor.close, + closeRe: ansiStyles.bgColor.closeRe + }; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + }; + } + }; +} -module.exports = makeError; +const proto = Object.defineProperties(() => {}, styles); +function build(_styles, _empty, key) { + const builder = function () { + return applyStyle.apply(builder, arguments); + }; -/***/ }), -/* 391 */ -/***/ (function(module, exports, __webpack_require__) { + builder._styles = _styles; + builder._empty = _empty; -"use strict"; -Object.defineProperty(exports,"__esModule",{value:true});exports.signalsByNumber=exports.signalsByName=void 0;var _os=__webpack_require__(11); + const self = this; -var _signals=__webpack_require__(392); -var _realtime=__webpack_require__(394); + Object.defineProperty(builder, 'level', { + enumerable: true, + get() { + return self.level; + }, + set(level) { + self.level = level; + } + }); + Object.defineProperty(builder, 'enabled', { + enumerable: true, + get() { + return self.enabled; + }, + set(enabled) { + self.enabled = enabled; + } + }); + // See below for fix regarding invisible grey/dim combination on Windows + builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; -const getSignalsByName=function(){ -const signals=(0,_signals.getSignals)(); -return signals.reduce(getSignalByName,{}); -}; + // `__proto__` is used because we must return a function, but there is + // no way to create a function with a different prototype + builder.__proto__ = proto; // eslint-disable-line no-proto -const getSignalByName=function( -signalByNameMemo, -{name,number,description,supported,action,forced,standard}) -{ -return{ -...signalByNameMemo, -[name]:{name,number,description,supported,action,forced,standard}}; + return builder; +} -}; +function applyStyle() { + // Support varags, but simply cast to string in case there's only one arg + const args = arguments; + const argsLen = args.length; + let str = String(arguments[0]); -const signalsByName=getSignalsByName();exports.signalsByName=signalsByName; + if (argsLen === 0) { + return ''; + } + if (argsLen > 1) { + // Don't slice `arguments`, it prevents V8 optimizations + for (let a = 1; a < argsLen; a++) { + str += ' ' + args[a]; + } + } + if (!this.enabled || this.level <= 0 || !str) { + return this._empty ? '' : str; + } + // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, + // see https://github.com/chalk/chalk/issues/58 + // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. + const originalDim = ansiStyles.dim.open; + if (isSimpleWindowsTerm && this.hasGrey) { + ansiStyles.dim.open = ''; + } -const getSignalsByNumber=function(){ -const signals=(0,_signals.getSignals)(); -const length=_realtime.SIGRTMAX+1; -const signalsA=Array.from({length},(value,number)=> -getSignalByNumber(number,signals)); + for (const code of this._styles.slice().reverse()) { + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code + // will be colored, and the rest will simply be 'plain'. + str = code.open + str.replace(code.closeRe, code.open) + code.close; -return Object.assign({},...signalsA); -}; + // Close the styling before a linebreak and reopen + // after next line to fix a bleed issue on macOS + // https://github.com/chalk/chalk/pull/92 + str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); + } -const getSignalByNumber=function(number,signals){ -const signal=findSignalByNumber(number,signals); + // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue + ansiStyles.dim.open = originalDim; -if(signal===undefined){ -return{}; + return str; } -const{name,description,supported,action,forced,standard}=signal; -return{ -[number]:{ -name, -number, -description, -supported, -action, -forced, -standard}}; - - -}; - +function chalkTag(chalk, strings) { + if (!Array.isArray(strings)) { + // If chalk() was called by itself or with a string, + // return the string itself as a string. + return [].slice.call(arguments, 1).join(' '); + } + const args = [].slice.call(arguments, 2); + const parts = [strings.raw[0]]; -const findSignalByNumber=function(number,signals){ -const signal=signals.find(({name})=>_os.constants.signals[name]===number); + for (let i = 1; i < strings.length; i++) { + parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); + parts.push(String(strings.raw[i])); + } -if(signal!==undefined){ -return signal; + return template(chalk, parts.join('')); } -return signals.find(signalA=>signalA.number===number); -}; +Object.defineProperties(Chalk.prototype, styles); + +module.exports = Chalk(); // eslint-disable-line new-cap +module.exports.supportsColor = stdoutColor; +module.exports.default = module.exports; // For TypeScript -const signalsByNumber=getSignalsByNumber();exports.signalsByNumber=signalsByNumber; -//# sourceMappingURL=main.js.map /***/ }), -/* 392 */ +/* 387 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -Object.defineProperty(exports,"__esModule",{value:true});exports.getSignals=void 0;var _os=__webpack_require__(11); - -var _core=__webpack_require__(393); -var _realtime=__webpack_require__(394); - -const getSignals=function(){ -const realtimeSignals=(0,_realtime.getRealtimeSignals)(); -const signals=[..._core.SIGNALS,...realtimeSignals].map(normalizeSignal); -return signals; -};exports.getSignals=getSignals; +var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; +module.exports = function (str) { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } + return str.replace(matchOperatorsRe, '\\$&'); +}; - - - -const normalizeSignal=function({ -name, -number:defaultNumber, -description, -action, -forced=false, -standard}) -{ -const{ -signals:{[name]:constantSignal}}= -_os.constants; -const supported=constantSignal!==undefined; -const number=supported?constantSignal:defaultNumber; -return{name,number,description,supported,action,forced,standard}; -}; -//# sourceMappingURL=signals.js.map - /***/ }), -/* 393 */ +/* 388 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -Object.defineProperty(exports,"__esModule",{value:true});exports.SIGNALS=void 0; +/* WEBPACK VAR INJECTION */(function(module) { +const colorConvert = __webpack_require__(389); -const SIGNALS=[ -{ -name:"SIGHUP", -number:1, -action:"terminate", -description:"Terminal closed", -standard:"posix"}, +const wrapAnsi16 = (fn, offset) => function () { + const code = fn.apply(colorConvert, arguments); + return `\u001B[${code + offset}m`; +}; -{ -name:"SIGINT", -number:2, -action:"terminate", -description:"User interruption with CTRL-C", -standard:"ansi"}, +const wrapAnsi256 = (fn, offset) => function () { + const code = fn.apply(colorConvert, arguments); + return `\u001B[${38 + offset};5;${code}m`; +}; -{ -name:"SIGQUIT", -number:3, -action:"core", -description:"User interruption with CTRL-\\", -standard:"posix"}, +const wrapAnsi16m = (fn, offset) => function () { + const rgb = fn.apply(colorConvert, arguments); + return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; +}; -{ -name:"SIGILL", -number:4, -action:"core", -description:"Invalid machine instruction", -standard:"ansi"}, +function assembleStyles() { + const codes = new Map(); + const styles = { + modifier: { + reset: [0, 0], + // 21 isn't widely supported and 22 does the same thing + bold: [1, 22], + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29] + }, + color: { + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], + gray: [90, 39], -{ -name:"SIGTRAP", -number:5, -action:"core", -description:"Debugger breakpoint", -standard:"posix"}, + // Bright color + redBright: [91, 39], + greenBright: [92, 39], + yellowBright: [93, 39], + blueBright: [94, 39], + magentaBright: [95, 39], + cyanBright: [96, 39], + whiteBright: [97, 39] + }, + bgColor: { + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], -{ -name:"SIGABRT", -number:6, -action:"core", -description:"Aborted", -standard:"ansi"}, + // Bright color + bgBlackBright: [100, 49], + bgRedBright: [101, 49], + bgGreenBright: [102, 49], + bgYellowBright: [103, 49], + bgBlueBright: [104, 49], + bgMagentaBright: [105, 49], + bgCyanBright: [106, 49], + bgWhiteBright: [107, 49] + } + }; -{ -name:"SIGIOT", -number:6, -action:"core", -description:"Aborted", -standard:"bsd"}, + // Fix humans + styles.color.grey = styles.color.gray; -{ -name:"SIGBUS", -number:7, -action:"core", -description: -"Bus error due to misaligned, non-existing address or paging error", -standard:"bsd"}, + for (const groupName of Object.keys(styles)) { + const group = styles[groupName]; -{ -name:"SIGEMT", -number:7, -action:"terminate", -description:"Command should be emulated but is not implemented", -standard:"other"}, + for (const styleName of Object.keys(group)) { + const style = group[styleName]; -{ -name:"SIGFPE", -number:8, -action:"core", -description:"Floating point arithmetic error", -standard:"ansi"}, + styles[styleName] = { + open: `\u001B[${style[0]}m`, + close: `\u001B[${style[1]}m` + }; -{ -name:"SIGKILL", -number:9, -action:"terminate", -description:"Forced termination", -standard:"posix", -forced:true}, + group[styleName] = styles[styleName]; -{ -name:"SIGUSR1", -number:10, -action:"terminate", -description:"Application-specific signal", -standard:"posix"}, + codes.set(style[0], style[1]); + } -{ -name:"SIGSEGV", -number:11, -action:"core", -description:"Segmentation fault", -standard:"ansi"}, + Object.defineProperty(styles, groupName, { + value: group, + enumerable: false + }); -{ -name:"SIGUSR2", -number:12, -action:"terminate", -description:"Application-specific signal", -standard:"posix"}, + Object.defineProperty(styles, 'codes', { + value: codes, + enumerable: false + }); + } -{ -name:"SIGPIPE", -number:13, -action:"terminate", -description:"Broken pipe or socket", -standard:"posix"}, + const ansi2ansi = n => n; + const rgb2rgb = (r, g, b) => [r, g, b]; -{ -name:"SIGALRM", -number:14, -action:"terminate", -description:"Timeout or timer", -standard:"posix"}, + styles.color.close = '\u001B[39m'; + styles.bgColor.close = '\u001B[49m'; -{ -name:"SIGTERM", -number:15, -action:"terminate", -description:"Termination", -standard:"ansi"}, + styles.color.ansi = { + ansi: wrapAnsi16(ansi2ansi, 0) + }; + styles.color.ansi256 = { + ansi256: wrapAnsi256(ansi2ansi, 0) + }; + styles.color.ansi16m = { + rgb: wrapAnsi16m(rgb2rgb, 0) + }; -{ -name:"SIGSTKFLT", -number:16, -action:"terminate", -description:"Stack is empty or overflowed", -standard:"other"}, + styles.bgColor.ansi = { + ansi: wrapAnsi16(ansi2ansi, 10) + }; + styles.bgColor.ansi256 = { + ansi256: wrapAnsi256(ansi2ansi, 10) + }; + styles.bgColor.ansi16m = { + rgb: wrapAnsi16m(rgb2rgb, 10) + }; -{ -name:"SIGCHLD", -number:17, -action:"ignore", -description:"Child process terminated, paused or unpaused", -standard:"posix"}, + for (let key of Object.keys(colorConvert)) { + if (typeof colorConvert[key] !== 'object') { + continue; + } -{ -name:"SIGCLD", -number:17, -action:"ignore", -description:"Child process terminated, paused or unpaused", -standard:"other"}, + const suite = colorConvert[key]; -{ -name:"SIGCONT", -number:18, -action:"unpause", -description:"Unpaused", -standard:"posix", -forced:true}, + if (key === 'ansi16') { + key = 'ansi'; + } -{ -name:"SIGSTOP", -number:19, -action:"pause", -description:"Paused", -standard:"posix", -forced:true}, + if ('ansi16' in suite) { + styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); + styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); + } -{ -name:"SIGTSTP", -number:20, -action:"pause", -description:"Paused using CTRL-Z or \"suspend\"", -standard:"posix"}, + if ('ansi256' in suite) { + styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); + styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); + } -{ -name:"SIGTTIN", -number:21, -action:"pause", -description:"Background process cannot read terminal input", -standard:"posix"}, + if ('rgb' in suite) { + styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); + styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); + } + } -{ -name:"SIGBREAK", -number:21, -action:"terminate", -description:"User interruption with CTRL-BREAK", -standard:"other"}, + return styles; +} -{ -name:"SIGTTOU", -number:22, -action:"pause", -description:"Background process cannot write to terminal output", -standard:"posix"}, +// Make the export immutable +Object.defineProperty(module, 'exports', { + enumerable: true, + get: assembleStyles +}); -{ -name:"SIGURG", -number:23, -action:"ignore", -description:"Socket received out-of-band data", -standard:"bsd"}, +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(11)(module))) -{ -name:"SIGXCPU", -number:24, -action:"core", -description:"Process timed out", -standard:"bsd"}, +/***/ }), +/* 389 */ +/***/ (function(module, exports, __webpack_require__) { -{ -name:"SIGXFSZ", -number:25, -action:"core", -description:"File too big", -standard:"bsd"}, +var conversions = __webpack_require__(390); +var route = __webpack_require__(392); -{ -name:"SIGVTALRM", -number:26, -action:"terminate", -description:"Timeout or timer", -standard:"bsd"}, +var convert = {}; -{ -name:"SIGPROF", -number:27, -action:"terminate", -description:"Timeout or timer", -standard:"bsd"}, +var models = Object.keys(conversions); -{ -name:"SIGWINCH", -number:28, -action:"ignore", -description:"Terminal window size changed", -standard:"bsd"}, +function wrapRaw(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; + } -{ -name:"SIGIO", -number:29, -action:"terminate", -description:"I/O is available", -standard:"other"}, + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); + } -{ -name:"SIGPOLL", -number:29, -action:"terminate", -description:"Watched event", -standard:"other"}, + return fn(args); + }; -{ -name:"SIGINFO", -number:29, -action:"ignore", -description:"Request for process information", -standard:"other"}, + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } -{ -name:"SIGPWR", -number:30, -action:"terminate", -description:"Device running out of power", -standard:"systemv"}, + return wrappedFn; +} -{ -name:"SIGSYS", -number:31, -action:"core", -description:"Invalid system call", -standard:"other"}, +function wrapRounded(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; + } -{ -name:"SIGUNUSED", -number:31, -action:"terminate", -description:"Invalid system call", -standard:"other"}];exports.SIGNALS=SIGNALS; -//# sourceMappingURL=core.js.map + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); + } -/***/ }), -/* 394 */ -/***/ (function(module, exports, __webpack_require__) { + var result = fn(args); -"use strict"; -Object.defineProperty(exports,"__esModule",{value:true});exports.SIGRTMAX=exports.getRealtimeSignals=void 0; -const getRealtimeSignals=function(){ -const length=SIGRTMAX-SIGRTMIN+1; -return Array.from({length},getRealtimeSignal); -};exports.getRealtimeSignals=getRealtimeSignals; + // we're assuming the result is an array here. + // see notice in conversions.js; don't use box types + // in conversion functions. + if (typeof result === 'object') { + for (var len = result.length, i = 0; i < len; i++) { + result[i] = Math.round(result[i]); + } + } -const getRealtimeSignal=function(value,index){ -return{ -name:`SIGRT${index+1}`, -number:SIGRTMIN+index, -action:"terminate", -description:"Application-specific signal (realtime)", -standard:"posix"}; + return result; + }; -}; + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } -const SIGRTMIN=34; -const SIGRTMAX=64;exports.SIGRTMAX=SIGRTMAX; -//# sourceMappingURL=realtime.js.map + return wrappedFn; +} -/***/ }), -/* 395 */ -/***/ (function(module, exports, __webpack_require__) { +models.forEach(function (fromModel) { + convert[fromModel] = {}; -"use strict"; + Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); + Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); -const aliases = ['stdin', 'stdout', 'stderr']; + var routes = route(fromModel); + var routeModels = Object.keys(routes); -const hasAlias = opts => aliases.some(alias => opts[alias] !== undefined); + routeModels.forEach(function (toModel) { + var fn = routes[toModel]; -const normalizeStdio = opts => { - if (!opts) { - return; - } + convert[fromModel][toModel] = wrapRounded(fn); + convert[fromModel][toModel].raw = wrapRaw(fn); + }); +}); - const {stdio} = opts; +module.exports = convert; - if (stdio === undefined) { - return aliases.map(alias => opts[alias]); - } - if (hasAlias(opts)) { - throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${aliases.map(alias => `\`${alias}\``).join(', ')}`); - } +/***/ }), +/* 390 */ +/***/ (function(module, exports, __webpack_require__) { - if (typeof stdio === 'string') { - return stdio; - } +/* MIT license */ +var cssKeywords = __webpack_require__(391); - if (!Array.isArray(stdio)) { - throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``); +// NOTE: conversions should only return primitive values (i.e. arrays, or +// values that give correct `typeof` results). +// do not use box values types (i.e. Number(), String(), etc.) + +var reverseKeywords = {}; +for (var key in cssKeywords) { + if (cssKeywords.hasOwnProperty(key)) { + reverseKeywords[cssKeywords[key]] = key; } +} - const length = Math.max(stdio.length, aliases.length); - return Array.from({length}, (value, index) => stdio[index]); -}; +var convert = module.exports = { + rgb: {channels: 3, labels: 'rgb'}, + hsl: {channels: 3, labels: 'hsl'}, + hsv: {channels: 3, labels: 'hsv'}, + hwb: {channels: 3, labels: 'hwb'}, + cmyk: {channels: 4, labels: 'cmyk'}, + xyz: {channels: 3, labels: 'xyz'}, + lab: {channels: 3, labels: 'lab'}, + lch: {channels: 3, labels: 'lch'}, + hex: {channels: 1, labels: ['hex']}, + keyword: {channels: 1, labels: ['keyword']}, + ansi16: {channels: 1, labels: ['ansi16']}, + ansi256: {channels: 1, labels: ['ansi256']}, + hcg: {channels: 3, labels: ['h', 'c', 'g']}, + apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, + gray: {channels: 1, labels: ['gray']} +}; -module.exports = normalizeStdio; +// hide .channels and .labels properties +for (var model in convert) { + if (convert.hasOwnProperty(model)) { + if (!('channels' in convert[model])) { + throw new Error('missing channels property: ' + model); + } -// `ipc` is pushed unless it is already present -module.exports.node = opts => { - const stdio = normalizeStdio(opts); + if (!('labels' in convert[model])) { + throw new Error('missing channel labels property: ' + model); + } - if (stdio === 'ipc') { - return 'ipc'; - } + if (convert[model].labels.length !== convert[model].channels) { + throw new Error('channel and label counts mismatch: ' + model); + } - if (stdio === undefined || typeof stdio === 'string') { - return [stdio, stdio, stdio, 'ipc']; + var channels = convert[model].channels; + var labels = convert[model].labels; + delete convert[model].channels; + delete convert[model].labels; + Object.defineProperty(convert[model], 'channels', {value: channels}); + Object.defineProperty(convert[model], 'labels', {value: labels}); } +} - if (stdio.includes('ipc')) { - return stdio; +convert.rgb.hsl = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var min = Math.min(r, g, b); + var max = Math.max(r, g, b); + var delta = max - min; + var h; + var s; + var l; + + if (max === min) { + h = 0; + } else if (r === max) { + h = (g - b) / delta; + } else if (g === max) { + h = 2 + (b - r) / delta; + } else if (b === max) { + h = 4 + (r - g) / delta; } - return [...stdio, 'ipc']; -}; + h = Math.min(h * 60, 360); + if (h < 0) { + h += 360; + } -/***/ }), -/* 396 */ -/***/ (function(module, exports, __webpack_require__) { + l = (min + max) / 2; -"use strict"; + if (max === min) { + s = 0; + } else if (l <= 0.5) { + s = delta / (max + min); + } else { + s = delta / (2 - max - min); + } -const os = __webpack_require__(11); -const onExit = __webpack_require__(397); + return [h, s * 100, l * 100]; +}; -const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5; +convert.rgb.hsv = function (rgb) { + var r = rgb[0]; + var g = rgb[1]; + var b = rgb[2]; + var min = Math.min(r, g, b); + var max = Math.max(r, g, b); + var delta = max - min; + var h; + var s; + var v; -// Monkey-patches `childProcess.kill()` to add `forceKillAfterTimeout` behavior -const spawnedKill = (kill, signal = 'SIGTERM', options = {}) => { - const killResult = kill(signal); - setKillTimeout(kill, signal, options, killResult); - return killResult; -}; + if (max === 0) { + s = 0; + } else { + s = (delta / max * 1000) / 10; + } -const setKillTimeout = (kill, signal, options, killResult) => { - if (!shouldForceKill(signal, options, killResult)) { - return; + if (max === min) { + h = 0; + } else if (r === max) { + h = (g - b) / delta; + } else if (g === max) { + h = 2 + (b - r) / delta; + } else if (b === max) { + h = 4 + (r - g) / delta; } - const timeout = getForceKillAfterTimeout(options); - const t = setTimeout(() => { - kill('SIGKILL'); - }, timeout); + h = Math.min(h * 60, 360); - // Guarded because there's no `.unref()` when `execa` is used in the renderer - // process in Electron. This cannot be tested since we don't run tests in - // Electron. - // istanbul ignore else - if (t.unref) { - t.unref(); + if (h < 0) { + h += 360; } -}; -const shouldForceKill = (signal, {forceKillAfterTimeout}, killResult) => { - return isSigterm(signal) && forceKillAfterTimeout !== false && killResult; -}; + v = ((max / 255) * 1000) / 10; -const isSigterm = signal => { - return signal === os.constants.signals.SIGTERM || - (typeof signal === 'string' && signal.toUpperCase() === 'SIGTERM'); + return [h, s, v]; }; -const getForceKillAfterTimeout = ({forceKillAfterTimeout = true}) => { - if (forceKillAfterTimeout === true) { - return DEFAULT_FORCE_KILL_TIMEOUT; - } +convert.rgb.hwb = function (rgb) { + var r = rgb[0]; + var g = rgb[1]; + var b = rgb[2]; + var h = convert.rgb.hsl(rgb)[0]; + var w = 1 / 255 * Math.min(r, Math.min(g, b)); - if (!Number.isInteger(forceKillAfterTimeout) || forceKillAfterTimeout < 0) { - throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${forceKillAfterTimeout}\` (${typeof forceKillAfterTimeout})`); - } + b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); - return forceKillAfterTimeout; + return [h, w * 100, b * 100]; }; -// `childProcess.cancel()` -const spawnedCancel = (spawned, context) => { - const killResult = spawned.kill(); +convert.rgb.cmyk = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var c; + var m; + var y; + var k; - if (killResult) { - context.isCanceled = true; - } -}; + k = Math.min(1 - r, 1 - g, 1 - b); + c = (1 - r - k) / (1 - k) || 0; + m = (1 - g - k) / (1 - k) || 0; + y = (1 - b - k) / (1 - k) || 0; -const timeoutKill = (spawned, signal, reject) => { - spawned.kill(signal); - reject(Object.assign(new Error('Timed out'), {timedOut: true, signal})); + return [c * 100, m * 100, y * 100, k * 100]; }; -// `timeout` option handling -const setupTimeout = (spawned, {timeout, killSignal = 'SIGTERM'}, spawnedPromise) => { - if (timeout === 0 || timeout === undefined) { - return spawnedPromise; - } +/** + * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance + * */ +function comparativeDistance(x, y) { + return ( + Math.pow(x[0] - y[0], 2) + + Math.pow(x[1] - y[1], 2) + + Math.pow(x[2] - y[2], 2) + ); +} - if (!Number.isInteger(timeout) || timeout < 0) { - throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`); +convert.rgb.keyword = function (rgb) { + var reversed = reverseKeywords[rgb]; + if (reversed) { + return reversed; } - let timeoutId; - const timeoutPromise = new Promise((resolve, reject) => { - timeoutId = setTimeout(() => { - timeoutKill(spawned, killSignal, reject); - }, timeout); - }); + var currentClosestDistance = Infinity; + var currentClosestKeyword; - const safeSpawnedPromise = spawnedPromise.finally(() => { - clearTimeout(timeoutId); - }); + for (var keyword in cssKeywords) { + if (cssKeywords.hasOwnProperty(keyword)) { + var value = cssKeywords[keyword]; - return Promise.race([timeoutPromise, safeSpawnedPromise]); -}; + // Compute comparative distance + var distance = comparativeDistance(rgb, value); -// `cleanup` option handling -const setExitHandler = async (spawned, {cleanup, detached}, timedPromise) => { - if (!cleanup || detached) { - return timedPromise; + // Check if its less, if so set as closest + if (distance < currentClosestDistance) { + currentClosestDistance = distance; + currentClosestKeyword = keyword; + } + } } - const removeExitHandler = onExit(() => { - spawned.kill(); - }); - - return timedPromise.finally(() => { - removeExitHandler(); - }); + return currentClosestKeyword; }; -module.exports = { - spawnedKill, - spawnedCancel, - setupTimeout, - setExitHandler +convert.keyword.rgb = function (keyword) { + return cssKeywords[keyword]; }; +convert.rgb.xyz = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; -/***/ }), -/* 397 */ -/***/ (function(module, exports, __webpack_require__) { + // assume sRGB + r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); + g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); + b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); -// Note: since nyc uses this module to output coverage, any lines -// that are in the direct sync flow of nyc's outputCoverage are -// ignored, since we can never get coverage for them. -var assert = __webpack_require__(30) -var signals = __webpack_require__(398) + var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); + var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); + var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); -var EE = __webpack_require__(399) -/* istanbul ignore if */ -if (typeof EE !== 'function') { - EE = EE.EventEmitter -} + return [x * 100, y * 100, z * 100]; +}; -var emitter -if (process.__signal_exit_emitter__) { - emitter = process.__signal_exit_emitter__ -} else { - emitter = process.__signal_exit_emitter__ = new EE() - emitter.count = 0 - emitter.emitted = {} -} +convert.rgb.lab = function (rgb) { + var xyz = convert.rgb.xyz(rgb); + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var b; -// Because this emitter is a global, we have to check to see if a -// previous version of this library failed to enable infinite listeners. -// I know what you're about to say. But literally everything about -// signal-exit is a compromise with evil. Get used to it. -if (!emitter.infinite) { - emitter.setMaxListeners(Infinity) - emitter.infinite = true -} + x /= 95.047; + y /= 100; + z /= 108.883; -module.exports = function (cb, opts) { - assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler') + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); - if (loaded === false) { - load() - } + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); - var ev = 'exit' - if (opts && opts.alwaysLast) { - ev = 'afterexit' - } + return [l, a, b]; +}; - var remove = function () { - emitter.removeListener(ev, cb) - if (emitter.listeners('exit').length === 0 && - emitter.listeners('afterexit').length === 0) { - unload() - } - } - emitter.on(ev, cb) +convert.hsl.rgb = function (hsl) { + var h = hsl[0] / 360; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var t1; + var t2; + var t3; + var rgb; + var val; - return remove -} + if (s === 0) { + val = l * 255; + return [val, val, val]; + } -module.exports.unload = unload -function unload () { - if (!loaded) { - return - } - loaded = false + if (l < 0.5) { + t2 = l * (1 + s); + } else { + t2 = l + s - l * s; + } - signals.forEach(function (sig) { - try { - process.removeListener(sig, sigListeners[sig]) - } catch (er) {} - }) - process.emit = originalProcessEmit - process.reallyExit = originalProcessReallyExit - emitter.count -= 1 -} + t1 = 2 * l - t2; -function emit (event, code, signal) { - if (emitter.emitted[event]) { - return - } - emitter.emitted[event] = true - emitter.emit(event, code, signal) -} + rgb = [0, 0, 0]; + for (var i = 0; i < 3; i++) { + t3 = h + 1 / 3 * -(i - 1); + if (t3 < 0) { + t3++; + } + if (t3 > 1) { + t3--; + } -// { : , ... } -var sigListeners = {} -signals.forEach(function (sig) { - sigListeners[sig] = function listener () { - // If there are no other listeners, an exit is coming! - // Simplest way: remove us and then re-send the signal. - // We know that this will kill the process, so we can - // safely emit now. - var listeners = process.listeners(sig) - if (listeners.length === emitter.count) { - unload() - emit('exit', null, sig) - /* istanbul ignore next */ - emit('afterexit', null, sig) - /* istanbul ignore next */ - process.kill(process.pid, sig) - } - } -}) + if (6 * t3 < 1) { + val = t1 + (t2 - t1) * 6 * t3; + } else if (2 * t3 < 1) { + val = t2; + } else if (3 * t3 < 2) { + val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; + } else { + val = t1; + } -module.exports.signals = function () { - return signals -} + rgb[i] = val * 255; + } -module.exports.load = load + return rgb; +}; -var loaded = false +convert.hsl.hsv = function (hsl) { + var h = hsl[0]; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var smin = s; + var lmin = Math.max(l, 0.01); + var sv; + var v; -function load () { - if (loaded) { - return - } - loaded = true + l *= 2; + s *= (l <= 1) ? l : 2 - l; + smin *= lmin <= 1 ? lmin : 2 - lmin; + v = (l + s) / 2; + sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); - // This is the number of onSignalExit's that are in play. - // It's important so that we can count the correct number of - // listeners on signals, and don't wait for the other one to - // handle it instead of us. - emitter.count += 1 + return [h, sv * 100, v * 100]; +}; - signals = signals.filter(function (sig) { - try { - process.on(sig, sigListeners[sig]) - return true - } catch (er) { - return false - } - }) +convert.hsv.rgb = function (hsv) { + var h = hsv[0] / 60; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var hi = Math.floor(h) % 6; - process.emit = processEmit - process.reallyExit = processReallyExit -} + var f = h - Math.floor(h); + var p = 255 * v * (1 - s); + var q = 255 * v * (1 - (s * f)); + var t = 255 * v * (1 - (s * (1 - f))); + v *= 255; -var originalProcessReallyExit = process.reallyExit -function processReallyExit (code) { - process.exitCode = code || 0 - emit('exit', process.exitCode, null) - /* istanbul ignore next */ - emit('afterexit', process.exitCode, null) - /* istanbul ignore next */ - originalProcessReallyExit.call(process, process.exitCode) -} + switch (hi) { + case 0: + return [v, t, p]; + case 1: + return [q, v, p]; + case 2: + return [p, v, t]; + case 3: + return [p, q, v]; + case 4: + return [t, p, v]; + case 5: + return [v, p, q]; + } +}; -var originalProcessEmit = process.emit -function processEmit (ev, arg) { - if (ev === 'exit') { - if (arg !== undefined) { - process.exitCode = arg - } - var ret = originalProcessEmit.apply(this, arguments) - emit('exit', process.exitCode, null) - /* istanbul ignore next */ - emit('afterexit', process.exitCode, null) - return ret - } else { - return originalProcessEmit.apply(this, arguments) - } -} +convert.hsv.hsl = function (hsv) { + var h = hsv[0]; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var vmin = Math.max(v, 0.01); + var lmin; + var sl; + var l; + l = (2 - s) * v; + lmin = (2 - s) * vmin; + sl = s * vmin; + sl /= (lmin <= 1) ? lmin : 2 - lmin; + sl = sl || 0; + l /= 2; -/***/ }), -/* 398 */ -/***/ (function(module, exports) { + return [h, sl * 100, l * 100]; +}; -// This is not the set of all possible signals. -// -// It IS, however, the set of all signals that trigger -// an exit on either Linux or BSD systems. Linux is a -// superset of the signal names supported on BSD, and -// the unknown signals just fail to register, so we can -// catch that easily enough. -// -// Don't bother with SIGKILL. It's uncatchable, which -// means that we can't fire any callbacks anyway. -// -// If a user does happen to register a handler on a non- -// fatal signal like SIGWINCH or something, and then -// exit, it'll end up firing `process.emit('exit')`, so -// the handler will be fired anyway. -// -// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised -// artificially, inherently leave the process in a -// state from which it is not safe to try and enter JS -// listeners. -module.exports = [ - 'SIGABRT', - 'SIGALRM', - 'SIGHUP', - 'SIGINT', - 'SIGTERM' -] - -if (process.platform !== 'win32') { - module.exports.push( - 'SIGVTALRM', - 'SIGXCPU', - 'SIGXFSZ', - 'SIGUSR2', - 'SIGTRAP', - 'SIGSYS', - 'SIGQUIT', - 'SIGIOT' - // should detect profiler and enable/disable accordingly. - // see #21 - // 'SIGPROF' - ) -} - -if (process.platform === 'linux') { - module.exports.push( - 'SIGIO', - 'SIGPOLL', - 'SIGPWR', - 'SIGSTKFLT', - 'SIGUNUSED' - ) -} - - -/***/ }), -/* 399 */ -/***/ (function(module, exports) { - -module.exports = require("events"); - -/***/ }), -/* 400 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const isStream = __webpack_require__(401); -const getStream = __webpack_require__(402); -const mergeStream = __webpack_require__(408); +// http://dev.w3.org/csswg/css-color/#hwb-to-rgb +convert.hwb.rgb = function (hwb) { + var h = hwb[0] / 360; + var wh = hwb[1] / 100; + var bl = hwb[2] / 100; + var ratio = wh + bl; + var i; + var v; + var f; + var n; -// `input` option -const handleInput = (spawned, input) => { - // Checking for stdin is workaround for https://github.com/nodejs/node/issues/26852 - // TODO: Remove `|| spawned.stdin === undefined` once we drop support for Node.js <=12.2.0 - if (input === undefined || spawned.stdin === undefined) { - return; + // wh + bl cant be > 1 + if (ratio > 1) { + wh /= ratio; + bl /= ratio; } - if (isStream(input)) { - input.pipe(spawned.stdin); - } else { - spawned.stdin.end(input); - } -}; + i = Math.floor(6 * h); + v = 1 - bl; + f = 6 * h - i; -// `all` interleaves `stdout` and `stderr` -const makeAllStream = (spawned, {all}) => { - if (!all || (!spawned.stdout && !spawned.stderr)) { - return; + if ((i & 0x01) !== 0) { + f = 1 - f; } - const mixed = mergeStream(); - - if (spawned.stdout) { - mixed.add(spawned.stdout); - } + n = wh + f * (v - wh); // linear interpolation - if (spawned.stderr) { - mixed.add(spawned.stderr); + var r; + var g; + var b; + switch (i) { + default: + case 6: + case 0: r = v; g = n; b = wh; break; + case 1: r = n; g = v; b = wh; break; + case 2: r = wh; g = v; b = n; break; + case 3: r = wh; g = n; b = v; break; + case 4: r = n; g = wh; b = v; break; + case 5: r = v; g = wh; b = n; break; } - return mixed; + return [r * 255, g * 255, b * 255]; }; -// On failure, `result.stdout|stderr|all` should contain the currently buffered stream -const getBufferedData = async (stream, streamPromise) => { - if (!stream) { - return; - } +convert.cmyk.rgb = function (cmyk) { + var c = cmyk[0] / 100; + var m = cmyk[1] / 100; + var y = cmyk[2] / 100; + var k = cmyk[3] / 100; + var r; + var g; + var b; - stream.destroy(); + r = 1 - Math.min(1, c * (1 - k) + k); + g = 1 - Math.min(1, m * (1 - k) + k); + b = 1 - Math.min(1, y * (1 - k) + k); - try { - return await streamPromise; - } catch (error) { - return error.bufferedData; - } + return [r * 255, g * 255, b * 255]; }; -const getStreamPromise = (stream, {encoding, buffer, maxBuffer}) => { - if (!stream || !buffer) { - return; - } +convert.xyz.rgb = function (xyz) { + var x = xyz[0] / 100; + var y = xyz[1] / 100; + var z = xyz[2] / 100; + var r; + var g; + var b; - if (encoding) { - return getStream(stream, {encoding, maxBuffer}); - } + r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); + g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); + b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - return getStream.buffer(stream, {maxBuffer}); -}; + // assume sRGB + r = r > 0.0031308 + ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) + : r * 12.92; -// Retrieve result of child process: exit code, signal, error, streams (stdout/stderr/all) -const getSpawnedResult = async ({stdout, stderr, all}, {encoding, buffer, maxBuffer}, processDone) => { - const stdoutPromise = getStreamPromise(stdout, {encoding, buffer, maxBuffer}); - const stderrPromise = getStreamPromise(stderr, {encoding, buffer, maxBuffer}); - const allPromise = getStreamPromise(all, {encoding, buffer, maxBuffer: maxBuffer * 2}); + g = g > 0.0031308 + ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) + : g * 12.92; - try { - return await Promise.all([processDone, stdoutPromise, stderrPromise, allPromise]); - } catch (error) { - return Promise.all([ - {error, signal: error.signal, timedOut: error.timedOut}, - getBufferedData(stdout, stdoutPromise), - getBufferedData(stderr, stderrPromise), - getBufferedData(all, allPromise) - ]); - } -}; + b = b > 0.0031308 + ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) + : b * 12.92; -const validateInputSync = ({input}) => { - if (isStream(input)) { - throw new TypeError('The `input` option cannot be a stream in sync mode'); - } -}; + r = Math.min(Math.max(0, r), 1); + g = Math.min(Math.max(0, g), 1); + b = Math.min(Math.max(0, b), 1); -module.exports = { - handleInput, - makeAllStream, - getSpawnedResult, - validateInputSync + return [r * 255, g * 255, b * 255]; }; +convert.xyz.lab = function (xyz) { + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var b; + x /= 95.047; + y /= 100; + z /= 108.883; -/***/ }), -/* 401 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -const isStream = stream => - stream !== null && - typeof stream === 'object' && - typeof stream.pipe === 'function'; + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); -isStream.writable = stream => - isStream(stream) && - stream.writable !== false && - typeof stream._write === 'function' && - typeof stream._writableState === 'object'; + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); -isStream.readable = stream => - isStream(stream) && - stream.readable !== false && - typeof stream._read === 'function' && - typeof stream._readableState === 'object'; + return [l, a, b]; +}; -isStream.duplex = stream => - isStream.writable(stream) && - isStream.readable(stream); +convert.lab.xyz = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var x; + var y; + var z; -isStream.transform = stream => - isStream.duplex(stream) && - typeof stream._transform === 'function' && - typeof stream._transformState === 'object'; + y = (l + 16) / 116; + x = a / 500 + y; + z = y - b / 200; -module.exports = isStream; + var y2 = Math.pow(y, 3); + var x2 = Math.pow(x, 3); + var z2 = Math.pow(z, 3); + y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; + x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; + z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; + x *= 95.047; + y *= 100; + z *= 108.883; -/***/ }), -/* 402 */ -/***/ (function(module, exports, __webpack_require__) { + return [x, y, z]; +}; -"use strict"; +convert.lab.lch = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var hr; + var h; + var c; -const pump = __webpack_require__(403); -const bufferStream = __webpack_require__(407); + hr = Math.atan2(b, a); + h = hr * 360 / 2 / Math.PI; -class MaxBufferError extends Error { - constructor() { - super('maxBuffer exceeded'); - this.name = 'MaxBufferError'; + if (h < 0) { + h += 360; } -} -async function getStream(inputStream, options) { - if (!inputStream) { - return Promise.reject(new Error('Expected a stream')); - } + c = Math.sqrt(a * a + b * b); - options = { - maxBuffer: Infinity, - ...options - }; + return [l, c, h]; +}; - const {maxBuffer} = options; +convert.lch.lab = function (lch) { + var l = lch[0]; + var c = lch[1]; + var h = lch[2]; + var a; + var b; + var hr; - let stream; - await new Promise((resolve, reject) => { - const rejectPromise = error => { - if (error) { // A null check - error.bufferedData = stream.getBufferedValue(); - } + hr = h / 360 * 2 * Math.PI; + a = c * Math.cos(hr); + b = c * Math.sin(hr); - reject(error); - }; + return [l, a, b]; +}; - stream = pump(inputStream, bufferStream(options), error => { - if (error) { - rejectPromise(error); - return; - } +convert.rgb.ansi16 = function (args) { + var r = args[0]; + var g = args[1]; + var b = args[2]; + var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization - resolve(); - }); + value = Math.round(value / 50); - stream.on('data', () => { - if (stream.getBufferedLength() > maxBuffer) { - rejectPromise(new MaxBufferError()); - } - }); - }); + if (value === 0) { + return 30; + } - return stream.getBufferedValue(); -} + var ansi = 30 + + ((Math.round(b / 255) << 2) + | (Math.round(g / 255) << 1) + | Math.round(r / 255)); -module.exports = getStream; -// TODO: Remove this for the next major release -module.exports.default = getStream; -module.exports.buffer = (stream, options) => getStream(stream, {...options, encoding: 'buffer'}); -module.exports.array = (stream, options) => getStream(stream, {...options, array: true}); -module.exports.MaxBufferError = MaxBufferError; + if (value === 2) { + ansi += 60; + } + return ansi; +}; -/***/ }), -/* 403 */ -/***/ (function(module, exports, __webpack_require__) { +convert.hsv.ansi16 = function (args) { + // optimization here; we already know the value and don't need to get + // it converted for us. + return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); +}; -var once = __webpack_require__(404) -var eos = __webpack_require__(406) -var fs = __webpack_require__(23) // we only need fs to get the ReadStream and WriteStream prototypes +convert.rgb.ansi256 = function (args) { + var r = args[0]; + var g = args[1]; + var b = args[2]; -var noop = function () {} -var ancient = /^v?\.0/.test(process.version) + // we use the extended greyscale palette here, with the exception of + // black and white. normal palette only has 4 greyscale shades. + if (r === g && g === b) { + if (r < 8) { + return 16; + } -var isFn = function (fn) { - return typeof fn === 'function' -} + if (r > 248) { + return 231; + } -var isFS = function (stream) { - if (!ancient) return false // newer node version do not need to care about fs is a special way - if (!fs) return false // browser - return (stream instanceof (fs.ReadStream || noop) || stream instanceof (fs.WriteStream || noop)) && isFn(stream.close) -} + return Math.round(((r - 8) / 247) * 24) + 232; + } -var isRequest = function (stream) { - return stream.setHeader && isFn(stream.abort) -} + var ansi = 16 + + (36 * Math.round(r / 255 * 5)) + + (6 * Math.round(g / 255 * 5)) + + Math.round(b / 255 * 5); -var destroyer = function (stream, reading, writing, callback) { - callback = once(callback) + return ansi; +}; - var closed = false - stream.on('close', function () { - closed = true - }) +convert.ansi16.rgb = function (args) { + var color = args % 10; - eos(stream, {readable: reading, writable: writing}, function (err) { - if (err) return callback(err) - closed = true - callback() - }) + // handle greyscale + if (color === 0 || color === 7) { + if (args > 50) { + color += 3.5; + } - var destroyed = false - return function (err) { - if (closed) return - if (destroyed) return - destroyed = true + color = color / 10.5 * 255; - if (isFS(stream)) return stream.close(noop) // use close for fs streams to avoid fd leaks - if (isRequest(stream)) return stream.abort() // request.destroy just do .end - .abort is what we want + return [color, color, color]; + } - if (isFn(stream.destroy)) return stream.destroy() + var mult = (~~(args > 50) + 1) * 0.5; + var r = ((color & 1) * mult) * 255; + var g = (((color >> 1) & 1) * mult) * 255; + var b = (((color >> 2) & 1) * mult) * 255; - callback(err || new Error('stream was destroyed')) - } -} + return [r, g, b]; +}; -var call = function (fn) { - fn() -} +convert.ansi256.rgb = function (args) { + // handle greyscale + if (args >= 232) { + var c = (args - 232) * 10 + 8; + return [c, c, c]; + } -var pipe = function (from, to) { - return from.pipe(to) -} + args -= 16; -var pump = function () { - var streams = Array.prototype.slice.call(arguments) - var callback = isFn(streams[streams.length - 1] || noop) && streams.pop() || noop + var rem; + var r = Math.floor(args / 36) / 5 * 255; + var g = Math.floor((rem = args % 36) / 6) / 5 * 255; + var b = (rem % 6) / 5 * 255; - if (Array.isArray(streams[0])) streams = streams[0] - if (streams.length < 2) throw new Error('pump requires two streams per minimum') + return [r, g, b]; +}; - var error - var destroys = streams.map(function (stream, i) { - var reading = i < streams.length - 1 - var writing = i > 0 - return destroyer(stream, reading, writing, function (err) { - if (!error) error = err - if (err) destroys.forEach(call) - if (reading) return - destroys.forEach(call) - callback(error) - }) - }) +convert.rgb.hex = function (args) { + var integer = ((Math.round(args[0]) & 0xFF) << 16) + + ((Math.round(args[1]) & 0xFF) << 8) + + (Math.round(args[2]) & 0xFF); - return streams.reduce(pipe) -} + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; -module.exports = pump +convert.hex.rgb = function (args) { + var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); + if (!match) { + return [0, 0, 0]; + } + var colorString = match[0]; -/***/ }), -/* 404 */ -/***/ (function(module, exports, __webpack_require__) { + if (match[0].length === 3) { + colorString = colorString.split('').map(function (char) { + return char + char; + }).join(''); + } -var wrappy = __webpack_require__(405) -module.exports = wrappy(once) -module.exports.strict = wrappy(onceStrict) + var integer = parseInt(colorString, 16); + var r = (integer >> 16) & 0xFF; + var g = (integer >> 8) & 0xFF; + var b = integer & 0xFF; -once.proto = once(function () { - Object.defineProperty(Function.prototype, 'once', { - value: function () { - return once(this) - }, - configurable: true - }) - - Object.defineProperty(Function.prototype, 'onceStrict', { - value: function () { - return onceStrict(this) - }, - configurable: true - }) -}) - -function once (fn) { - var f = function () { - if (f.called) return f.value - f.called = true - return f.value = fn.apply(this, arguments) - } - f.called = false - return f -} - -function onceStrict (fn) { - var f = function () { - if (f.called) - throw new Error(f.onceError) - f.called = true - return f.value = fn.apply(this, arguments) - } - var name = fn.name || 'Function wrapped with `once`' - f.onceError = name + " shouldn't be called more than once" - f.called = false - return f -} - - -/***/ }), -/* 405 */ -/***/ (function(module, exports) { - -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) - - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) - } - return ret - } -} - - -/***/ }), -/* 406 */ -/***/ (function(module, exports, __webpack_require__) { - -var once = __webpack_require__(404); - -var noop = function() {}; - -var isRequest = function(stream) { - return stream.setHeader && typeof stream.abort === 'function'; -}; - -var isChildProcess = function(stream) { - return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3 + return [r, g, b]; }; -var eos = function(stream, opts, callback) { - if (typeof opts === 'function') return eos(stream, null, opts); - if (!opts) opts = {}; - - callback = once(callback || noop); - - var ws = stream._writableState; - var rs = stream._readableState; - var readable = opts.readable || (opts.readable !== false && stream.readable); - var writable = opts.writable || (opts.writable !== false && stream.writable); - - var onlegacyfinish = function() { - if (!stream.writable) onfinish(); - }; - - var onfinish = function() { - writable = false; - if (!readable) callback.call(stream); - }; - - var onend = function() { - readable = false; - if (!writable) callback.call(stream); - }; - - var onexit = function(exitCode) { - callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null); - }; - - var onerror = function(err) { - callback.call(stream, err); - }; - - var onclose = function() { - if (readable && !(rs && rs.ended)) return callback.call(stream, new Error('premature close')); - if (writable && !(ws && ws.ended)) return callback.call(stream, new Error('premature close')); - }; - - var onrequest = function() { - stream.req.on('finish', onfinish); - }; +convert.rgb.hcg = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var max = Math.max(Math.max(r, g), b); + var min = Math.min(Math.min(r, g), b); + var chroma = (max - min); + var grayscale; + var hue; - if (isRequest(stream)) { - stream.on('complete', onfinish); - stream.on('abort', onclose); - if (stream.req) onrequest(); - else stream.on('request', onrequest); - } else if (writable && !ws) { // legacy streams - stream.on('end', onlegacyfinish); - stream.on('close', onlegacyfinish); + if (chroma < 1) { + grayscale = min / (1 - chroma); + } else { + grayscale = 0; } - if (isChildProcess(stream)) stream.on('exit', onexit); + if (chroma <= 0) { + hue = 0; + } else + if (max === r) { + hue = ((g - b) / chroma) % 6; + } else + if (max === g) { + hue = 2 + (b - r) / chroma; + } else { + hue = 4 + (r - g) / chroma + 4; + } - stream.on('end', onend); - stream.on('finish', onfinish); - if (opts.error !== false) stream.on('error', onerror); - stream.on('close', onclose); + hue /= 6; + hue %= 1; - return function() { - stream.removeListener('complete', onfinish); - stream.removeListener('abort', onclose); - stream.removeListener('request', onrequest); - if (stream.req) stream.req.removeListener('finish', onfinish); - stream.removeListener('end', onlegacyfinish); - stream.removeListener('close', onlegacyfinish); - stream.removeListener('finish', onfinish); - stream.removeListener('exit', onexit); - stream.removeListener('end', onend); - stream.removeListener('error', onerror); - stream.removeListener('close', onclose); - }; + return [hue * 360, chroma * 100, grayscale * 100]; }; -module.exports = eos; - - -/***/ }), -/* 407 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const {PassThrough: PassThroughStream} = __webpack_require__(27); - -module.exports = options => { - options = {...options}; - - const {array} = options; - let {encoding} = options; - const isBuffer = encoding === 'buffer'; - let objectMode = false; +convert.hsl.hcg = function (hsl) { + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var c = 1; + var f = 0; - if (array) { - objectMode = !(encoding || isBuffer); + if (l < 0.5) { + c = 2.0 * s * l; } else { - encoding = encoding || 'utf8'; - } - - if (isBuffer) { - encoding = null; + c = 2.0 * s * (1.0 - l); } - const stream = new PassThroughStream({objectMode}); - - if (encoding) { - stream.setEncoding(encoding); + if (c < 1.0) { + f = (l - 0.5 * c) / (1.0 - c); } - let length = 0; - const chunks = []; - - stream.on('data', chunk => { - chunks.push(chunk); - - if (objectMode) { - length = chunks.length; - } else { - length += chunk.length; - } - }); - - stream.getBufferedValue = () => { - if (array) { - return chunks; - } - - return isBuffer ? Buffer.concat(chunks, length) : chunks.join(''); - }; - - stream.getBufferedLength = () => length; - - return stream; + return [hsl[0], c * 100, f * 100]; }; +convert.hsv.hcg = function (hsv) { + var s = hsv[1] / 100; + var v = hsv[2] / 100; -/***/ }), -/* 408 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; + var c = s * v; + var f = 0; + if (c < 1.0) { + f = (v - c) / (1 - c); + } -const { PassThrough } = __webpack_require__(27); + return [hsv[0], c * 100, f * 100]; +}; -module.exports = function (/*streams...*/) { - var sources = [] - var output = new PassThrough({objectMode: true}) +convert.hcg.rgb = function (hcg) { + var h = hcg[0] / 360; + var c = hcg[1] / 100; + var g = hcg[2] / 100; - output.setMaxListeners(0) + if (c === 0.0) { + return [g * 255, g * 255, g * 255]; + } - output.add = add - output.isEmpty = isEmpty + var pure = [0, 0, 0]; + var hi = (h % 1) * 6; + var v = hi % 1; + var w = 1 - v; + var mg = 0; - output.on('unpipe', remove) + switch (Math.floor(hi)) { + case 0: + pure[0] = 1; pure[1] = v; pure[2] = 0; break; + case 1: + pure[0] = w; pure[1] = 1; pure[2] = 0; break; + case 2: + pure[0] = 0; pure[1] = 1; pure[2] = v; break; + case 3: + pure[0] = 0; pure[1] = w; pure[2] = 1; break; + case 4: + pure[0] = v; pure[1] = 0; pure[2] = 1; break; + default: + pure[0] = 1; pure[1] = 0; pure[2] = w; + } - Array.prototype.slice.call(arguments).forEach(add) + mg = (1.0 - c) * g; - return output + return [ + (c * pure[0] + mg) * 255, + (c * pure[1] + mg) * 255, + (c * pure[2] + mg) * 255 + ]; +}; - function add (source) { - if (Array.isArray(source)) { - source.forEach(add) - return this - } +convert.hcg.hsv = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; - sources.push(source); - source.once('end', remove.bind(null, source)) - source.once('error', output.emit.bind(output, 'error')) - source.pipe(output, {end: false}) - return this - } + var v = c + g * (1.0 - c); + var f = 0; - function isEmpty () { - return sources.length == 0; - } + if (v > 0.0) { + f = c / v; + } - function remove (source) { - sources = sources.filter(function (it) { return it !== source }) - if (!sources.length && output.readable) { output.end() } - } -} + return [hcg[0], f * 100, v * 100]; +}; +convert.hcg.hsl = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; -/***/ }), -/* 409 */ -/***/ (function(module, exports, __webpack_require__) { + var l = g * (1.0 - c) + 0.5 * c; + var s = 0; -"use strict"; + if (l > 0.0 && l < 0.5) { + s = c / (2 * l); + } else + if (l >= 0.5 && l < 1.0) { + s = c / (2 * (1 - l)); + } + return [hcg[0], s * 100, l * 100]; +}; -const nativePromisePrototype = (async () => {})().constructor.prototype; -const descriptors = ['then', 'catch', 'finally'].map(property => [ - property, - Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property) -]); +convert.hcg.hwb = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + var v = c + g * (1.0 - c); + return [hcg[0], (v - c) * 100, (1 - v) * 100]; +}; -// The return value is a mixin of `childProcess` and `Promise` -const mergePromise = (spawned, promise) => { - for (const [property, descriptor] of descriptors) { - // Starting the main `promise` is deferred to avoid consuming streams - const value = typeof promise === 'function' ? - (...args) => Reflect.apply(descriptor.value, promise(), args) : - descriptor.value.bind(promise); +convert.hwb.hcg = function (hwb) { + var w = hwb[1] / 100; + var b = hwb[2] / 100; + var v = 1 - b; + var c = v - w; + var g = 0; - Reflect.defineProperty(spawned, property, {...descriptor, value}); + if (c < 1) { + g = (v - c) / (1 - c); } - return spawned; + return [hwb[0], c * 100, g * 100]; }; -// Use promises instead of `child_process` events -const getSpawnedPromise = spawned => { - return new Promise((resolve, reject) => { - spawned.on('exit', (exitCode, signal) => { - resolve({exitCode, signal}); - }); - - spawned.on('error', error => { - reject(error); - }); - - if (spawned.stdin) { - spawned.stdin.on('error', error => { - reject(error); - }); - } - }); +convert.apple.rgb = function (apple) { + return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; }; -module.exports = { - mergePromise, - getSpawnedPromise +convert.rgb.apple = function (rgb) { + return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; }; - - -/***/ }), -/* 410 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const SPACES_REGEXP = / +/g; - -const joinCommand = (file, args = []) => { - if (!Array.isArray(args)) { - return file; - } - - return [file, ...args].join(' '); +convert.gray.rgb = function (args) { + return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; }; -// Allow spaces to be escaped by a backslash if not meant as a delimiter -const handleEscaping = (tokens, token, index) => { - if (index === 0) { - return [token]; - } +convert.gray.hsl = convert.gray.hsv = function (args) { + return [0, 0, args[0]]; +}; - const previousToken = tokens[tokens.length - 1]; +convert.gray.hwb = function (gray) { + return [0, 100, gray[0]]; +}; - if (previousToken.endsWith('\\')) { - return [...tokens.slice(0, -1), `${previousToken.slice(0, -1)} ${token}`]; - } +convert.gray.cmyk = function (gray) { + return [0, 0, 0, gray[0]]; +}; - return [...tokens, token]; +convert.gray.lab = function (gray) { + return [gray[0], 0, 0]; }; -// Handle `execa.command()` -const parseCommand = command => { - return command - .trim() - .split(SPACES_REGEXP) - .reduce(handleEscaping, []); +convert.gray.hex = function (gray) { + var val = Math.round(gray[0] / 100 * 255) & 0xFF; + var integer = (val << 16) + (val << 8) + val; + + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; }; -module.exports = { - joinCommand, - parseCommand +convert.rgb.gray = function (rgb) { + var val = (rgb[0] + rgb[1] + rgb[2]) / 3; + return [val / 255 * 100]; }; /***/ }), -/* 411 */ +/* 391 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; + + +module.exports = { + "aliceblue": [240, 248, 255], + "antiquewhite": [250, 235, 215], + "aqua": [0, 255, 255], + "aquamarine": [127, 255, 212], + "azure": [240, 255, 255], + "beige": [245, 245, 220], + "bisque": [255, 228, 196], + "black": [0, 0, 0], + "blanchedalmond": [255, 235, 205], + "blue": [0, 0, 255], + "blueviolet": [138, 43, 226], + "brown": [165, 42, 42], + "burlywood": [222, 184, 135], + "cadetblue": [95, 158, 160], + "chartreuse": [127, 255, 0], + "chocolate": [210, 105, 30], + "coral": [255, 127, 80], + "cornflowerblue": [100, 149, 237], + "cornsilk": [255, 248, 220], + "crimson": [220, 20, 60], + "cyan": [0, 255, 255], + "darkblue": [0, 0, 139], + "darkcyan": [0, 139, 139], + "darkgoldenrod": [184, 134, 11], + "darkgray": [169, 169, 169], + "darkgreen": [0, 100, 0], + "darkgrey": [169, 169, 169], + "darkkhaki": [189, 183, 107], + "darkmagenta": [139, 0, 139], + "darkolivegreen": [85, 107, 47], + "darkorange": [255, 140, 0], + "darkorchid": [153, 50, 204], + "darkred": [139, 0, 0], + "darksalmon": [233, 150, 122], + "darkseagreen": [143, 188, 143], + "darkslateblue": [72, 61, 139], + "darkslategray": [47, 79, 79], + "darkslategrey": [47, 79, 79], + "darkturquoise": [0, 206, 209], + "darkviolet": [148, 0, 211], + "deeppink": [255, 20, 147], + "deepskyblue": [0, 191, 255], + "dimgray": [105, 105, 105], + "dimgrey": [105, 105, 105], + "dodgerblue": [30, 144, 255], + "firebrick": [178, 34, 34], + "floralwhite": [255, 250, 240], + "forestgreen": [34, 139, 34], + "fuchsia": [255, 0, 255], + "gainsboro": [220, 220, 220], + "ghostwhite": [248, 248, 255], + "gold": [255, 215, 0], + "goldenrod": [218, 165, 32], + "gray": [128, 128, 128], + "green": [0, 128, 0], + "greenyellow": [173, 255, 47], + "grey": [128, 128, 128], + "honeydew": [240, 255, 240], + "hotpink": [255, 105, 180], + "indianred": [205, 92, 92], + "indigo": [75, 0, 130], + "ivory": [255, 255, 240], + "khaki": [240, 230, 140], + "lavender": [230, 230, 250], + "lavenderblush": [255, 240, 245], + "lawngreen": [124, 252, 0], + "lemonchiffon": [255, 250, 205], + "lightblue": [173, 216, 230], + "lightcoral": [240, 128, 128], + "lightcyan": [224, 255, 255], + "lightgoldenrodyellow": [250, 250, 210], + "lightgray": [211, 211, 211], + "lightgreen": [144, 238, 144], + "lightgrey": [211, 211, 211], + "lightpink": [255, 182, 193], + "lightsalmon": [255, 160, 122], + "lightseagreen": [32, 178, 170], + "lightskyblue": [135, 206, 250], + "lightslategray": [119, 136, 153], + "lightslategrey": [119, 136, 153], + "lightsteelblue": [176, 196, 222], + "lightyellow": [255, 255, 224], + "lime": [0, 255, 0], + "limegreen": [50, 205, 50], + "linen": [250, 240, 230], + "magenta": [255, 0, 255], + "maroon": [128, 0, 0], + "mediumaquamarine": [102, 205, 170], + "mediumblue": [0, 0, 205], + "mediumorchid": [186, 85, 211], + "mediumpurple": [147, 112, 219], + "mediumseagreen": [60, 179, 113], + "mediumslateblue": [123, 104, 238], + "mediumspringgreen": [0, 250, 154], + "mediumturquoise": [72, 209, 204], + "mediumvioletred": [199, 21, 133], + "midnightblue": [25, 25, 112], + "mintcream": [245, 255, 250], + "mistyrose": [255, 228, 225], + "moccasin": [255, 228, 181], + "navajowhite": [255, 222, 173], + "navy": [0, 0, 128], + "oldlace": [253, 245, 230], + "olive": [128, 128, 0], + "olivedrab": [107, 142, 35], + "orange": [255, 165, 0], + "orangered": [255, 69, 0], + "orchid": [218, 112, 214], + "palegoldenrod": [238, 232, 170], + "palegreen": [152, 251, 152], + "paleturquoise": [175, 238, 238], + "palevioletred": [219, 112, 147], + "papayawhip": [255, 239, 213], + "peachpuff": [255, 218, 185], + "peru": [205, 133, 63], + "pink": [255, 192, 203], + "plum": [221, 160, 221], + "powderblue": [176, 224, 230], + "purple": [128, 0, 128], + "rebeccapurple": [102, 51, 153], + "red": [255, 0, 0], + "rosybrown": [188, 143, 143], + "royalblue": [65, 105, 225], + "saddlebrown": [139, 69, 19], + "salmon": [250, 128, 114], + "sandybrown": [244, 164, 96], + "seagreen": [46, 139, 87], + "seashell": [255, 245, 238], + "sienna": [160, 82, 45], + "silver": [192, 192, 192], + "skyblue": [135, 206, 235], + "slateblue": [106, 90, 205], + "slategray": [112, 128, 144], + "slategrey": [112, 128, 144], + "snow": [255, 250, 250], + "springgreen": [0, 255, 127], + "steelblue": [70, 130, 180], + "tan": [210, 180, 140], + "teal": [0, 128, 128], + "thistle": [216, 191, 216], + "tomato": [255, 99, 71], + "turquoise": [64, 224, 208], + "violet": [238, 130, 238], + "wheat": [245, 222, 179], + "white": [255, 255, 255], + "whitesmoke": [245, 245, 245], + "yellow": [255, 255, 0], + "yellowgreen": [154, 205, 50] +}; -var childProcess = __webpack_require__(372); -var spawn = childProcess.spawn; -var exec = childProcess.exec; - -module.exports = function (pid, signal, callback) { - if (typeof signal === 'function' && callback === undefined) { - callback = signal; - signal = undefined; - } - - pid = parseInt(pid); - if (Number.isNaN(pid)) { - if (callback) { - return callback(new Error("pid must be a number")); - } else { - throw new Error("pid must be a number"); - } - } - - var tree = {}; - var pidsToProcess = {}; - tree[pid] = []; - pidsToProcess[pid] = 1; - - switch (process.platform) { - case 'win32': - exec('taskkill /pid ' + pid + ' /T /F', callback); - break; - case 'darwin': - buildProcessTree(pid, tree, pidsToProcess, function (parentPid) { - return spawn('pgrep', ['-P', parentPid]); - }, function () { - killAll(tree, signal, callback); - }); - break; - // case 'sunos': - // buildProcessTreeSunOS(pid, tree, pidsToProcess, function () { - // killAll(tree, signal, callback); - // }); - // break; - default: // Linux - buildProcessTree(pid, tree, pidsToProcess, function (parentPid) { - return spawn('ps', ['-o', 'pid', '--no-headers', '--ppid', parentPid]); - }, function () { - killAll(tree, signal, callback); - }); - break; - } -}; - -function killAll (tree, signal, callback) { - var killed = {}; - try { - Object.keys(tree).forEach(function (pid) { - tree[pid].forEach(function (pidpid) { - if (!killed[pidpid]) { - killPid(pidpid, signal); - killed[pidpid] = 1; - } - }); - if (!killed[pid]) { - killPid(pid, signal); - killed[pid] = 1; - } - }); - } catch (err) { - if (callback) { - return callback(err); - } else { - throw err; - } - } - if (callback) { - return callback(); - } -} - -function killPid(pid, signal) { - try { - process.kill(parseInt(pid, 10), signal); - } - catch (err) { - if (err.code !== 'ESRCH') throw err; - } -} +/***/ }), +/* 392 */ +/***/ (function(module, exports, __webpack_require__) { -function buildProcessTree (parentPid, tree, pidsToProcess, spawnChildProcessesList, cb) { - var ps = spawnChildProcessesList(parentPid); - var allData = ''; - ps.stdout.on('data', function (data) { - var data = data.toString('ascii'); - allData += data; - }); +var conversions = __webpack_require__(390); - var onClose = function (code) { - delete pidsToProcess[parentPid]; +/* + this function routes a model to all other models. - if (code != 0) { - // no more parent processes - if (Object.keys(pidsToProcess).length == 0) { - cb(); - } - return; - } + all functions that are routed have a property `.conversion` attached + to the returned synthetic function. This property is an array + of strings, each with the steps in between the 'from' and 'to' + color models (inclusive). - allData.match(/\d+/g).forEach(function (pid) { - pid = parseInt(pid, 10); - tree[parentPid].push(pid); - tree[pid] = []; - pidsToProcess[pid] = 1; - buildProcessTree(pid, tree, pidsToProcess, spawnChildProcessesList, cb); - }); - }; + conversions that are not possible simply are not included. +*/ - ps.on('close', onClose); +function buildGraph() { + var graph = {}; + // https://jsperf.com/object-keys-vs-for-in-with-closure/3 + var models = Object.keys(conversions); + + for (var len = models.length, i = 0; i < len; i++) { + graph[models[i]] = { + // http://jsperf.com/1-vs-infinity + // micro-opt, but this is simple. + distance: -1, + parent: null + }; + } + + return graph; } +// https://en.wikipedia.org/wiki/Breadth-first_search +function deriveBFS(fromModel) { + var graph = buildGraph(); + var queue = [fromModel]; // unshift -> queue -> pop -/***/ }), -/* 412 */ -/***/ (function(module, exports, __webpack_require__) { + graph[fromModel].distance = 0; -"use strict"; + while (queue.length) { + var current = queue.pop(); + var adjacents = Object.keys(conversions[current]); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const tslib_1 = __webpack_require__(36); -const Rx = tslib_1.__importStar(__webpack_require__(169)); -const operators_1 = __webpack_require__(270); -const SEP = /\r?\n/; -const observe_readable_1 = __webpack_require__(413); -/** - * Creates an Observable from a Readable Stream that: - * - splits data from `readable` into lines - * - completes when `readable` emits "end" - * - fails if `readable` emits "errors" - * - * @param {ReadableStream} readable - * @return {Rx.Observable} - */ -function observeLines(readable) { - const done$ = observe_readable_1.observeReadable(readable).pipe(operators_1.share()); - const scan$ = Rx.fromEvent(readable, 'data').pipe(operators_1.scan(({ buffer }, chunk) => { - buffer += chunk; - const lines = []; - while (true) { - const match = buffer.match(SEP); - if (!match || match.index === undefined) { - break; - } - lines.push(buffer.slice(0, match.index)); - buffer = buffer.slice(match.index + match[0].length); - } - return { buffer, lines }; - }, { buffer: '' }), - // stop if done completes or errors - operators_1.takeUntil(done$.pipe(operators_1.materialize())), operators_1.share()); - return Rx.merge( - // use done$ to provide completion/errors - done$, - // merge in the "lines" from each step - scan$.pipe(operators_1.mergeMap(({ lines }) => lines || [])), - // inject the "unsplit" data at the end - scan$.pipe(operators_1.last(), operators_1.mergeMap(({ buffer }) => (buffer ? [buffer] : [])), - // if there were no lines, last() will error, so catch and complete - operators_1.catchError(() => Rx.empty()))); + for (var len = adjacents.length, i = 0; i < len; i++) { + var adjacent = adjacents[i]; + var node = graph[adjacent]; + + if (node.distance === -1) { + node.distance = graph[current].distance + 1; + node.parent = current; + queue.unshift(adjacent); + } + } + } + + return graph; } -exports.observeLines = observeLines; +function link(from, to) { + return function (args) { + return to(from(args)); + }; +} -/***/ }), -/* 413 */ -/***/ (function(module, exports, __webpack_require__) { +function wrapConversion(toModel, graph) { + var path = [graph[toModel].parent, toModel]; + var fn = conversions[graph[toModel].parent][toModel]; -"use strict"; + var cur = graph[toModel].parent; + while (graph[cur].parent) { + path.unshift(graph[cur].parent); + fn = link(conversions[graph[cur].parent][cur], fn); + cur = graph[cur].parent; + } -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const tslib_1 = __webpack_require__(36); -const Rx = tslib_1.__importStar(__webpack_require__(169)); -const operators_1 = __webpack_require__(270); -/** - * Produces an Observable from a ReadableSteam that: - * - completes on the first "end" event - * - fails on the first "error" event - */ -function observeReadable(readable) { - return Rx.race(Rx.fromEvent(readable, 'end').pipe(operators_1.first(), operators_1.ignoreElements()), Rx.fromEvent(readable, 'error').pipe(operators_1.first(), operators_1.mergeMap((err) => Rx.throwError(err)))); + fn.conversion = path; + return fn; } -exports.observeReadable = observeReadable; +module.exports = function (fromModel) { + var graph = deriveBFS(fromModel); + var conversion = {}; -/***/ }), -/* 414 */ -/***/ (function(module, exports, __webpack_require__) { + var models = Object.keys(graph); + for (var len = models.length, i = 0; i < len; i++) { + var toModel = models[i]; + var node = graph[toModel]; -"use strict"; + if (node.parent === null) { + // no possible conversion, or this node is the source model. + continue; + } + + conversion[toModel] = wrapConversion(toModel, graph); + } + + return conversion; +}; -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -var tooling_log_1 = __webpack_require__(415); -exports.ToolingLog = tooling_log_1.ToolingLog; -var tooling_log_text_writer_1 = __webpack_require__(416); -exports.ToolingLogTextWriter = tooling_log_text_writer_1.ToolingLogTextWriter; -var log_levels_1 = __webpack_require__(417); -exports.pickLevelFromFlags = log_levels_1.pickLevelFromFlags; -exports.parseLogLevel = log_levels_1.parseLogLevel; -var tooling_log_collecting_writer_1 = __webpack_require__(418); -exports.ToolingLogCollectingWriter = tooling_log_collecting_writer_1.ToolingLogCollectingWriter; /***/ }), -/* 415 */ +/* 393 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const tslib_1 = __webpack_require__(36); -const Rx = tslib_1.__importStar(__webpack_require__(169)); -const tooling_log_text_writer_1 = __webpack_require__(416); -class ToolingLog { - constructor(writerConfig) { - this.identWidth = 0; - this.writers = writerConfig ? [new tooling_log_text_writer_1.ToolingLogTextWriter(writerConfig)] : []; - this.written$ = new Rx.Subject(); - } - indent(delta = 0) { - this.identWidth = Math.max(this.identWidth + delta, 0); - return this.identWidth; - } - verbose(...args) { - this.sendToWriters('verbose', args); - } - debug(...args) { - this.sendToWriters('debug', args); - } - info(...args) { - this.sendToWriters('info', args); - } - success(...args) { - this.sendToWriters('success', args); - } - warning(...args) { - this.sendToWriters('warning', args); - } - error(error) { - this.sendToWriters('error', [error]); - } - write(...args) { - this.sendToWriters('write', args); - } - getWriters() { - return this.writers.slice(0); - } - setWriters(writers) { - this.writers = [...writers]; - } - getWritten$() { - return this.written$.asObservable(); - } - sendToWriters(type, args) { - const msg = { - type, - indent: this.identWidth, - args, - }; - let written = false; - for (const writer of this.writers) { - if (writer.write(msg)) { - written = true; - } - } - if (written) { - this.written$.next(msg); - } - } -} -exports.ToolingLog = ToolingLog; - +const os = __webpack_require__(364); +const hasFlag = __webpack_require__(394); -/***/ }), -/* 416 */ -/***/ (function(module, exports, __webpack_require__) { +const env = process.env; -"use strict"; +let forceColor; +if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false')) { + forceColor = false; +} else if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + forceColor = true; +} +if ('FORCE_COLOR' in env) { + forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; +} -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const tslib_1 = __webpack_require__(36); -const util_1 = __webpack_require__(29); -const chalk_1 = tslib_1.__importDefault(__webpack_require__(2)); -const log_levels_1 = __webpack_require__(417); -const { magentaBright, yellow, red, blue, green, dim } = chalk_1.default; -const PREFIX_INDENT = ' '.repeat(6); -const MSG_PREFIXES = { - verbose: ` ${magentaBright('sill')} `, - debug: ` ${dim('debg')} `, - info: ` ${blue('info')} `, - success: ` ${green('succ')} `, - warning: ` ${yellow('warn')} `, - error: `${red('ERROR')} `, -}; -const has = (obj, key) => obj.hasOwnProperty(key); -function shouldWriteType(level, type) { - if (type === 'write') { - return true; - } - return Boolean(level.flags[type === 'success' ? 'info' : type]); -} -function stringifyError(error) { - if (typeof error !== 'string' && !(error instanceof Error)) { - error = new Error(`"${error}" thrown`); - } - if (typeof error === 'string') { - return error; - } - return error.stack || error.message || error; -} -class ToolingLogTextWriter { - constructor(config) { - this.level = log_levels_1.parseLogLevel(config.level); - this.writeTo = config.writeTo; - if (!this.writeTo || typeof this.writeTo.write !== 'function') { - throw new Error('ToolingLogTextWriter requires the `writeTo` option be set to a stream (like process.stdout)'); - } - } - write(msg) { - if (!shouldWriteType(this.level, msg.type)) { - return false; - } - const prefix = has(MSG_PREFIXES, msg.type) ? MSG_PREFIXES[msg.type] : ''; - ToolingLogTextWriter.write(this.writeTo, prefix, msg); - return true; - } - static write(writeTo, prefix, msg) { - const txt = msg.type === 'error' - ? stringifyError(msg.args[0]) - : util_1.format(msg.args[0], ...msg.args.slice(1)); - (prefix + txt).split('\n').forEach((line, i) => { - let lineIndent = ''; - if (msg.indent > 0) { - // if we are indenting write some spaces followed by a symbol - lineIndent += ' '.repeat(msg.indent - 1); - lineIndent += line.startsWith('-') ? '└' : '│'; - } - if (line && prefix && i > 0) { - // apply additional indentation to lines after - // the first if this message gets a prefix - lineIndent += PREFIX_INDENT; - } - writeTo.write(`${lineIndent}${line}\n`); - }); - } +function translateLevel(level) { + if (level === 0) { + return false; + } + + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; } -exports.ToolingLogTextWriter = ToolingLogTextWriter; +function supportsColor(stream) { + if (forceColor === false) { + return 0; + } -/***/ }), -/* 417 */ -/***/ (function(module, exports, __webpack_require__) { + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } -"use strict"; + if (hasFlag('color=256')) { + return 2; + } -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const LEVELS = ['silent', 'error', 'warning', 'info', 'debug', 'verbose']; -function pickLevelFromFlags(flags, options = {}) { - if (flags.verbose) - return 'verbose'; - if (flags.debug) - return 'debug'; - if (flags.quiet) - return 'error'; - if (flags.silent) - return 'silent'; - return options.default || 'info'; -} -exports.pickLevelFromFlags = pickLevelFromFlags; -function parseLogLevel(name) { - const i = LEVELS.indexOf(name); - if (i === -1) { - const msg = `Invalid log level "${name}" ` + `(expected one of ${LEVELS.join(',')})`; - throw new Error(msg); - } - const flags = {}; - LEVELS.forEach((level, levelI) => { - flags[level] = levelI <= i; - }); - return { - name, - flags: flags, - }; -} -exports.parseLogLevel = parseLogLevel; + if (stream && !stream.isTTY && forceColor !== true) { + // VS code debugger doesn't have isTTY set + if (env.VSCODE_PID) { + return 1; + } + return 0; + } + const min = forceColor ? 1 : 0; -/***/ }), -/* 418 */ -/***/ (function(module, exports, __webpack_require__) { + if (process.platform === 'win32') { + // Node.js 7.5.0 is the first version of Node.js to include a patch to + // libuv that enables 256 color output on Windows. Anything earlier and it + // won't work. However, here we target Node.js 8 at minimum as it is an LTS + // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows + // release that supports 256 colors. Windows 10 build 14931 is the first release + // that supports 16m/TrueColor. + const osRelease = os.release().split('.'); + if ( + Number(process.versions.node.split('.')[0]) >= 8 && + Number(osRelease[0]) >= 10 && + Number(osRelease[2]) >= 10586 + ) { + return Number(osRelease[2]) >= 14931 ? 3 : 2; + } -"use strict"; + return 1; + } -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const tooling_log_text_writer_1 = __webpack_require__(416); -class ToolingLogCollectingWriter extends tooling_log_text_writer_1.ToolingLogTextWriter { - constructor() { - super({ - level: 'verbose', - writeTo: { - write: (msg) => { - // trim trailing new line - this.messages.push(msg.slice(0, -1)); - }, - }, - }); - this.messages = []; - } -} -exports.ToolingLogCollectingWriter = ToolingLogCollectingWriter; + if ('CI' in env) { + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } + return min; + } -/***/ }), -/* 419 */ -/***/ (function(module, exports, __webpack_require__) { + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } -"use strict"; + if (env.COLORTERM === 'truecolor') { + return 3; + } -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -var absolute_path_serializer_1 = __webpack_require__(420); -exports.createAbsolutePathSerializer = absolute_path_serializer_1.createAbsolutePathSerializer; + if ('TERM_PROGRAM' in env) { + const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + + switch (env.TERM_PROGRAM) { + case 'iTerm.app': + return version >= 3 ? 3 : 2; + case 'Apple_Terminal': + return 2; + // No default + } + } + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } -/***/ }), -/* 420 */ -/***/ (function(module, exports, __webpack_require__) { + if (/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } -"use strict"; + if ('COLORTERM' in env) { + return 1; + } -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const repo_root_1 = __webpack_require__(421); -function createAbsolutePathSerializer(rootPath = repo_root_1.REPO_ROOT) { - return { - print: (value) => value.replace(rootPath, '').replace(/\\/g, '/'), - test: (value) => typeof value === 'string' && value.startsWith(rootPath), - }; + if (env.TERM === 'dumb') { + return min; + } + + return min; } -exports.createAbsolutePathSerializer = createAbsolutePathSerializer; + +function getSupportLevel(stream) { + const level = supportsColor(stream); + return translateLevel(level); +} + +module.exports = { + supportsColor: getSupportLevel, + stdout: getSupportLevel(process.stdout), + stderr: getSupportLevel(process.stderr) +}; /***/ }), -/* 421 */ +/* 394 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const tslib_1 = __webpack_require__(36); -const path_1 = tslib_1.__importDefault(__webpack_require__(16)); -const fs_1 = tslib_1.__importDefault(__webpack_require__(23)); -const load_json_file_1 = tslib_1.__importDefault(__webpack_require__(422)); -const isKibanaDir = (dir) => { - try { - const path = path_1.default.resolve(dir, 'package.json'); - const json = load_json_file_1.default.sync(path); - if (json && typeof json === 'object' && 'name' in json && json.name === 'kibana') { - return true; - } - } - catch (error) { - if (error && error.code === 'ENOENT') { - return false; - } - throw error; - } +module.exports = (flag, argv) => { + argv = argv || process.argv; + const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); + const pos = argv.indexOf(prefix + flag); + const terminatorPos = argv.indexOf('--'); + return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); }; -// search for the kibana directory, since this file is moved around it might -// not be where we think but should always be a relatively close parent -// of this directory -const startDir = fs_1.default.realpathSync(__dirname); -const { root: rootDir } = path_1.default.parse(startDir); -let cursor = startDir; -while (true) { - if (isKibanaDir(cursor)) { - break; - } - const parent = path_1.default.dirname(cursor); - if (parent === rootDir) { - throw new Error(`unable to find kibana directory from ${startDir}`); - } - cursor = parent; -} -exports.REPO_ROOT = cursor; /***/ }), -/* 422 */ +/* 395 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const path = __webpack_require__(16); -const {promisify} = __webpack_require__(29); -const fs = __webpack_require__(423); -const stripBom = __webpack_require__(427); -const parseJson = __webpack_require__(428); +const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; +const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; +const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; +const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; -const parse = (data, filePath, options = {}) => { - data = stripBom(data); +const ESCAPES = new Map([ + ['n', '\n'], + ['r', '\r'], + ['t', '\t'], + ['b', '\b'], + ['f', '\f'], + ['v', '\v'], + ['0', '\0'], + ['\\', '\\'], + ['e', '\u001B'], + ['a', '\u0007'] +]); - if (typeof options.beforeParse === 'function') { - data = options.beforeParse(data); +function unescape(c) { + if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { + return String.fromCharCode(parseInt(c.slice(1), 16)); } - return parseJson(data, options.reviver, path.relative(process.cwd(), filePath)); -}; - -module.exports = async (filePath, options) => parse(await promisify(fs.readFile)(filePath, 'utf8'), filePath, options); -module.exports.sync = (filePath, options) => parse(fs.readFileSync(filePath, 'utf8'), filePath, options); + return ESCAPES.get(c) || c; +} +function parseArguments(name, args) { + const results = []; + const chunks = args.trim().split(/\s*,\s*/g); + let matches; -/***/ }), -/* 423 */ -/***/ (function(module, exports, __webpack_require__) { + for (const chunk of chunks) { + if (!isNaN(chunk)) { + results.push(Number(chunk)); + } else if ((matches = chunk.match(STRING_REGEX))) { + results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); + } else { + throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); + } + } -var fs = __webpack_require__(23) -var polyfills = __webpack_require__(424) -var legacy = __webpack_require__(425) -var clone = __webpack_require__(426) + return results; +} -var queue = [] +function parseStyle(style) { + STYLE_REGEX.lastIndex = 0; -var util = __webpack_require__(29) + const results = []; + let matches; -function noop () {} + while ((matches = STYLE_REGEX.exec(style)) !== null) { + const name = matches[1]; -var debug = noop -if (util.debuglog) - debug = util.debuglog('gfs4') -else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) - debug = function() { - var m = util.format.apply(util, arguments) - m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') - console.error(m) - } + if (matches[2]) { + const args = parseArguments(name, matches[2]); + results.push([name].concat(args)); + } else { + results.push([name]); + } + } -if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { - process.on('exit', function() { - debug(queue) - __webpack_require__(30).equal(queue.length, 0) - }) + return results; } -module.exports = patch(clone(fs)) -if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) { - module.exports = patch(fs) - fs.__patched = true; -} +function buildStyle(chalk, styles) { + const enabled = {}; -// Always patch fs.close/closeSync, because we want to -// retry() whenever a close happens *anywhere* in the program. -// This is essential when multiple graceful-fs instances are -// in play at the same time. -module.exports.close = (function (fs$close) { return function (fd, cb) { - return fs$close.call(fs, fd, function (err) { - if (!err) - retry() + for (const layer of styles) { + for (const style of layer.styles) { + enabled[style[0]] = layer.inverse ? null : style.slice(1); + } + } - if (typeof cb === 'function') - cb.apply(this, arguments) - }) -}})(fs.close) + let current = chalk; + for (const styleName of Object.keys(enabled)) { + if (Array.isArray(enabled[styleName])) { + if (!(styleName in current)) { + throw new Error(`Unknown Chalk style: ${styleName}`); + } -module.exports.closeSync = (function (fs$closeSync) { return function (fd) { - // Note that graceful-fs also retries when fs.closeSync() fails. - // Looks like a bug to me, although it's probably a harmless one. - var rval = fs$closeSync.apply(fs, arguments) - retry() - return rval -}})(fs.closeSync) + if (enabled[styleName].length > 0) { + current = current[styleName].apply(current, enabled[styleName]); + } else { + current = current[styleName]; + } + } + } -// Only patch fs once, otherwise we'll run into a memory leak if -// graceful-fs is loaded multiple times, such as in test environments that -// reset the loaded modules between tests. -// We look for the string `graceful-fs` from the comment above. This -// way we are not adding any extra properties and it will detect if older -// versions of graceful-fs are installed. -if (!/\bgraceful-fs\b/.test(fs.closeSync.toString())) { - fs.closeSync = module.exports.closeSync; - fs.close = module.exports.close; + return current; } -function patch (fs) { - // Everything that references the open() function needs to be in here - polyfills(fs) - fs.gracefulify = patch - fs.FileReadStream = ReadStream; // Legacy name. - fs.FileWriteStream = WriteStream; // Legacy name. - fs.createReadStream = createReadStream - fs.createWriteStream = createWriteStream - var fs$readFile = fs.readFile - fs.readFile = readFile - function readFile (path, options, cb) { - if (typeof options === 'function') - cb = options, options = null - - return go$readFile(path, options, cb) +module.exports = (chalk, tmp) => { + const styles = []; + const chunks = []; + let chunk = []; - function go$readFile (path, options, cb) { - return fs$readFile(path, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$readFile, [path, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } + // eslint-disable-next-line max-params + tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { + if (escapeChar) { + chunk.push(unescape(escapeChar)); + } else if (style) { + const str = chunk.join(''); + chunk = []; + chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); + styles.push({inverse, styles: parseStyle(style)}); + } else if (close) { + if (styles.length === 0) { + throw new Error('Found extraneous } in Chalk template literal'); + } - var fs$writeFile = fs.writeFile - fs.writeFile = writeFile - function writeFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null + chunks.push(buildStyle(chalk, styles)(chunk.join(''))); + chunk = []; + styles.pop(); + } else { + chunk.push(chr); + } + }); - return go$writeFile(path, data, options, cb) + chunks.push(chunk.join('')); - function go$writeFile (path, data, options, cb) { - return fs$writeFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$writeFile, [path, data, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } + if (styles.length > 0) { + const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; + throw new Error(errMsg); + } - var fs$appendFile = fs.appendFile - if (fs$appendFile) - fs.appendFile = appendFile - function appendFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null + return chunks.join(''); +}; - return go$appendFile(path, data, options, cb) - function go$appendFile (path, data, options, cb) { - return fs$appendFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$appendFile, [path, data, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } +/***/ }), +/* 396 */ +/***/ (function(module, exports, __webpack_require__) { - var fs$readdir = fs.readdir - fs.readdir = readdir - function readdir (path, options, cb) { - var args = [path] - if (typeof options !== 'function') { - args.push(options) - } else { - cb = options - } - args.push(go$readdir$cb) +"use strict"; - return go$readdir(args) - function go$readdir$cb (err, files) { - if (files && files.sort) - files.sort() +var childProcess = __webpack_require__(343); +var spawn = childProcess.spawn; +var exec = childProcess.exec; - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$readdir, [args]]) +module.exports = function (pid, signal, callback) { + if (typeof signal === 'function' && callback === undefined) { + callback = signal; + signal = undefined; + } - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } + pid = parseInt(pid); + if (Number.isNaN(pid)) { + if (callback) { + return callback(new Error("pid must be a number")); + } else { + throw new Error("pid must be a number"); + } } - } - function go$readdir (args) { - return fs$readdir.apply(fs, args) - } + var tree = {}; + var pidsToProcess = {}; + tree[pid] = []; + pidsToProcess[pid] = 1; - if (process.version.substr(0, 4) === 'v0.8') { - var legStreams = legacy(fs) - ReadStream = legStreams.ReadStream - WriteStream = legStreams.WriteStream - } + switch (process.platform) { + case 'win32': + exec('taskkill /pid ' + pid + ' /T /F', callback); + break; + case 'darwin': + buildProcessTree(pid, tree, pidsToProcess, function (parentPid) { + return spawn('pgrep', ['-P', parentPid]); + }, function () { + killAll(tree, signal, callback); + }); + break; + // case 'sunos': + // buildProcessTreeSunOS(pid, tree, pidsToProcess, function () { + // killAll(tree, signal, callback); + // }); + // break; + default: // Linux + buildProcessTree(pid, tree, pidsToProcess, function (parentPid) { + return spawn('ps', ['-o', 'pid', '--no-headers', '--ppid', parentPid]); + }, function () { + killAll(tree, signal, callback); + }); + break; + } +}; - var fs$ReadStream = fs.ReadStream - if (fs$ReadStream) { - ReadStream.prototype = Object.create(fs$ReadStream.prototype) - ReadStream.prototype.open = ReadStream$open - } +function killAll (tree, signal, callback) { + var killed = {}; + try { + Object.keys(tree).forEach(function (pid) { + tree[pid].forEach(function (pidpid) { + if (!killed[pidpid]) { + killPid(pidpid, signal); + killed[pidpid] = 1; + } + }); + if (!killed[pid]) { + killPid(pid, signal); + killed[pid] = 1; + } + }); + } catch (err) { + if (callback) { + return callback(err); + } else { + throw err; + } + } + if (callback) { + return callback(); + } +} - var fs$WriteStream = fs.WriteStream - if (fs$WriteStream) { - WriteStream.prototype = Object.create(fs$WriteStream.prototype) - WriteStream.prototype.open = WriteStream$open - } +function killPid(pid, signal) { + try { + process.kill(parseInt(pid, 10), signal); + } + catch (err) { + if (err.code !== 'ESRCH') throw err; + } +} - fs.ReadStream = ReadStream - fs.WriteStream = WriteStream +function buildProcessTree (parentPid, tree, pidsToProcess, spawnChildProcessesList, cb) { + var ps = spawnChildProcessesList(parentPid); + var allData = ''; + ps.stdout.on('data', function (data) { + var data = data.toString('ascii'); + allData += data; + }); - function ReadStream (path, options) { - if (this instanceof ReadStream) - return fs$ReadStream.apply(this, arguments), this - else - return ReadStream.apply(Object.create(ReadStream.prototype), arguments) - } + var onClose = function (code) { + delete pidsToProcess[parentPid]; - function ReadStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - if (that.autoClose) - that.destroy() + if (code != 0) { + // no more parent processes + if (Object.keys(pidsToProcess).length == 0) { + cb(); + } + return; + } - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - that.read() - } - }) - } + allData.match(/\d+/g).forEach(function (pid) { + pid = parseInt(pid, 10); + tree[parentPid].push(pid); + tree[pid] = []; + pidsToProcess[pid] = 1; + buildProcessTree(pid, tree, pidsToProcess, spawnChildProcessesList, cb); + }); + }; - function WriteStream (path, options) { - if (this instanceof WriteStream) - return fs$WriteStream.apply(this, arguments), this - else - return WriteStream.apply(Object.create(WriteStream.prototype), arguments) - } + ps.on('close', onClose); +} - function WriteStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - that.destroy() - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - } - }) - } - function createReadStream (path, options) { - return new ReadStream(path, options) - } +/***/ }), +/* 397 */ +/***/ (function(module, exports) { - function createWriteStream (path, options) { - return new WriteStream(path, options) - } +module.exports = require("util"); - var fs$open = fs.open - fs.open = open - function open (path, flags, mode, cb) { - if (typeof mode === 'function') - cb = mode, mode = null +/***/ }), +/* 398 */ +/***/ (function(module, exports, __webpack_require__) { - return go$open(path, flags, mode, cb) +"use strict"; - function go$open (path, flags, mode, cb) { - return fs$open(path, flags, mode, function (err, fd) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$open, [path, flags, mode, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(6); +const Rx = tslib_1.__importStar(__webpack_require__(140)); +const operators_1 = __webpack_require__(241); +const SEP = /\r?\n/; +const observe_readable_1 = __webpack_require__(399); +/** + * Creates an Observable from a Readable Stream that: + * - splits data from `readable` into lines + * - completes when `readable` emits "end" + * - fails if `readable` emits "errors" + * + * @param {ReadableStream} readable + * @return {Rx.Observable} + */ +function observeLines(readable) { + const done$ = observe_readable_1.observeReadable(readable).pipe(operators_1.share()); + const scan$ = Rx.fromEvent(readable, 'data').pipe(operators_1.scan(({ buffer }, chunk) => { + buffer += chunk; + const lines = []; + while (true) { + const match = buffer.match(SEP); + if (!match || match.index === undefined) { + break; + } + lines.push(buffer.slice(0, match.index)); + buffer = buffer.slice(match.index + match[0].length); } - }) - } - } - - return fs -} - -function enqueue (elem) { - debug('ENQUEUE', elem[0].name, elem[1]) - queue.push(elem) -} - -function retry () { - var elem = queue.shift() - if (elem) { - debug('RETRY', elem[0].name, elem[1]) - elem[0].apply(null, elem[1]) - } + return { buffer, lines }; + }, { buffer: '' }), + // stop if done completes or errors + operators_1.takeUntil(done$.pipe(operators_1.materialize())), operators_1.share()); + return Rx.merge( + // use done$ to provide completion/errors + done$, + // merge in the "lines" from each step + scan$.pipe(operators_1.mergeMap(({ lines }) => lines || [])), + // inject the "unsplit" data at the end + scan$.pipe(operators_1.last(), operators_1.mergeMap(({ buffer }) => (buffer ? [buffer] : [])), + // if there were no lines, last() will error, so catch and complete + operators_1.catchError(() => Rx.empty()))); } +exports.observeLines = observeLines; /***/ }), -/* 424 */ +/* 399 */ /***/ (function(module, exports, __webpack_require__) { -var constants = __webpack_require__(25) - -var origCwd = process.cwd -var cwd = null - -var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform - -process.cwd = function() { - if (!cwd) - cwd = origCwd.call(process) - return cwd -} -try { - process.cwd() -} catch (er) {} +"use strict"; -var chdir = process.chdir -process.chdir = function(d) { - cwd = null - chdir.call(process, d) +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(6); +const Rx = tslib_1.__importStar(__webpack_require__(140)); +const operators_1 = __webpack_require__(241); +/** + * Produces an Observable from a ReadableSteam that: + * - completes on the first "end" event + * - fails on the first "error" event + */ +function observeReadable(readable) { + return Rx.race(Rx.fromEvent(readable, 'end').pipe(operators_1.first(), operators_1.ignoreElements()), Rx.fromEvent(readable, 'error').pipe(operators_1.first(), operators_1.mergeMap((err) => Rx.throwError(err)))); } +exports.observeReadable = observeReadable; -module.exports = patch - -function patch (fs) { - // (re-)implement some things that are known busted or missing. - - // lchmod, broken prior to 0.6.2 - // back-port the fix here. - if (constants.hasOwnProperty('O_SYMLINK') && - process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { - patchLchmod(fs) - } - - // lutimes implementation, or no-op - if (!fs.lutimes) { - patchLutimes(fs) - } - - // https://github.com/isaacs/node-graceful-fs/issues/4 - // Chown should not fail on einval or eperm if non-root. - // It should not fail on enosys ever, as this just indicates - // that a fs doesn't support the intended operation. - - fs.chown = chownFix(fs.chown) - fs.fchown = chownFix(fs.fchown) - fs.lchown = chownFix(fs.lchown) - fs.chmod = chmodFix(fs.chmod) - fs.fchmod = chmodFix(fs.fchmod) - fs.lchmod = chmodFix(fs.lchmod) +/***/ }), +/* 400 */ +/***/ (function(module, exports, __webpack_require__) { - fs.chownSync = chownFixSync(fs.chownSync) - fs.fchownSync = chownFixSync(fs.fchownSync) - fs.lchownSync = chownFixSync(fs.lchownSync) +"use strict"; - fs.chmodSync = chmodFixSync(fs.chmodSync) - fs.fchmodSync = chmodFixSync(fs.fchmodSync) - fs.lchmodSync = chmodFixSync(fs.lchmodSync) +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +var tooling_log_1 = __webpack_require__(401); +exports.ToolingLog = tooling_log_1.ToolingLog; +var tooling_log_text_writer_1 = __webpack_require__(402); +exports.ToolingLogTextWriter = tooling_log_text_writer_1.ToolingLogTextWriter; +var log_levels_1 = __webpack_require__(403); +exports.pickLevelFromFlags = log_levels_1.pickLevelFromFlags; +exports.parseLogLevel = log_levels_1.parseLogLevel; +var tooling_log_collecting_writer_1 = __webpack_require__(404); +exports.ToolingLogCollectingWriter = tooling_log_collecting_writer_1.ToolingLogCollectingWriter; - fs.stat = statFix(fs.stat) - fs.fstat = statFix(fs.fstat) - fs.lstat = statFix(fs.lstat) - fs.statSync = statFixSync(fs.statSync) - fs.fstatSync = statFixSync(fs.fstatSync) - fs.lstatSync = statFixSync(fs.lstatSync) +/***/ }), +/* 401 */ +/***/ (function(module, exports, __webpack_require__) { - // if lchmod/lchown do not exist, then make them no-ops - if (!fs.lchmod) { - fs.lchmod = function (path, mode, cb) { - if (cb) process.nextTick(cb) - } - fs.lchmodSync = function () {} - } - if (!fs.lchown) { - fs.lchown = function (path, uid, gid, cb) { - if (cb) process.nextTick(cb) - } - fs.lchownSync = function () {} - } +"use strict"; - // on Windows, A/V software can lock the directory, causing this - // to fail with an EACCES or EPERM if the directory contains newly - // created files. Try again on failure, for up to 60 seconds. - - // Set the timeout this long because some Windows Anti-Virus, such as Parity - // bit9, may lock files for up to a minute, causing npm package install - // failures. Also, take care to yield the scheduler. Windows scheduling gives - // CPU to a busy looping process, which can cause the program causing the lock - // contention to be starved of CPU by node, so the contention doesn't resolve. - if (platform === "win32") { - fs.rename = (function (fs$rename) { return function (from, to, cb) { - var start = Date.now() - var backoff = 0; - fs$rename(from, to, function CB (er) { - if (er - && (er.code === "EACCES" || er.code === "EPERM") - && Date.now() - start < 60000) { - setTimeout(function() { - fs.stat(to, function (stater, st) { - if (stater && stater.code === "ENOENT") - fs$rename(from, to, CB); - else - cb(er) - }) - }, backoff) - if (backoff < 100) - backoff += 10; - return; - } - if (cb) cb(er) - }) - }})(fs.rename) - } - - // if read() returns EAGAIN, then just try it again. - fs.read = (function (fs$read) { return function (fd, buffer, offset, length, position, callback_) { - var callback - if (callback_ && typeof callback_ === 'function') { - var eagCounter = 0 - callback = function (er, _, __) { - if (er && er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - return fs$read.call(fs, fd, buffer, offset, length, position, callback) - } - callback_.apply(this, arguments) - } +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(6); +const Rx = tslib_1.__importStar(__webpack_require__(140)); +const tooling_log_text_writer_1 = __webpack_require__(402); +class ToolingLog { + constructor(writerConfig) { + this.identWidth = 0; + this.writers = writerConfig ? [new tooling_log_text_writer_1.ToolingLogTextWriter(writerConfig)] : []; + this.written$ = new Rx.Subject(); } - return fs$read.call(fs, fd, buffer, offset, length, position, callback) - }})(fs.read) - - fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { - var eagCounter = 0 - while (true) { - try { - return fs$readSync.call(fs, fd, buffer, offset, length, position) - } catch (er) { - if (er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - continue - } - throw er - } + indent(delta = 0) { + this.identWidth = Math.max(this.identWidth + delta, 0); + return this.identWidth; } - }})(fs.readSync) - - function patchLchmod (fs) { - fs.lchmod = function (path, mode, callback) { - fs.open( path - , constants.O_WRONLY | constants.O_SYMLINK - , mode - , function (err, fd) { - if (err) { - if (callback) callback(err) - return - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function (err) { - fs.close(fd, function(err2) { - if (callback) callback(err || err2) - }) - }) - }) + verbose(...args) { + this.sendToWriters('verbose', args); } - - fs.lchmodSync = function (path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var threw = true - var ret - try { - ret = fs.fchmodSync(fd, mode) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) + debug(...args) { + this.sendToWriters('debug', args); + } + info(...args) { + this.sendToWriters('info', args); + } + success(...args) { + this.sendToWriters('success', args); + } + warning(...args) { + this.sendToWriters('warning', args); + } + error(error) { + this.sendToWriters('error', [error]); + } + write(...args) { + this.sendToWriters('write', args); + } + getWriters() { + return this.writers.slice(0); + } + setWriters(writers) { + this.writers = [...writers]; + } + getWritten$() { + return this.written$.asObservable(); + } + sendToWriters(type, args) { + const msg = { + type, + indent: this.identWidth, + args, + }; + let written = false; + for (const writer of this.writers) { + if (writer.write(msg)) { + written = true; + } + } + if (written) { + this.written$.next(msg); } - } - return ret } - } +} +exports.ToolingLog = ToolingLog; - function patchLutimes (fs) { - if (constants.hasOwnProperty("O_SYMLINK")) { - fs.lutimes = function (path, at, mt, cb) { - fs.open(path, constants.O_SYMLINK, function (er, fd) { - if (er) { - if (cb) cb(er) - return - } - fs.futimes(fd, at, mt, function (er) { - fs.close(fd, function (er2) { - if (cb) cb(er || er2) - }) - }) - }) - } - fs.lutimesSync = function (path, at, mt) { - var fd = fs.openSync(path, constants.O_SYMLINK) - var ret - var threw = true - try { - ret = fs.futimesSync(fd, at, mt) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) - } - } - return ret - } +/***/ }), +/* 402 */ +/***/ (function(module, exports, __webpack_require__) { - } else { - fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } - fs.lutimesSync = function () {} - } - } +"use strict"; - function chmodFix (orig) { - if (!orig) return orig - return function (target, mode, cb) { - return orig.call(fs, target, mode, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(6); +const util_1 = __webpack_require__(397); +const chalk_1 = tslib_1.__importDefault(__webpack_require__(386)); +const log_levels_1 = __webpack_require__(403); +const { magentaBright, yellow, red, blue, green, dim } = chalk_1.default; +const PREFIX_INDENT = ' '.repeat(6); +const MSG_PREFIXES = { + verbose: ` ${magentaBright('sill')} `, + debug: ` ${dim('debg')} `, + info: ` ${blue('info')} `, + success: ` ${green('succ')} `, + warning: ` ${yellow('warn')} `, + error: `${red('ERROR')} `, +}; +const has = (obj, key) => obj.hasOwnProperty(key); +function shouldWriteType(level, type) { + if (type === 'write') { + return level.name !== 'silent'; } - } - - function chmodFixSync (orig) { - if (!orig) return orig - return function (target, mode) { - try { - return orig.call(fs, target, mode) - } catch (er) { - if (!chownErOk(er)) throw er - } + return Boolean(level.flags[type === 'success' ? 'info' : type]); +} +function stringifyError(error) { + if (typeof error !== 'string' && !(error instanceof Error)) { + error = new Error(`"${error}" thrown`); } - } - - - function chownFix (orig) { - if (!orig) return orig - return function (target, uid, gid, cb) { - return orig.call(fs, target, uid, gid, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) + if (typeof error === 'string') { + return error; } - } - - function chownFixSync (orig) { - if (!orig) return orig - return function (target, uid, gid) { - try { - return orig.call(fs, target, uid, gid) - } catch (er) { - if (!chownErOk(er)) throw er - } + return error.stack || error.message || error; +} +class ToolingLogTextWriter { + constructor(config) { + this.level = log_levels_1.parseLogLevel(config.level); + this.writeTo = config.writeTo; + if (!this.writeTo || typeof this.writeTo.write !== 'function') { + throw new Error('ToolingLogTextWriter requires the `writeTo` option be set to a stream (like process.stdout)'); + } } - } - - - function statFix (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target, cb) { - return orig.call(fs, target, function (er, stats) { - if (!stats) return cb.apply(this, arguments) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - if (cb) cb.apply(this, arguments) - }) + write(msg) { + if (!shouldWriteType(this.level, msg.type)) { + return false; + } + const prefix = has(MSG_PREFIXES, msg.type) ? MSG_PREFIXES[msg.type] : ''; + ToolingLogTextWriter.write(this.writeTo, prefix, msg); + return true; } - } - - function statFixSync (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target) { - var stats = orig.call(fs, target) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - return stats; + static write(writeTo, prefix, msg) { + const txt = msg.type === 'error' + ? stringifyError(msg.args[0]) + : util_1.format(msg.args[0], ...msg.args.slice(1)); + (prefix + txt).split('\n').forEach((line, i) => { + let lineIndent = ''; + if (msg.indent > 0) { + // if we are indenting write some spaces followed by a symbol + lineIndent += ' '.repeat(msg.indent - 1); + lineIndent += line.startsWith('-') ? '└' : '│'; + } + if (line && prefix && i > 0) { + // apply additional indentation to lines after + // the first if this message gets a prefix + lineIndent += PREFIX_INDENT; + } + writeTo.write(`${lineIndent}${line}\n`); + }); } - } +} +exports.ToolingLogTextWriter = ToolingLogTextWriter; - // ENOSYS means that the fs doesn't support the op. Just ignore - // that, because it doesn't matter. - // - // if there's no getuid, or if getuid() is something other - // than 0, and the error is EINVAL or EPERM, then just ignore - // it. - // - // This specific case is a silent failure in cp, install, tar, - // and most other unix tools that manage permissions. - // - // When running as root, or if other types of errors are - // encountered, then it's strict. - function chownErOk (er) { - if (!er) - return true - if (er.code === "ENOSYS") - return true +/***/ }), +/* 403 */ +/***/ (function(module, exports, __webpack_require__) { - var nonroot = !process.getuid || process.getuid() !== 0 - if (nonroot) { - if (er.code === "EINVAL" || er.code === "EPERM") - return true - } +"use strict"; - return false - } +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const LEVELS = ['silent', 'error', 'warning', 'info', 'debug', 'verbose']; +function pickLevelFromFlags(flags, options = {}) { + if (flags.verbose) + return 'verbose'; + if (flags.debug) + return 'debug'; + if (flags.quiet) + return 'error'; + if (flags.silent) + return 'silent'; + return options.default || 'info'; +} +exports.pickLevelFromFlags = pickLevelFromFlags; +function parseLogLevel(name) { + const i = LEVELS.indexOf(name); + if (i === -1) { + const msg = `Invalid log level "${name}" ` + `(expected one of ${LEVELS.join(',')})`; + throw new Error(msg); + } + const flags = {}; + LEVELS.forEach((level, levelI) => { + flags[level] = levelI <= i; + }); + return { + name, + flags: flags, + }; } +exports.parseLogLevel = parseLogLevel; /***/ }), -/* 425 */ +/* 404 */ /***/ (function(module, exports, __webpack_require__) { -var Stream = __webpack_require__(27).Stream +"use strict"; -module.exports = legacy +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const tooling_log_text_writer_1 = __webpack_require__(402); +class ToolingLogCollectingWriter extends tooling_log_text_writer_1.ToolingLogTextWriter { + constructor(level = 'verbose') { + super({ + level, + writeTo: { + write: (msg) => { + // trim trailing new line + this.messages.push(msg.slice(0, -1)); + }, + }, + }); + this.messages = []; + } +} +exports.ToolingLogCollectingWriter = ToolingLogCollectingWriter; -function legacy (fs) { - return { - ReadStream: ReadStream, - WriteStream: WriteStream - } - function ReadStream (path, options) { - if (!(this instanceof ReadStream)) return new ReadStream(path, options); +/***/ }), +/* 405 */ +/***/ (function(module, exports, __webpack_require__) { - Stream.call(this); +"use strict"; - var self = this; +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +var absolute_path_serializer_1 = __webpack_require__(406); +exports.createAbsolutePathSerializer = absolute_path_serializer_1.createAbsolutePathSerializer; - this.path = path; - this.fd = null; - this.readable = true; - this.paused = false; - this.flags = 'r'; - this.mode = 438; /*=0666*/ - this.bufferSize = 64 * 1024; +/***/ }), +/* 406 */ +/***/ (function(module, exports, __webpack_require__) { - options = options || {}; +"use strict"; - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; - } - - if (this.encoding) this.setEncoding(this.encoding); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const repo_root_1 = __webpack_require__(407); +function createAbsolutePathSerializer(rootPath = repo_root_1.REPO_ROOT) { + return { + print: (value) => value.replace(rootPath, '').replace(/\\/g, '/'), + test: (value) => typeof value === 'string' && value.startsWith(rootPath), + }; +} +exports.createAbsolutePathSerializer = createAbsolutePathSerializer; - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if ('number' !== typeof this.end) { - throw TypeError('end must be a Number'); - } - if (this.start > this.end) { - throw new Error('start must be <= end'); - } +/***/ }), +/* 407 */ +/***/ (function(module, exports, __webpack_require__) { - this.pos = this.start; - } +"use strict"; - if (this.fd !== null) { - process.nextTick(function() { - self._read(); - }); - return; +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(6); +const path_1 = tslib_1.__importDefault(__webpack_require__(4)); +const fs_1 = tslib_1.__importDefault(__webpack_require__(349)); +const load_json_file_1 = tslib_1.__importDefault(__webpack_require__(408)); +const isKibanaDir = (dir) => { + try { + const path = path_1.default.resolve(dir, 'package.json'); + const json = load_json_file_1.default.sync(path); + if (json && typeof json === 'object' && 'name' in json && json.name === 'kibana') { + return true; + } } - - fs.open(this.path, this.flags, this.mode, function (err, fd) { - if (err) { - self.emit('error', err); - self.readable = false; - return; - } - - self.fd = fd; - self.emit('open', fd); - self._read(); - }) - } - - function WriteStream (path, options) { - if (!(this instanceof WriteStream)) return new WriteStream(path, options); - - Stream.call(this); - - this.path = path; - this.fd = null; - this.writable = true; - - this.flags = 'w'; - this.encoding = 'binary'; - this.mode = 438; /*=0666*/ - this.bytesWritten = 0; - - options = options || {}; - - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; + catch (error) { + if (error && error.code === 'ENOENT') { + return false; + } + throw error; } - - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } - - this.pos = this.start; +}; +// search for the kibana directory, since this file is moved around it might +// not be where we think but should always be a relatively close parent +// of this directory +const startDir = fs_1.default.realpathSync(__dirname); +const { root: rootDir } = path_1.default.parse(startDir); +let cursor = startDir; +while (true) { + if (isKibanaDir(cursor)) { + break; } - - this.busy = false; - this._queue = []; - - if (this.fd === null) { - this._open = fs.open; - this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); - this.flush(); + const parent = path_1.default.dirname(cursor); + if (parent === rootDir) { + throw new Error(`unable to find kibana directory from ${startDir}`); } - } + cursor = parent; } +exports.REPO_ROOT = cursor; /***/ }), -/* 426 */ +/* 408 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const path = __webpack_require__(4); +const {promisify} = __webpack_require__(397); +const fs = __webpack_require__(409); +const stripBom = __webpack_require__(414); +const parseJson = __webpack_require__(415); -module.exports = clone - -function clone (obj) { - if (obj === null || typeof obj !== 'object') - return obj +const parse = (data, filePath, options = {}) => { + data = stripBom(data); - if (obj instanceof Object) - var copy = { __proto__: obj.__proto__ } - else - var copy = Object.create(null) + if (typeof options.beforeParse === 'function') { + data = options.beforeParse(data); + } - Object.getOwnPropertyNames(obj).forEach(function (key) { - Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) - }) + return parseJson(data, options.reviver, path.relative(process.cwd(), filePath)); +}; - return copy -} +module.exports = async (filePath, options) => parse(await promisify(fs.readFile)(filePath, 'utf8'), filePath, options); +module.exports.sync = (filePath, options) => parse(fs.readFileSync(filePath, 'utf8'), filePath, options); /***/ }), -/* 427 */ +/* 409 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var fs = __webpack_require__(349) +var polyfills = __webpack_require__(410) +var legacy = __webpack_require__(412) +var clone = __webpack_require__(413) +var queue = [] -module.exports = string => { - if (typeof string !== 'string') { - throw new TypeError(`Expected a string, got ${typeof string}`); - } +var util = __webpack_require__(397) - // Catches EFBBBF (UTF-8 BOM) because the buffer-to-string - // conversion translates it to FEFF (UTF-16 BOM) - if (string.charCodeAt(0) === 0xFEFF) { - return string.slice(1); - } +function noop () {} - return string; -}; +var debug = noop +if (util.debuglog) + debug = util.debuglog('gfs4') +else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) + debug = function() { + var m = util.format.apply(util, arguments) + m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') + console.error(m) + } +if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { + process.on('exit', function() { + debug(queue) + __webpack_require__(371).equal(queue.length, 0) + }) +} -/***/ }), -/* 428 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports = patch(clone(fs)) +if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) { + module.exports = patch(fs) + fs.__patched = true; +} -"use strict"; +// Always patch fs.close/closeSync, because we want to +// retry() whenever a close happens *anywhere* in the program. +// This is essential when multiple graceful-fs instances are +// in play at the same time. +module.exports.close = (function (fs$close) { return function (fd, cb) { + return fs$close.call(fs, fd, function (err) { + if (!err) + retry() -const errorEx = __webpack_require__(429); -const fallback = __webpack_require__(431); -const {default: LinesAndColumns} = __webpack_require__(432); -const {codeFrameColumns} = __webpack_require__(433); + if (typeof cb === 'function') + cb.apply(this, arguments) + }) +}})(fs.close) -const JSONError = errorEx('JSONError', { - fileName: errorEx.append('in %s'), - codeFrame: errorEx.append('\n\n%s\n') -}); +module.exports.closeSync = (function (fs$closeSync) { return function (fd) { + // Note that graceful-fs also retries when fs.closeSync() fails. + // Looks like a bug to me, although it's probably a harmless one. + var rval = fs$closeSync.apply(fs, arguments) + retry() + return rval +}})(fs.closeSync) -module.exports = (string, reviver, filename) => { - if (typeof reviver === 'string') { - filename = reviver; - reviver = null; - } +// Only patch fs once, otherwise we'll run into a memory leak if +// graceful-fs is loaded multiple times, such as in test environments that +// reset the loaded modules between tests. +// We look for the string `graceful-fs` from the comment above. This +// way we are not adding any extra properties and it will detect if older +// versions of graceful-fs are installed. +if (!/\bgraceful-fs\b/.test(fs.closeSync.toString())) { + fs.closeSync = module.exports.closeSync; + fs.close = module.exports.close; +} - try { - try { - return JSON.parse(string, reviver); - } catch (error) { - fallback(string, reviver); - throw error; - } - } catch (error) { - error.message = error.message.replace(/\n/g, ''); - const indexMatch = error.message.match(/in JSON at position (\d+) while parsing near/); +function patch (fs) { + // Everything that references the open() function needs to be in here + polyfills(fs) + fs.gracefulify = patch + fs.FileReadStream = ReadStream; // Legacy name. + fs.FileWriteStream = WriteStream; // Legacy name. + fs.createReadStream = createReadStream + fs.createWriteStream = createWriteStream + var fs$readFile = fs.readFile + fs.readFile = readFile + function readFile (path, options, cb) { + if (typeof options === 'function') + cb = options, options = null - const jsonError = new JSONError(error); - if (filename) { - jsonError.fileName = filename; - } + return go$readFile(path, options, cb) - if (indexMatch && indexMatch.length > 0) { - const lines = new LinesAndColumns(string); - const index = Number(indexMatch[1]); - const location = lines.locationForIndex(index); + function go$readFile (path, options, cb) { + return fs$readFile(path, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readFile, [path, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } - const codeFrame = codeFrameColumns( - string, - {start: {line: location.line + 1, column: location.column + 1}}, - {highlightCode: true} - ); + var fs$writeFile = fs.writeFile + fs.writeFile = writeFile + function writeFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null - jsonError.codeFrame = codeFrame; - } + return go$writeFile(path, data, options, cb) - throw jsonError; - } -}; + function go$writeFile (path, data, options, cb) { + return fs$writeFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$writeFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } + var fs$appendFile = fs.appendFile + if (fs$appendFile) + fs.appendFile = appendFile + function appendFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null -/***/ }), -/* 429 */ -/***/ (function(module, exports, __webpack_require__) { + return go$appendFile(path, data, options, cb) -"use strict"; + function go$appendFile (path, data, options, cb) { + return fs$appendFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$appendFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } + var fs$readdir = fs.readdir + fs.readdir = readdir + function readdir (path, options, cb) { + var args = [path] + if (typeof options !== 'function') { + args.push(options) + } else { + cb = options + } + args.push(go$readdir$cb) -var util = __webpack_require__(29); -var isArrayish = __webpack_require__(430); + return go$readdir(args) -var errorEx = function errorEx(name, properties) { - if (!name || name.constructor !== String) { - properties = name || {}; - name = Error.name; - } + function go$readdir$cb (err, files) { + if (files && files.sort) + files.sort() - var errorExError = function ErrorEXError(message) { - if (!this) { - return new ErrorEXError(message); - } + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readdir, [args]]) - message = message instanceof Error - ? message.message - : (message || this.message); + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + } + } - Error.call(this, message); - Error.captureStackTrace(this, errorExError); + function go$readdir (args) { + return fs$readdir.apply(fs, args) + } - this.name = name; + if (process.version.substr(0, 4) === 'v0.8') { + var legStreams = legacy(fs) + ReadStream = legStreams.ReadStream + WriteStream = legStreams.WriteStream + } - Object.defineProperty(this, 'message', { - configurable: true, - enumerable: false, - get: function () { - var newMessage = message.split(/\r?\n/g); + var fs$ReadStream = fs.ReadStream + if (fs$ReadStream) { + ReadStream.prototype = Object.create(fs$ReadStream.prototype) + ReadStream.prototype.open = ReadStream$open + } - for (var key in properties) { - if (!properties.hasOwnProperty(key)) { - continue; - } + var fs$WriteStream = fs.WriteStream + if (fs$WriteStream) { + WriteStream.prototype = Object.create(fs$WriteStream.prototype) + WriteStream.prototype.open = WriteStream$open + } - var modifier = properties[key]; + fs.ReadStream = ReadStream + fs.WriteStream = WriteStream - if ('message' in modifier) { - newMessage = modifier.message(this[key], newMessage) || newMessage; - if (!isArrayish(newMessage)) { - newMessage = [newMessage]; - } - } - } + function ReadStream (path, options) { + if (this instanceof ReadStream) + return fs$ReadStream.apply(this, arguments), this + else + return ReadStream.apply(Object.create(ReadStream.prototype), arguments) + } - return newMessage.join('\n'); - }, - set: function (v) { - message = v; - } - }); + function ReadStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + if (that.autoClose) + that.destroy() - var stackDescriptor = Object.getOwnPropertyDescriptor(this, 'stack'); - var stackGetter = stackDescriptor.get; - var stackValue = stackDescriptor.value; - delete stackDescriptor.value; - delete stackDescriptor.writable; + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) + that.read() + } + }) + } - stackDescriptor.get = function () { - var stack = (stackGetter) - ? stackGetter.call(this).split(/\r?\n+/g) - : stackValue.split(/\r?\n+/g); + function WriteStream (path, options) { + if (this instanceof WriteStream) + return fs$WriteStream.apply(this, arguments), this + else + return WriteStream.apply(Object.create(WriteStream.prototype), arguments) + } - // starting in Node 7, the stack builder caches the message. - // just replace it. - stack[0] = this.name + ': ' + this.message; + function WriteStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + that.destroy() + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) + } + }) + } - var lineCount = 1; - for (var key in properties) { - if (!properties.hasOwnProperty(key)) { - continue; - } + function createReadStream (path, options) { + return new ReadStream(path, options) + } - var modifier = properties[key]; + function createWriteStream (path, options) { + return new WriteStream(path, options) + } - if ('line' in modifier) { - var line = modifier.line(this[key]); - if (line) { - stack.splice(lineCount++, 0, ' ' + line); - } - } + var fs$open = fs.open + fs.open = open + function open (path, flags, mode, cb) { + if (typeof mode === 'function') + cb = mode, mode = null - if ('stack' in modifier) { - modifier.stack(this[key], stack); - } - } + return go$open(path, flags, mode, cb) - return stack.join('\n'); - }; - - Object.defineProperty(this, 'stack', stackDescriptor); - }; - - if (Object.setPrototypeOf) { - Object.setPrototypeOf(errorExError.prototype, Error.prototype); - Object.setPrototypeOf(errorExError, Error); - } else { - util.inherits(errorExError, Error); - } - - return errorExError; -}; - -errorEx.append = function (str, def) { - return { - message: function (v, message) { - v = v || def; - - if (v) { - message[0] += ' ' + str.replace('%s', v.toString()); - } - - return message; - } - }; -}; - -errorEx.line = function (str, def) { - return { - line: function (v) { - v = v || def; + function go$open (path, flags, mode, cb) { + return fs$open(path, flags, mode, function (err, fd) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$open, [path, flags, mode, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } - if (v) { - return str.replace('%s', v.toString()); - } + return fs +} - return null; - } - }; -}; +function enqueue (elem) { + debug('ENQUEUE', elem[0].name, elem[1]) + queue.push(elem) +} -module.exports = errorEx; +function retry () { + var elem = queue.shift() + if (elem) { + debug('RETRY', elem[0].name, elem[1]) + elem[0].apply(null, elem[1]) + } +} /***/ }), -/* 430 */ +/* 410 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - - -module.exports = function isArrayish(obj) { - if (!obj) { - return false; - } - - return obj instanceof Array || Array.isArray(obj) || - (obj.length >= 0 && obj.splice instanceof Function); -}; - +var constants = __webpack_require__(411) -/***/ }), -/* 431 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; +var origCwd = process.cwd +var cwd = null +var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform -module.exports = parseJson -function parseJson (txt, reviver, context) { - context = context || 20 - try { - return JSON.parse(txt, reviver) - } catch (e) { - const syntaxErr = e.message.match(/^Unexpected token.*position\s+(\d+)/i) - const errIdx = syntaxErr - ? +syntaxErr[1] - : e.message.match(/^Unexpected end of JSON.*/i) - ? txt.length - 1 - : null - if (errIdx != null) { - const start = errIdx <= context - ? 0 - : errIdx - context - const end = errIdx + context >= txt.length - ? txt.length - : errIdx + context - e.message += ` while parsing near '${ - start === 0 ? '' : '...' - }${txt.slice(start, end)}${ - end === txt.length ? '' : '...' - }'` - } else { - e.message += ` while parsing '${txt.slice(0, context * 2)}'` - } - throw e - } +process.cwd = function() { + if (!cwd) + cwd = origCwd.call(process) + return cwd } +try { + process.cwd() +} catch (er) {} +var chdir = process.chdir +process.chdir = function(d) { + cwd = null + chdir.call(process, d) +} -/***/ }), -/* 432 */ -/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -var LF = '\n'; -var CR = '\r'; -var LinesAndColumns = (function () { - function LinesAndColumns(string) { - this.string = string; - var offsets = [0]; - for (var offset = 0; offset < string.length;) { - switch (string[offset]) { - case LF: - offset += LF.length; - offsets.push(offset); - break; - case CR: - offset += CR.length; - if (string[offset] === LF) { - offset += LF.length; - } - offsets.push(offset); - break; - default: - offset++; - break; - } - } - this.offsets = offsets; - } - LinesAndColumns.prototype.locationForIndex = function (index) { - if (index < 0 || index > this.string.length) { - return null; - } - var line = 0; - var offsets = this.offsets; - while (offsets[line + 1] <= index) { - line++; - } - var column = index - offsets[line]; - return { line: line, column: column }; - }; - LinesAndColumns.prototype.indexForLocation = function (location) { - var line = location.line, column = location.column; - if (line < 0 || line >= this.offsets.length) { - return null; - } - if (column < 0 || column > this.lengthOfLine(line)) { - return null; - } - return this.offsets[line] + column; - }; - LinesAndColumns.prototype.lengthOfLine = function (line) { - var offset = this.offsets[line]; - var nextOffset = line === this.offsets.length - 1 ? this.string.length : this.offsets[line + 1]; - return nextOffset - offset; - }; - return LinesAndColumns; -}()); -/* harmony default export */ __webpack_exports__["default"] = (LinesAndColumns); - - -/***/ }), -/* 433 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports = patch -"use strict"; +function patch (fs) { + // (re-)implement some things that are known busted or missing. + // lchmod, broken prior to 0.6.2 + // back-port the fix here. + if (constants.hasOwnProperty('O_SYMLINK') && + process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { + patchLchmod(fs) + } -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.codeFrameColumns = codeFrameColumns; -exports.default = _default; + // lutimes implementation, or no-op + if (!fs.lutimes) { + patchLutimes(fs) + } -var _highlight = _interopRequireWildcard(__webpack_require__(434)); + // https://github.com/isaacs/node-graceful-fs/issues/4 + // Chown should not fail on einval or eperm if non-root. + // It should not fail on enosys ever, as this just indicates + // that a fs doesn't support the intended operation. -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + fs.chown = chownFix(fs.chown) + fs.fchown = chownFix(fs.fchown) + fs.lchown = chownFix(fs.lchown) -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + fs.chmod = chmodFix(fs.chmod) + fs.fchmod = chmodFix(fs.fchmod) + fs.lchmod = chmodFix(fs.lchmod) -let deprecationWarningShown = false; + fs.chownSync = chownFixSync(fs.chownSync) + fs.fchownSync = chownFixSync(fs.fchownSync) + fs.lchownSync = chownFixSync(fs.lchownSync) -function getDefs(chalk) { - return { - gutter: chalk.grey, - marker: chalk.red.bold, - message: chalk.red.bold - }; -} + fs.chmodSync = chmodFixSync(fs.chmodSync) + fs.fchmodSync = chmodFixSync(fs.fchmodSync) + fs.lchmodSync = chmodFixSync(fs.lchmodSync) -const NEWLINE = /\r\n|[\n\r\u2028\u2029]/; + fs.stat = statFix(fs.stat) + fs.fstat = statFix(fs.fstat) + fs.lstat = statFix(fs.lstat) -function getMarkerLines(loc, source, opts) { - const startLoc = Object.assign({ - column: 0, - line: -1 - }, loc.start); - const endLoc = Object.assign({}, startLoc, {}, loc.end); - const { - linesAbove = 2, - linesBelow = 3 - } = opts || {}; - const startLine = startLoc.line; - const startColumn = startLoc.column; - const endLine = endLoc.line; - const endColumn = endLoc.column; - let start = Math.max(startLine - (linesAbove + 1), 0); - let end = Math.min(source.length, endLine + linesBelow); + fs.statSync = statFixSync(fs.statSync) + fs.fstatSync = statFixSync(fs.fstatSync) + fs.lstatSync = statFixSync(fs.lstatSync) - if (startLine === -1) { - start = 0; + // if lchmod/lchown do not exist, then make them no-ops + if (!fs.lchmod) { + fs.lchmod = function (path, mode, cb) { + if (cb) process.nextTick(cb) + } + fs.lchmodSync = function () {} } - - if (endLine === -1) { - end = source.length; + if (!fs.lchown) { + fs.lchown = function (path, uid, gid, cb) { + if (cb) process.nextTick(cb) + } + fs.lchownSync = function () {} } - const lineDiff = endLine - startLine; - const markerLines = {}; + // on Windows, A/V software can lock the directory, causing this + // to fail with an EACCES or EPERM if the directory contains newly + // created files. Try again on failure, for up to 60 seconds. - if (lineDiff) { - for (let i = 0; i <= lineDiff; i++) { - const lineNumber = i + startLine; + // Set the timeout this long because some Windows Anti-Virus, such as Parity + // bit9, may lock files for up to a minute, causing npm package install + // failures. Also, take care to yield the scheduler. Windows scheduling gives + // CPU to a busy looping process, which can cause the program causing the lock + // contention to be starved of CPU by node, so the contention doesn't resolve. + if (platform === "win32") { + fs.rename = (function (fs$rename) { return function (from, to, cb) { + var start = Date.now() + var backoff = 0; + fs$rename(from, to, function CB (er) { + if (er + && (er.code === "EACCES" || er.code === "EPERM") + && Date.now() - start < 60000) { + setTimeout(function() { + fs.stat(to, function (stater, st) { + if (stater && stater.code === "ENOENT") + fs$rename(from, to, CB); + else + cb(er) + }) + }, backoff) + if (backoff < 100) + backoff += 10; + return; + } + if (cb) cb(er) + }) + }})(fs.rename) + } - if (!startColumn) { - markerLines[lineNumber] = true; - } else if (i === 0) { - const sourceLength = source[lineNumber - 1].length; - markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1]; - } else if (i === lineDiff) { - markerLines[lineNumber] = [0, endColumn]; - } else { - const sourceLength = source[lineNumber - i].length; - markerLines[lineNumber] = [0, sourceLength]; + // if read() returns EAGAIN, then just try it again. + fs.read = (function (fs$read) { return function (fd, buffer, offset, length, position, callback_) { + var callback + if (callback_ && typeof callback_ === 'function') { + var eagCounter = 0 + callback = function (er, _, __) { + if (er && er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + } + callback_.apply(this, arguments) } } - } else { - if (startColumn === endColumn) { - if (startColumn) { - markerLines[startLine] = [startColumn, 0]; - } else { - markerLines[startLine] = true; + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + }})(fs.read) + + fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { + var eagCounter = 0 + while (true) { + try { + return fs$readSync.call(fs, fd, buffer, offset, length, position) + } catch (er) { + if (er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + continue + } + throw er } - } else { - markerLines[startLine] = [startColumn, endColumn - startColumn]; } - } - - return { - start, - end, - markerLines - }; -} - -function codeFrameColumns(rawLines, loc, opts = {}) { - const highlighted = (opts.highlightCode || opts.forceColor) && (0, _highlight.shouldHighlight)(opts); - const chalk = (0, _highlight.getChalk)(opts); - const defs = getDefs(chalk); + }})(fs.readSync) - const maybeHighlight = (chalkFn, string) => { - return highlighted ? chalkFn(string) : string; - }; + function patchLchmod (fs) { + fs.lchmod = function (path, mode, callback) { + fs.open( path + , constants.O_WRONLY | constants.O_SYMLINK + , mode + , function (err, fd) { + if (err) { + if (callback) callback(err) + return + } + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + fs.fchmod(fd, mode, function (err) { + fs.close(fd, function(err2) { + if (callback) callback(err || err2) + }) + }) + }) + } - const lines = rawLines.split(NEWLINE); - const { - start, - end, - markerLines - } = getMarkerLines(loc, lines, opts); - const hasColumns = loc.start && typeof loc.start.column === "number"; - const numberMaxWidth = String(end).length; - const highlightedLines = highlighted ? (0, _highlight.default)(rawLines, opts) : rawLines; - let frame = highlightedLines.split(NEWLINE).slice(start, end).map((line, index) => { - const number = start + 1 + index; - const paddedNumber = ` ${number}`.slice(-numberMaxWidth); - const gutter = ` ${paddedNumber} | `; - const hasMarker = markerLines[number]; - const lastMarkerLine = !markerLines[number + 1]; + fs.lchmodSync = function (path, mode) { + var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) - if (hasMarker) { - let markerLine = ""; + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + var threw = true + var ret + try { + ret = fs.fchmodSync(fd, mode) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } + } + return ret + } + } - if (Array.isArray(hasMarker)) { - const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, " "); - const numberOfMarkers = hasMarker[1] || 1; - markerLine = ["\n ", maybeHighlight(defs.gutter, gutter.replace(/\d/g, " ")), markerSpacing, maybeHighlight(defs.marker, "^").repeat(numberOfMarkers)].join(""); + function patchLutimes (fs) { + if (constants.hasOwnProperty("O_SYMLINK")) { + fs.lutimes = function (path, at, mt, cb) { + fs.open(path, constants.O_SYMLINK, function (er, fd) { + if (er) { + if (cb) cb(er) + return + } + fs.futimes(fd, at, mt, function (er) { + fs.close(fd, function (er2) { + if (cb) cb(er || er2) + }) + }) + }) + } - if (lastMarkerLine && opts.message) { - markerLine += " " + maybeHighlight(defs.message, opts.message); + fs.lutimesSync = function (path, at, mt) { + var fd = fs.openSync(path, constants.O_SYMLINK) + var ret + var threw = true + try { + ret = fs.futimesSync(fd, at, mt) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } } + return ret } - return [maybeHighlight(defs.marker, ">"), maybeHighlight(defs.gutter, gutter), line, markerLine].join(""); } else { - return ` ${maybeHighlight(defs.gutter, gutter)}${line}`; + fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } + fs.lutimesSync = function () {} } - }).join("\n"); - - if (opts.message && !hasColumns) { - frame = `${" ".repeat(numberMaxWidth + 1)}${opts.message}\n${frame}`; } - if (highlighted) { - return chalk.reset(frame); - } else { - return frame; + function chmodFix (orig) { + if (!orig) return orig + return function (target, mode, cb) { + return orig.call(fs, target, mode, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } } -} - -function _default(rawLines, lineNumber, colNumber, opts = {}) { - if (!deprecationWarningShown) { - deprecationWarningShown = true; - const message = "Passing lineNumber and colNumber is deprecated to @babel/code-frame. Please use `codeFrameColumns`."; - if (process.emitWarning) { - process.emitWarning(message, "DeprecationWarning"); - } else { - const deprecationError = new Error(message); - deprecationError.name = "DeprecationWarning"; - console.warn(new Error(message)); + function chmodFixSync (orig) { + if (!orig) return orig + return function (target, mode) { + try { + return orig.call(fs, target, mode) + } catch (er) { + if (!chownErOk(er)) throw er + } } } - colNumber = Math.max(colNumber, 0); - const location = { - start: { - column: colNumber, - line: lineNumber - } - }; - return codeFrameColumns(rawLines, location, opts); -} - -/***/ }), -/* 434 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.shouldHighlight = shouldHighlight; -exports.getChalk = getChalk; -exports.default = highlight; - -var _jsTokens = _interopRequireWildcard(__webpack_require__(435)); - -var _helperValidatorIdentifier = __webpack_require__(436); - -var _chalk = _interopRequireDefault(__webpack_require__(439)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function getDefs(chalk) { - return { - keyword: chalk.cyan, - capitalized: chalk.yellow, - jsx_tag: chalk.yellow, - punctuator: chalk.yellow, - number: chalk.magenta, - string: chalk.green, - regex: chalk.magenta, - comment: chalk.grey, - invalid: chalk.white.bgRed.bold - }; -} - -const NEWLINE = /\r\n|[\n\r\u2028\u2029]/; -const JSX_TAG = /^[a-z][\w-]*$/i; -const BRACKET = /^[()[\]{}]$/; - -function getTokenType(match) { - const [offset, text] = match.slice(-2); - const token = (0, _jsTokens.matchToToken)(match); - - if (token.type === "name") { - if ((0, _helperValidatorIdentifier.isKeyword)(token.value) || (0, _helperValidatorIdentifier.isReservedWord)(token.value)) { - return "keyword"; - } - if (JSX_TAG.test(token.value) && (text[offset - 1] === "<" || text.substr(offset - 2, 2) == " colorize(str)).join("\n"); - } else { - return args[0]; + var nonroot = !process.getuid || process.getuid() !== 0 + if (nonroot) { + if (er.code === "EINVAL" || er.code === "EPERM") + return true } - }); -} - -function shouldHighlight(options) { - return _chalk.default.supportsColor || options.forceColor; -} - -function getChalk(options) { - let chalk = _chalk.default; - if (options.forceColor) { - chalk = new _chalk.default.constructor({ - enabled: true, - level: 1 - }); + return false } - - return chalk; } -function highlight(code, options = {}) { - if (shouldHighlight(options)) { - const chalk = getChalk(options); - const defs = getDefs(chalk); - return highlightTokens(defs, code); - } else { - return code; - } -} /***/ }), -/* 435 */ +/* 411 */ /***/ (function(module, exports) { -// Copyright 2014, 2015, 2016, 2017, 2018 Simon Lydell -// License: MIT. (See LICENSE.) - -Object.defineProperty(exports, "__esModule", { - value: true -}) - -// This regex comes from regex.coffee, and is inserted here by generate-index.js -// (run `npm run build`). -exports.default = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyus]{1,6}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g - -exports.matchToToken = function(match) { - var token = {type: "invalid", value: match[0], closed: undefined} - if (match[ 1]) token.type = "string" , token.closed = !!(match[3] || match[4]) - else if (match[ 5]) token.type = "comment" - else if (match[ 6]) token.type = "comment", token.closed = !!match[7] - else if (match[ 8]) token.type = "regex" - else if (match[ 9]) token.type = "number" - else if (match[10]) token.type = "name" - else if (match[11]) token.type = "punctuator" - else if (match[12]) token.type = "whitespace" - return token -} - +module.exports = require("constants"); /***/ }), -/* 436 */ +/* 412 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var Stream = __webpack_require__(382).Stream +module.exports = legacy -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "isIdentifierName", { - enumerable: true, - get: function () { - return _identifier.isIdentifierName; - } -}); -Object.defineProperty(exports, "isIdentifierChar", { - enumerable: true, - get: function () { - return _identifier.isIdentifierChar; - } -}); -Object.defineProperty(exports, "isIdentifierStart", { - enumerable: true, - get: function () { - return _identifier.isIdentifierStart; - } -}); -Object.defineProperty(exports, "isReservedWord", { - enumerable: true, - get: function () { - return _keyword.isReservedWord; - } -}); -Object.defineProperty(exports, "isStrictBindOnlyReservedWord", { - enumerable: true, - get: function () { - return _keyword.isStrictBindOnlyReservedWord; - } -}); -Object.defineProperty(exports, "isStrictBindReservedWord", { - enumerable: true, - get: function () { - return _keyword.isStrictBindReservedWord; - } -}); -Object.defineProperty(exports, "isStrictReservedWord", { - enumerable: true, - get: function () { - return _keyword.isStrictReservedWord; - } -}); -Object.defineProperty(exports, "isKeyword", { - enumerable: true, - get: function () { - return _keyword.isKeyword; +function legacy (fs) { + return { + ReadStream: ReadStream, + WriteStream: WriteStream } -}); -var _identifier = __webpack_require__(437); + function ReadStream (path, options) { + if (!(this instanceof ReadStream)) return new ReadStream(path, options); -var _keyword = __webpack_require__(438); + Stream.call(this); -/***/ }), -/* 437 */ -/***/ (function(module, exports, __webpack_require__) { + var self = this; -"use strict"; + this.path = path; + this.fd = null; + this.readable = true; + this.paused = false; + this.flags = 'r'; + this.mode = 438; /*=0666*/ + this.bufferSize = 64 * 1024; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.isIdentifierStart = isIdentifierStart; -exports.isIdentifierChar = isIdentifierChar; -exports.isIdentifierName = isIdentifierName; -let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08c7\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\u9ffc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7ca\ua7f5-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; -let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf\u1ac0\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; -const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); -const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); -nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; -const astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 107, 20, 28, 22, 13, 52, 76, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 85, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 230, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 35, 56, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 190, 0, 80, 921, 103, 110, 18, 195, 2749, 1070, 4050, 582, 8634, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8952, 286, 50, 2, 18, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 2357, 44, 11, 6, 17, 0, 370, 43, 1301, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42717, 35, 4148, 12, 221, 3, 5761, 15, 7472, 3104, 541, 1507, 4938]; -const astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 154, 10, 176, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 19306, 9, 135, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 262, 6, 10, 9, 419, 13, 1495, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; + options = options || {}; -function isInAstralSet(code, set) { - let pos = 0x10000; + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } - for (let i = 0, length = set.length; i < length; i += 2) { - pos += set[i]; - if (pos > code) return false; - pos += set[i + 1]; - if (pos >= code) return true; - } + if (this.encoding) this.setEncoding(this.encoding); - return false; -} + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.end === undefined) { + this.end = Infinity; + } else if ('number' !== typeof this.end) { + throw TypeError('end must be a Number'); + } -function isIdentifierStart(code) { - if (code < 65) return code === 36; - if (code <= 90) return true; - if (code < 97) return code === 95; - if (code <= 122) return true; + if (this.start > this.end) { + throw new Error('start must be <= end'); + } - if (code <= 0xffff) { - return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)); - } + this.pos = this.start; + } - return isInAstralSet(code, astralIdentifierStartCodes); -} + if (this.fd !== null) { + process.nextTick(function() { + self._read(); + }); + return; + } -function isIdentifierChar(code) { - if (code < 48) return code === 36; - if (code < 58) return true; - if (code < 65) return false; - if (code <= 90) return true; - if (code < 97) return code === 95; - if (code <= 122) return true; + fs.open(this.path, this.flags, this.mode, function (err, fd) { + if (err) { + self.emit('error', err); + self.readable = false; + return; + } - if (code <= 0xffff) { - return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)); + self.fd = fd; + self.emit('open', fd); + self._read(); + }) } - return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes); -} + function WriteStream (path, options) { + if (!(this instanceof WriteStream)) return new WriteStream(path, options); -function isIdentifierName(name) { - let isFirst = true; + Stream.call(this); - for (let _i = 0, _Array$from = Array.from(name); _i < _Array$from.length; _i++) { - const char = _Array$from[_i]; - const cp = char.codePointAt(0); + this.path = path; + this.fd = null; + this.writable = true; - if (isFirst) { - if (!isIdentifierStart(cp)) { - return false; + this.flags = 'w'; + this.encoding = 'binary'; + this.mode = 438; /*=0666*/ + this.bytesWritten = 0; + + options = options || {}; + + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } + + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.start < 0) { + throw new Error('start must be >= zero'); } - isFirst = false; - } else if (!isIdentifierChar(cp)) { - return false; + this.pos = this.start; } - } - return true; + this.busy = false; + this._queue = []; + + if (this.fd === null) { + this._open = fs.open; + this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); + this.flush(); + } + } } + /***/ }), -/* 438 */ +/* 413 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.isReservedWord = isReservedWord; -exports.isStrictReservedWord = isStrictReservedWord; -exports.isStrictBindOnlyReservedWord = isStrictBindOnlyReservedWord; -exports.isStrictBindReservedWord = isStrictBindReservedWord; -exports.isKeyword = isKeyword; -const reservedWords = { - keyword: ["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete"], - strict: ["implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"], - strictBind: ["eval", "arguments"] -}; -const keywords = new Set(reservedWords.keyword); -const reservedWordsStrictSet = new Set(reservedWords.strict); -const reservedWordsStrictBindSet = new Set(reservedWords.strictBind); +module.exports = clone -function isReservedWord(word, inModule) { - return inModule && word === "await" || word === "enum"; -} +function clone (obj) { + if (obj === null || typeof obj !== 'object') + return obj -function isStrictReservedWord(word, inModule) { - return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word); -} + if (obj instanceof Object) + var copy = { __proto__: obj.__proto__ } + else + var copy = Object.create(null) -function isStrictBindOnlyReservedWord(word) { - return reservedWordsStrictBindSet.has(word); -} + Object.getOwnPropertyNames(obj).forEach(function (key) { + Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) + }) -function isStrictBindReservedWord(word, inModule) { - return isStrictReservedWord(word, inModule) || isStrictBindOnlyReservedWord(word); + return copy } -function isKeyword(word) { - return keywords.has(word); -} /***/ }), -/* 439 */ +/* 414 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const escapeStringRegexp = __webpack_require__(3); -const ansiStyles = __webpack_require__(440); -const stdoutColor = __webpack_require__(441).stdout; -const template = __webpack_require__(442); +module.exports = string => { + if (typeof string !== 'string') { + throw new TypeError(`Expected a string, got ${typeof string}`); + } -const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); + // Catches EFBBBF (UTF-8 BOM) because the buffer-to-string + // conversion translates it to FEFF (UTF-16 BOM) + if (string.charCodeAt(0) === 0xFEFF) { + return string.slice(1); + } -// `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; + return string; +}; -// `color-convert` models to exclude from the Chalk API due to conflicts and such -const skipModels = new Set(['gray']); -const styles = Object.create(null); +/***/ }), +/* 415 */ +/***/ (function(module, exports, __webpack_require__) { -function applyOptions(obj, options) { - options = options || {}; +"use strict"; - // Detect level if not set manually - const scLevel = stdoutColor ? stdoutColor.level : 0; - obj.level = options.level === undefined ? scLevel : options.level; - obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; -} +const errorEx = __webpack_require__(416); +const fallback = __webpack_require__(418); +const {default: LinesAndColumns} = __webpack_require__(419); +const {codeFrameColumns} = __webpack_require__(420); -function Chalk(options) { - // We check for this.template here since calling `chalk.constructor()` - // by itself will have a `this` of a previously constructed chalk object - if (!this || !(this instanceof Chalk) || this.template) { - const chalk = {}; - applyOptions(chalk, options); +const JSONError = errorEx('JSONError', { + fileName: errorEx.append('in %s'), + codeFrame: errorEx.append('\n\n%s\n') +}); - chalk.template = function () { - const args = [].slice.call(arguments); - return chalkTag.apply(null, [chalk.template].concat(args)); - }; +module.exports = (string, reviver, filename) => { + if (typeof reviver === 'string') { + filename = reviver; + reviver = null; + } - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); + try { + try { + return JSON.parse(string, reviver); + } catch (error) { + fallback(string, reviver); + throw error; + } + } catch (error) { + error.message = error.message.replace(/\n/g, ''); + const indexMatch = error.message.match(/in JSON at position (\d+) while parsing near/); - chalk.template.constructor = Chalk; + const jsonError = new JSONError(error); + if (filename) { + jsonError.fileName = filename; + } - return chalk.template; - } + if (indexMatch && indexMatch.length > 0) { + const lines = new LinesAndColumns(string); + const index = Number(indexMatch[1]); + const location = lines.locationForIndex(index); - applyOptions(this, options); -} - -// Use bright blue on Windows as the normal blue color is illegible -if (isSimpleWindowsTerm) { - ansiStyles.blue.open = '\u001B[94m'; -} - -for (const key of Object.keys(ansiStyles)) { - ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); + const codeFrame = codeFrameColumns( + string, + {start: {line: location.line + 1, column: location.column + 1}}, + {highlightCode: true} + ); - styles[key] = { - get() { - const codes = ansiStyles[key]; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); + jsonError.codeFrame = codeFrame; } - }; -} -styles.visible = { - get() { - return build.call(this, this._styles || [], true, 'visible'); + throw jsonError; } }; -ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); -for (const model of Object.keys(ansiStyles.color.ansi)) { - if (skipModels.has(model)) { - continue; - } - styles[model] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.color.close, - closeRe: ansiStyles.color.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} +/***/ }), +/* 416 */ +/***/ (function(module, exports, __webpack_require__) { -ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); -for (const model of Object.keys(ansiStyles.bgColor.ansi)) { - if (skipModels.has(model)) { - continue; +"use strict"; + + +var util = __webpack_require__(397); +var isArrayish = __webpack_require__(417); + +var errorEx = function errorEx(name, properties) { + if (!name || name.constructor !== String) { + properties = name || {}; + name = Error.name; } - const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); - styles[bgModel] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.bgColor.close, - closeRe: ansiStyles.bgColor.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; + var errorExError = function ErrorEXError(message) { + if (!this) { + return new ErrorEXError(message); } - }; -} -const proto = Object.defineProperties(() => {}, styles); + message = message instanceof Error + ? message.message + : (message || this.message); -function build(_styles, _empty, key) { - const builder = function () { - return applyStyle.apply(builder, arguments); - }; + Error.call(this, message); + Error.captureStackTrace(this, errorExError); - builder._styles = _styles; - builder._empty = _empty; + this.name = name; - const self = this; + Object.defineProperty(this, 'message', { + configurable: true, + enumerable: false, + get: function () { + var newMessage = message.split(/\r?\n/g); - Object.defineProperty(builder, 'level', { - enumerable: true, - get() { - return self.level; - }, - set(level) { - self.level = level; - } - }); + for (var key in properties) { + if (!properties.hasOwnProperty(key)) { + continue; + } - Object.defineProperty(builder, 'enabled', { - enumerable: true, - get() { - return self.enabled; - }, - set(enabled) { - self.enabled = enabled; - } - }); + var modifier = properties[key]; - // See below for fix regarding invisible grey/dim combination on Windows - builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; + if ('message' in modifier) { + newMessage = modifier.message(this[key], newMessage) || newMessage; + if (!isArrayish(newMessage)) { + newMessage = [newMessage]; + } + } + } - // `__proto__` is used because we must return a function, but there is - // no way to create a function with a different prototype - builder.__proto__ = proto; // eslint-disable-line no-proto + return newMessage.join('\n'); + }, + set: function (v) { + message = v; + } + }); - return builder; -} + var stackDescriptor = Object.getOwnPropertyDescriptor(this, 'stack'); + var stackGetter = stackDescriptor.get; + var stackValue = stackDescriptor.value; + delete stackDescriptor.value; + delete stackDescriptor.writable; -function applyStyle() { - // Support varags, but simply cast to string in case there's only one arg - const args = arguments; - const argsLen = args.length; - let str = String(arguments[0]); + stackDescriptor.get = function () { + var stack = (stackGetter) + ? stackGetter.call(this).split(/\r?\n+/g) + : stackValue.split(/\r?\n+/g); - if (argsLen === 0) { - return ''; - } + // starting in Node 7, the stack builder caches the message. + // just replace it. + stack[0] = this.name + ': ' + this.message; - if (argsLen > 1) { - // Don't slice `arguments`, it prevents V8 optimizations - for (let a = 1; a < argsLen; a++) { - str += ' ' + args[a]; - } - } + var lineCount = 1; + for (var key in properties) { + if (!properties.hasOwnProperty(key)) { + continue; + } - if (!this.enabled || this.level <= 0 || !str) { - return this._empty ? '' : str; - } + var modifier = properties[key]; - // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, - // see https://github.com/chalk/chalk/issues/58 - // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. - const originalDim = ansiStyles.dim.open; - if (isSimpleWindowsTerm && this.hasGrey) { - ansiStyles.dim.open = ''; - } + if ('line' in modifier) { + var line = modifier.line(this[key]); + if (line) { + stack.splice(lineCount++, 0, ' ' + line); + } + } - for (const code of this._styles.slice().reverse()) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - str = code.open + str.replace(code.closeRe, code.open) + code.close; + if ('stack' in modifier) { + modifier.stack(this[key], stack); + } + } - // Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS - // https://github.com/chalk/chalk/pull/92 - str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); + return stack.join('\n'); + }; + + Object.defineProperty(this, 'stack', stackDescriptor); + }; + + if (Object.setPrototypeOf) { + Object.setPrototypeOf(errorExError.prototype, Error.prototype); + Object.setPrototypeOf(errorExError, Error); + } else { + util.inherits(errorExError, Error); } - // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue - ansiStyles.dim.open = originalDim; + return errorExError; +}; - return str; -} +errorEx.append = function (str, def) { + return { + message: function (v, message) { + v = v || def; -function chalkTag(chalk, strings) { - if (!Array.isArray(strings)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return [].slice.call(arguments, 1).join(' '); - } + if (v) { + message[0] += ' ' + str.replace('%s', v.toString()); + } - const args = [].slice.call(arguments, 2); - const parts = [strings.raw[0]]; + return message; + } + }; +}; - for (let i = 1; i < strings.length; i++) { - parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); - parts.push(String(strings.raw[i])); - } +errorEx.line = function (str, def) { + return { + line: function (v) { + v = v || def; - return template(chalk, parts.join('')); -} + if (v) { + return str.replace('%s', v.toString()); + } -Object.defineProperties(Chalk.prototype, styles); + return null; + } + }; +}; -module.exports = Chalk(); // eslint-disable-line new-cap -module.exports.supportsColor = stdoutColor; -module.exports.default = module.exports; // For TypeScript +module.exports = errorEx; /***/ }), -/* 440 */ +/* 417 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(6); -const wrapAnsi16 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${code + offset}m`; -}; -const wrapAnsi256 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};5;${code}m`; -}; +module.exports = function isArrayish(obj) { + if (!obj) { + return false; + } -const wrapAnsi16m = (fn, offset) => function () { - const rgb = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; + return obj instanceof Array || Array.isArray(obj) || + (obj.length >= 0 && obj.splice instanceof Function); }; -function assembleStyles() { - const codes = new Map(); - const styles = { - modifier: { - reset: [0, 0], - // 21 isn't widely supported and 22 does the same thing - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - gray: [90, 39], - - // Bright color - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39] - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], - // Bright color - bgBlackBright: [100, 49], - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49] - } - }; +/***/ }), +/* 418 */ +/***/ (function(module, exports, __webpack_require__) { - // Fix humans - styles.color.grey = styles.color.gray; +"use strict"; - for (const groupName of Object.keys(styles)) { - const group = styles[groupName]; - for (const styleName of Object.keys(group)) { - const style = group[styleName]; +module.exports = parseJson +function parseJson (txt, reviver, context) { + context = context || 20 + try { + return JSON.parse(txt, reviver) + } catch (e) { + const syntaxErr = e.message.match(/^Unexpected token.*position\s+(\d+)/i) + const errIdx = syntaxErr + ? +syntaxErr[1] + : e.message.match(/^Unexpected end of JSON.*/i) + ? txt.length - 1 + : null + if (errIdx != null) { + const start = errIdx <= context + ? 0 + : errIdx - context + const end = errIdx + context >= txt.length + ? txt.length + : errIdx + context + e.message += ` while parsing near '${ + start === 0 ? '' : '...' + }${txt.slice(start, end)}${ + end === txt.length ? '' : '...' + }'` + } else { + e.message += ` while parsing '${txt.slice(0, context * 2)}'` + } + throw e + } +} - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m` - }; - group[styleName] = styles[styleName]; +/***/ }), +/* 419 */ +/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) { - codes.set(style[0], style[1]); - } +"use strict"; +__webpack_require__.r(__webpack_exports__); +var LF = '\n'; +var CR = '\r'; +var LinesAndColumns = (function () { + function LinesAndColumns(string) { + this.string = string; + var offsets = [0]; + for (var offset = 0; offset < string.length;) { + switch (string[offset]) { + case LF: + offset += LF.length; + offsets.push(offset); + break; + case CR: + offset += CR.length; + if (string[offset] === LF) { + offset += LF.length; + } + offsets.push(offset); + break; + default: + offset++; + break; + } + } + this.offsets = offsets; + } + LinesAndColumns.prototype.locationForIndex = function (index) { + if (index < 0 || index > this.string.length) { + return null; + } + var line = 0; + var offsets = this.offsets; + while (offsets[line + 1] <= index) { + line++; + } + var column = index - offsets[line]; + return { line: line, column: column }; + }; + LinesAndColumns.prototype.indexForLocation = function (location) { + var line = location.line, column = location.column; + if (line < 0 || line >= this.offsets.length) { + return null; + } + if (column < 0 || column > this.lengthOfLine(line)) { + return null; + } + return this.offsets[line] + column; + }; + LinesAndColumns.prototype.lengthOfLine = function (line) { + var offset = this.offsets[line]; + var nextOffset = line === this.offsets.length - 1 ? this.string.length : this.offsets[line + 1]; + return nextOffset - offset; + }; + return LinesAndColumns; +}()); +/* harmony default export */ __webpack_exports__["default"] = (LinesAndColumns); - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); - } +/***/ }), +/* 420 */ +/***/ (function(module, exports, __webpack_require__) { - const ansi2ansi = n => n; - const rgb2rgb = (r, g, b) => [r, g, b]; +"use strict"; - styles.color.close = '\u001B[39m'; - styles.bgColor.close = '\u001B[49m'; - styles.color.ansi = { - ansi: wrapAnsi16(ansi2ansi, 0) - }; - styles.color.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 0) - }; - styles.color.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 0) - }; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.codeFrameColumns = codeFrameColumns; +exports.default = _default; - styles.bgColor.ansi = { - ansi: wrapAnsi16(ansi2ansi, 10) - }; - styles.bgColor.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 10) - }; - styles.bgColor.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 10) - }; +var _highlight = _interopRequireWildcard(__webpack_require__(421)); - for (let key of Object.keys(colorConvert)) { - if (typeof colorConvert[key] !== 'object') { - continue; - } +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - const suite = colorConvert[key]; +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - if (key === 'ansi16') { - key = 'ansi'; - } +let deprecationWarningShown = false; - if ('ansi16' in suite) { - styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); - styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); - } +function getDefs(chalk) { + return { + gutter: chalk.grey, + marker: chalk.red.bold, + message: chalk.red.bold + }; +} - if ('ansi256' in suite) { - styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); - styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); - } +const NEWLINE = /\r\n|[\n\r\u2028\u2029]/; - if ('rgb' in suite) { - styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); - styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); - } - } +function getMarkerLines(loc, source, opts) { + const startLoc = Object.assign({ + column: 0, + line: -1 + }, loc.start); + const endLoc = Object.assign({}, startLoc, {}, loc.end); + const { + linesAbove = 2, + linesBelow = 3 + } = opts || {}; + const startLine = startLoc.line; + const startColumn = startLoc.column; + const endLine = endLoc.line; + const endColumn = endLoc.column; + let start = Math.max(startLine - (linesAbove + 1), 0); + let end = Math.min(source.length, endLine + linesBelow); - return styles; -} + if (startLine === -1) { + start = 0; + } -// Make the export immutable -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); + if (endLine === -1) { + end = source.length; + } -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(5)(module))) + const lineDiff = endLine - startLine; + const markerLines = {}; -/***/ }), -/* 441 */ -/***/ (function(module, exports, __webpack_require__) { + if (lineDiff) { + for (let i = 0; i <= lineDiff; i++) { + const lineNumber = i + startLine; -"use strict"; + if (!startColumn) { + markerLines[lineNumber] = true; + } else if (i === 0) { + const sourceLength = source[lineNumber - 1].length; + markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1]; + } else if (i === lineDiff) { + markerLines[lineNumber] = [0, endColumn]; + } else { + const sourceLength = source[lineNumber - i].length; + markerLines[lineNumber] = [0, sourceLength]; + } + } + } else { + if (startColumn === endColumn) { + if (startColumn) { + markerLines[startLine] = [startColumn, 0]; + } else { + markerLines[startLine] = true; + } + } else { + markerLines[startLine] = [startColumn, endColumn - startColumn]; + } + } -const os = __webpack_require__(11); -const hasFlag = __webpack_require__(12); + return { + start, + end, + markerLines + }; +} -const env = process.env; +function codeFrameColumns(rawLines, loc, opts = {}) { + const highlighted = (opts.highlightCode || opts.forceColor) && (0, _highlight.shouldHighlight)(opts); + const chalk = (0, _highlight.getChalk)(opts); + const defs = getDefs(chalk); -let forceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false')) { - forceColor = false; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - forceColor = true; -} -if ('FORCE_COLOR' in env) { - forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; -} + const maybeHighlight = (chalkFn, string) => { + return highlighted ? chalkFn(string) : string; + }; -function translateLevel(level) { - if (level === 0) { - return false; - } + const lines = rawLines.split(NEWLINE); + const { + start, + end, + markerLines + } = getMarkerLines(loc, lines, opts); + const hasColumns = loc.start && typeof loc.start.column === "number"; + const numberMaxWidth = String(end).length; + const highlightedLines = highlighted ? (0, _highlight.default)(rawLines, opts) : rawLines; + let frame = highlightedLines.split(NEWLINE).slice(start, end).map((line, index) => { + const number = start + 1 + index; + const paddedNumber = ` ${number}`.slice(-numberMaxWidth); + const gutter = ` ${paddedNumber} | `; + const hasMarker = markerLines[number]; + const lastMarkerLine = !markerLines[number + 1]; - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} + if (hasMarker) { + let markerLine = ""; -function supportsColor(stream) { - if (forceColor === false) { - return 0; - } + if (Array.isArray(hasMarker)) { + const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, " "); + const numberOfMarkers = hasMarker[1] || 1; + markerLine = ["\n ", maybeHighlight(defs.gutter, gutter.replace(/\d/g, " ")), markerSpacing, maybeHighlight(defs.marker, "^").repeat(numberOfMarkers)].join(""); - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } + if (lastMarkerLine && opts.message) { + markerLine += " " + maybeHighlight(defs.message, opts.message); + } + } - if (hasFlag('color=256')) { - return 2; - } + return [maybeHighlight(defs.marker, ">"), maybeHighlight(defs.gutter, gutter), line, markerLine].join(""); + } else { + return ` ${maybeHighlight(defs.gutter, gutter)}${line}`; + } + }).join("\n"); - if (stream && !stream.isTTY && forceColor !== true) { - // VS code debugger doesn't have isTTY set - if (env.VSCODE_PID) { - return 1; - } - return 0; - } + if (opts.message && !hasColumns) { + frame = `${" ".repeat(numberMaxWidth + 1)}${opts.message}\n${frame}`; + } - const min = forceColor ? 1 : 0; + if (highlighted) { + return chalk.reset(frame); + } else { + return frame; + } +} - if (process.platform === 'win32') { - // Node.js 7.5.0 is the first version of Node.js to include a patch to - // libuv that enables 256 color output on Windows. Anything earlier and it - // won't work. However, here we target Node.js 8 at minimum as it is an LTS - // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows - // release that supports 256 colors. Windows 10 build 14931 is the first release - // that supports 16m/TrueColor. - const osRelease = os.release().split('.'); - if ( - Number(process.versions.node.split('.')[0]) >= 8 && - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } +function _default(rawLines, lineNumber, colNumber, opts = {}) { + if (!deprecationWarningShown) { + deprecationWarningShown = true; + const message = "Passing lineNumber and colNumber is deprecated to @babel/code-frame. Please use `codeFrameColumns`."; - return 1; - } + if (process.emitWarning) { + process.emitWarning(message, "DeprecationWarning"); + } else { + const deprecationError = new Error(message); + deprecationError.name = "DeprecationWarning"; + console.warn(new Error(message)); + } + } - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; - } + colNumber = Math.max(colNumber, 0); + const location = { + start: { + column: colNumber, + line: lineNumber + } + }; + return codeFrameColumns(rawLines, location, opts); +} - return min; - } +/***/ }), +/* 421 */ +/***/ (function(module, exports, __webpack_require__) { - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } +"use strict"; - if (env.COLORTERM === 'truecolor') { - return 3; - } - if ('TERM_PROGRAM' in env) { - const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.shouldHighlight = shouldHighlight; +exports.getChalk = getChalk; +exports.default = highlight; - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } +var _jsTokens = _interopRequireWildcard(__webpack_require__(422)); - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } +var _helperValidatorIdentifier = __webpack_require__(423); - if (/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } +var _chalk = _interopRequireDefault(__webpack_require__(426)); - if ('COLORTERM' in env) { - return 1; - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - if (env.TERM === 'dumb') { - return min; - } +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - return min; -} +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } -function getSupportLevel(stream) { - const level = supportsColor(stream); - return translateLevel(level); +function getDefs(chalk) { + return { + keyword: chalk.cyan, + capitalized: chalk.yellow, + jsx_tag: chalk.yellow, + punctuator: chalk.yellow, + number: chalk.magenta, + string: chalk.green, + regex: chalk.magenta, + comment: chalk.grey, + invalid: chalk.white.bgRed.bold + }; } -module.exports = { - supportsColor: getSupportLevel, - stdout: getSupportLevel(process.stdout), - stderr: getSupportLevel(process.stderr) -}; +const NEWLINE = /\r\n|[\n\r\u2028\u2029]/; +const JSX_TAG = /^[a-z][\w-]*$/i; +const BRACKET = /^[()[\]{}]$/; +function getTokenType(match) { + const [offset, text] = match.slice(-2); + const token = (0, _jsTokens.matchToToken)(match); -/***/ }), -/* 442 */ -/***/ (function(module, exports, __webpack_require__) { + if (token.type === "name") { + if ((0, _helperValidatorIdentifier.isKeyword)(token.value) || (0, _helperValidatorIdentifier.isReservedWord)(token.value)) { + return "keyword"; + } -"use strict"; + if (JSX_TAG.test(token.value) && (text[offset - 1] === "<" || text.substr(offset - 2, 2) == " escape ? unescape(escape) : chr)); - } else { - throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); - } - } +function highlightTokens(defs, text) { + return text.replace(_jsTokens.default, function (...args) { + const type = getTokenType(args); + const colorize = defs[type]; - return results; + if (colorize) { + return args[0].split(NEWLINE).map(str => colorize(str)).join("\n"); + } else { + return args[0]; + } + }); } -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; +function shouldHighlight(options) { + return _chalk.default.supportsColor || options.forceColor; +} - const results = []; - let matches; +function getChalk(options) { + let chalk = _chalk.default; - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; + if (options.forceColor) { + chalk = new _chalk.default.constructor({ + enabled: true, + level: 1 + }); + } - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } - } + return chalk; +} - return results; +function highlight(code, options = {}) { + if (shouldHighlight(options)) { + const chalk = getChalk(options); + const defs = getDefs(chalk); + return highlightTokens(defs, code); + } else { + return code; + } } -function buildStyle(chalk, styles) { - const enabled = {}; +/***/ }), +/* 422 */ +/***/ (function(module, exports) { - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } - } +// Copyright 2014, 2015, 2016, 2017, 2018 Simon Lydell +// License: MIT. (See LICENSE.) - let current = chalk; - for (const styleName of Object.keys(enabled)) { - if (Array.isArray(enabled[styleName])) { - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } +Object.defineProperty(exports, "__esModule", { + value: true +}) - if (enabled[styleName].length > 0) { - current = current[styleName].apply(current, enabled[styleName]); - } else { - current = current[styleName]; - } - } - } +// This regex comes from regex.coffee, and is inserted here by generate-index.js +// (run `npm run build`). +exports.default = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyus]{1,6}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g - return current; +exports.matchToToken = function(match) { + var token = {type: "invalid", value: match[0], closed: undefined} + if (match[ 1]) token.type = "string" , token.closed = !!(match[3] || match[4]) + else if (match[ 5]) token.type = "comment" + else if (match[ 6]) token.type = "comment", token.closed = !!match[7] + else if (match[ 8]) token.type = "regex" + else if (match[ 9]) token.type = "number" + else if (match[10]) token.type = "name" + else if (match[11]) token.type = "punctuator" + else if (match[12]) token.type = "whitespace" + return token } -module.exports = (chalk, tmp) => { - const styles = []; - const chunks = []; - let chunk = []; - // eslint-disable-next-line max-params - tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { - if (escapeChar) { - chunk.push(unescape(escapeChar)); - } else if (style) { - const str = chunk.join(''); - chunk = []; - chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); - styles.push({inverse, styles: parseStyle(style)}); - } else if (close) { - if (styles.length === 0) { - throw new Error('Found extraneous } in Chalk template literal'); - } +/***/ }), +/* 423 */ +/***/ (function(module, exports, __webpack_require__) { - chunks.push(buildStyle(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(chr); - } - }); +"use strict"; - chunks.push(chunk.join('')); - if (styles.length > 0) { - const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMsg); - } +Object.defineProperty(exports, "__esModule", { + value: true +}); +Object.defineProperty(exports, "isIdentifierName", { + enumerable: true, + get: function () { + return _identifier.isIdentifierName; + } +}); +Object.defineProperty(exports, "isIdentifierChar", { + enumerable: true, + get: function () { + return _identifier.isIdentifierChar; + } +}); +Object.defineProperty(exports, "isIdentifierStart", { + enumerable: true, + get: function () { + return _identifier.isIdentifierStart; + } +}); +Object.defineProperty(exports, "isReservedWord", { + enumerable: true, + get: function () { + return _keyword.isReservedWord; + } +}); +Object.defineProperty(exports, "isStrictBindOnlyReservedWord", { + enumerable: true, + get: function () { + return _keyword.isStrictBindOnlyReservedWord; + } +}); +Object.defineProperty(exports, "isStrictBindReservedWord", { + enumerable: true, + get: function () { + return _keyword.isStrictBindReservedWord; + } +}); +Object.defineProperty(exports, "isStrictReservedWord", { + enumerable: true, + get: function () { + return _keyword.isStrictReservedWord; + } +}); +Object.defineProperty(exports, "isKeyword", { + enumerable: true, + get: function () { + return _keyword.isKeyword; + } +}); - return chunks.join(''); -}; +var _identifier = __webpack_require__(424); +var _keyword = __webpack_require__(425); /***/ }), -/* 443 */ +/* 424 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const path_1 = __webpack_require__(16); -exports.CA_CERT_PATH = path_1.resolve(__dirname, '../certs/ca.crt'); -exports.ES_KEY_PATH = path_1.resolve(__dirname, '../certs/elasticsearch.key'); -exports.ES_CERT_PATH = path_1.resolve(__dirname, '../certs/elasticsearch.crt'); -exports.ES_P12_PATH = path_1.resolve(__dirname, '../certs/elasticsearch.p12'); -exports.ES_P12_PASSWORD = 'storepass'; -exports.ES_EMPTYPASSWORD_P12_PATH = path_1.resolve(__dirname, '../certs/elasticsearch_emptypassword.p12'); -exports.ES_NOPASSWORD_P12_PATH = path_1.resolve(__dirname, '../certs/elasticsearch_nopassword.p12'); -exports.KBN_KEY_PATH = path_1.resolve(__dirname, '../certs/kibana.key'); -exports.KBN_CERT_PATH = path_1.resolve(__dirname, '../certs/kibana.crt'); -exports.KBN_P12_PATH = path_1.resolve(__dirname, '../certs/kibana.p12'); -exports.KBN_P12_PASSWORD = 'storepass'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.isIdentifierStart = isIdentifierStart; +exports.isIdentifierChar = isIdentifierChar; +exports.isIdentifierName = isIdentifierName; +let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08c7\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\u9ffc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7ca\ua7f5-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; +let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf\u1ac0\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; +const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); +const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); +nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; +const astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 107, 20, 28, 22, 13, 52, 76, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 85, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 230, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 35, 56, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 190, 0, 80, 921, 103, 110, 18, 195, 2749, 1070, 4050, 582, 8634, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8952, 286, 50, 2, 18, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 2357, 44, 11, 6, 17, 0, 370, 43, 1301, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42717, 35, 4148, 12, 221, 3, 5761, 15, 7472, 3104, 541, 1507, 4938]; +const astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 154, 10, 176, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 19306, 9, 135, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 262, 6, 10, 9, 419, 13, 1495, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; -/***/ }), -/* 444 */ -/***/ (function(module, exports, __webpack_require__) { +function isInAstralSet(code, set) { + let pos = 0x10000; -"use strict"; + for (let i = 0, length = set.length; i < length; i += 2) { + pos += set[i]; + if (pos > code) return false; + pos += set[i + 1]; + if (pos >= code) return true; + } -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -var run_1 = __webpack_require__(445); -exports.run = run_1.run; -var fail_1 = __webpack_require__(446); -exports.createFailError = fail_1.createFailError; -exports.createFlagError = fail_1.createFlagError; -exports.combineErrors = fail_1.combineErrors; -exports.isFailError = fail_1.isFailError; + return false; +} +function isIdentifierStart(code) { + if (code < 65) return code === 36; + if (code <= 90) return true; + if (code < 97) return code === 95; + if (code <= 122) return true; -/***/ }), -/* 445 */ -/***/ (function(module, exports, __webpack_require__) { + if (code <= 0xffff) { + return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)); + } -"use strict"; + return isInAstralSet(code, astralIdentifierStartCodes); +} -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const tslib_1 = __webpack_require__(36); -const util_1 = __webpack_require__(29); -// @ts-ignore @types are outdated and module is super simple -const exit_hook_1 = tslib_1.__importDefault(__webpack_require__(368)); -const tooling_log_1 = __webpack_require__(414); -const fail_1 = __webpack_require__(446); -const flags_1 = __webpack_require__(447); -const proc_runner_1 = __webpack_require__(37); -async function run(fn, options = {}) { - var _a; - const flags = flags_1.getFlags(process.argv.slice(2), options); - if (flags.help) { - process.stderr.write(flags_1.getHelp(options)); - process.exit(1); - } - const log = new tooling_log_1.ToolingLog({ - level: tooling_log_1.pickLevelFromFlags(flags), - writeTo: process.stdout, - }); - process.on('unhandledRejection', (error) => { - log.error('UNHANDLED PROMISE REJECTION'); - log.error(error instanceof Error - ? error - : new Error(`non-Error type rejection value: ${util_1.inspect(error)}`)); - process.exit(1); - }); - const handleErrorWithoutExit = (error) => { - if (fail_1.isFailError(error)) { - log.error(error.message); - if (error.showHelp) { - log.write(flags_1.getHelp(options)); - } - process.exitCode = error.exitCode; - } - else { - log.error('UNHANDLED ERROR'); - log.error(error); - process.exitCode = 1; - } - }; - const doCleanup = () => { - const tasks = cleanupTasks.slice(0); - cleanupTasks.length = 0; - for (const task of tasks) { - try { - task(); - } - catch (error) { - handleErrorWithoutExit(error); - } - } - }; - const unhookExit = exit_hook_1.default(doCleanup); - const cleanupTasks = [unhookExit]; - try { - if (!((_a = options.flags) === null || _a === void 0 ? void 0 : _a.allowUnexpected) && flags.unexpected.length) { - throw fail_1.createFlagError(`Unknown flag(s) "${flags.unexpected.join('", "')}"`); - } - try { - await proc_runner_1.withProcRunner(log, async (procRunner) => { - await fn({ - log, - flags, - procRunner, - addCleanupTask: (task) => cleanupTasks.push(task), - }); - }); - } - finally { - doCleanup(); - } - } - catch (error) { - handleErrorWithoutExit(error); - process.exit(); - } +function isIdentifierChar(code) { + if (code < 48) return code === 36; + if (code < 58) return true; + if (code < 65) return false; + if (code <= 90) return true; + if (code < 97) return code === 95; + if (code <= 122) return true; + + if (code <= 0xffff) { + return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)); + } + + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes); } -exports.run = run; +function isIdentifierName(name) { + let isFirst = true; -/***/ }), -/* 446 */ -/***/ (function(module, exports, __webpack_require__) { + for (let _i = 0, _Array$from = Array.from(name); _i < _Array$from.length; _i++) { + const char = _Array$from[_i]; + const cp = char.codePointAt(0); -"use strict"; + if (isFirst) { + if (!isIdentifierStart(cp)) { + return false; + } -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const util_1 = __webpack_require__(29); -const FAIL_TAG = Symbol('fail error'); -function createFailError(reason, options = {}) { - const { exitCode = 1, showHelp = false } = options; - return Object.assign(new Error(reason), { - exitCode, - showHelp, - [FAIL_TAG]: true, - }); -} -exports.createFailError = createFailError; -function createFlagError(reason) { - return createFailError(reason, { - showHelp: true, - }); -} -exports.createFlagError = createFlagError; -function isFailError(error) { - return Boolean(error && error[FAIL_TAG]); -} -exports.isFailError = isFailError; -function combineErrors(errors) { - if (errors.length === 1) { - return errors[0]; + isFirst = false; + } else if (!isIdentifierChar(cp)) { + return false; } - const exitCode = errors - .filter(isFailError) - .reduce((acc, error) => Math.max(acc, error.exitCode), 1); - const showHelp = errors.some((error) => isFailError(error) && error.showHelp); - const message = errors.reduce((acc, error) => { - if (isFailError(error)) { - return acc + '\n' + error.message; - } - return acc + `\nUNHANDLED ERROR\n${util_1.inspect(error)}`; - }, ''); - return createFailError(`${errors.length} errors:\n${message}`, { - exitCode, - showHelp, - }); -} -exports.combineErrors = combineErrors; + } + return true; +} /***/ }), -/* 447 */ +/* 425 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const tslib_1 = __webpack_require__(36); -const path_1 = __webpack_require__(16); -const dedent_1 = tslib_1.__importDefault(__webpack_require__(14)); -const getopts_1 = tslib_1.__importDefault(__webpack_require__(448)); -function getFlags(argv, options) { - const unexpectedNames = new Set(); - const flagOpts = options.flags || {}; - const { verbose, quiet, silent, debug, help, _, ...others } = getopts_1.default(argv, { - string: flagOpts.string, - boolean: [...(flagOpts.boolean || []), 'verbose', 'quiet', 'silent', 'debug', 'help'], - alias: { - ...(flagOpts.alias || {}), - v: 'verbose', - }, - default: flagOpts.default, - unknown: (name) => { - unexpectedNames.add(name); - return flagOpts.guessTypesForUnexpectedFlags; - }, - }); - const unexpected = []; - for (const unexpectedName of unexpectedNames) { - const matchingArgv = []; - iterArgv: for (const [i, v] of argv.entries()) { - for (const prefix of ['--', '-']) { - if (v.startsWith(prefix)) { - // -/--name=value - if (v.startsWith(`${prefix}${unexpectedName}=`)) { - matchingArgv.push(v); - continue iterArgv; - } - // -/--name (value possibly follows) - if (v === `${prefix}${unexpectedName}`) { - matchingArgv.push(v); - // value follows -/--name - if (argv.length > i + 1 && !argv[i + 1].startsWith('-')) { - matchingArgv.push(argv[i + 1]); - } - continue iterArgv; - } - } - } - // special case for `--no-{flag}` disabling of boolean flags - if (v === `--no-${unexpectedName}`) { - matchingArgv.push(v); - continue iterArgv; - } - // special case for shortcut flags formatted as `-abc` where `a`, `b`, - // and `c` will be three separate unexpected flags - if (unexpectedName.length === 1 && - v[0] === '-' && - v[1] !== '-' && - !v.includes('=') && - v.includes(unexpectedName)) { - matchingArgv.push(`-${unexpectedName}`); - continue iterArgv; - } - } - if (matchingArgv.length) { - unexpected.push(...matchingArgv); - } - else { - throw new Error(`unable to find unexpected flag named "${unexpectedName}"`); - } - } - return { - verbose, - quiet, - silent, - debug, - help, - _, - unexpected, - ...others, - }; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.isReservedWord = isReservedWord; +exports.isStrictReservedWord = isStrictReservedWord; +exports.isStrictBindOnlyReservedWord = isStrictBindOnlyReservedWord; +exports.isStrictBindReservedWord = isStrictBindReservedWord; +exports.isKeyword = isKeyword; +const reservedWords = { + keyword: ["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete"], + strict: ["implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"], + strictBind: ["eval", "arguments"] +}; +const keywords = new Set(reservedWords.keyword); +const reservedWordsStrictSet = new Set(reservedWords.strict); +const reservedWordsStrictBindSet = new Set(reservedWords.strictBind); + +function isReservedWord(word, inModule) { + return inModule && word === "await" || word === "enum"; } -exports.getFlags = getFlags; -function getHelp(options) { - var _a, _b; - const usage = options.usage || `node ${path_1.relative(process.cwd(), process.argv[1])}`; - const optionHelp = (dedent_1.default(((_b = (_a = options) === null || _a === void 0 ? void 0 : _a.flags) === null || _b === void 0 ? void 0 : _b.help) || '') + - '\n' + - dedent_1.default ` - --verbose, -v Log verbosely - --debug Log debug messages (less than verbose) - --quiet Only log errors - --silent Don't log anything - --help Show this message - `) - .split('\n') - .filter(Boolean) - .join('\n '); - return ` - ${usage} - ${dedent_1.default(options.description || 'Runs a dev task') - .split('\n') - .join('\n ')} +function isStrictReservedWord(word, inModule) { + return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word); +} - Options: - ${optionHelp + '\n\n'}`; +function isStrictBindOnlyReservedWord(word) { + return reservedWordsStrictBindSet.has(word); +} + +function isStrictBindReservedWord(word, inModule) { + return isStrictReservedWord(word, inModule) || isStrictBindOnlyReservedWord(word); } -exports.getHelp = getHelp; +function isKeyword(word) { + return keywords.has(word); +} /***/ }), -/* 448 */ +/* 426 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const escapeStringRegexp = __webpack_require__(387); +const ansiStyles = __webpack_require__(427); +const stdoutColor = __webpack_require__(428).stdout; -const EMPTYARR = [] -const SHORTSPLIT = /$|[!-@[-`{-~][\s\S]*/g -const isArray = Array.isArray +const template = __webpack_require__(429); -const parseValue = function(any) { - if (any === "") return "" - if (any === "false") return false - const maybe = Number(any) - return maybe * 0 === 0 ? maybe : any -} +const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); -const parseAlias = function(aliases) { - let out = {}, - key, - alias, - prev, - len, - any, - i, - k +// `supportsColor.level` → `ansiStyles.color[name]` mapping +const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; - for (key in aliases) { - any = aliases[key] - alias = out[key] = isArray(any) ? any : [any] +// `color-convert` models to exclude from the Chalk API due to conflicts and such +const skipModels = new Set(['gray']); - for (i = 0, len = alias.length; i < len; i++) { - prev = out[alias[i]] = [key] +const styles = Object.create(null); - for (k = 0; k < len; k++) { - if (i !== k) prev.push(alias[k]) - } - } - } +function applyOptions(obj, options) { + options = options || {}; - return out + // Detect level if not set manually + const scLevel = stdoutColor ? stdoutColor.level : 0; + obj.level = options.level === undefined ? scLevel : options.level; + obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; } -const parseDefault = function(aliases, defaults) { - let out = {}, - key, - alias, - value, - len, - i +function Chalk(options) { + // We check for this.template here since calling `chalk.constructor()` + // by itself will have a `this` of a previously constructed chalk object + if (!this || !(this instanceof Chalk) || this.template) { + const chalk = {}; + applyOptions(chalk, options); - for (key in defaults) { - value = defaults[key] - alias = aliases[key] + chalk.template = function () { + const args = [].slice.call(arguments); + return chalkTag.apply(null, [chalk.template].concat(args)); + }; - out[key] = value + Object.setPrototypeOf(chalk, Chalk.prototype); + Object.setPrototypeOf(chalk.template, chalk); - if (alias === undefined) { - aliases[key] = EMPTYARR - } else { - for (i = 0, len = alias.length; i < len; i++) { - out[alias[i]] = value - } - } - } + chalk.template.constructor = Chalk; - return out + return chalk.template; + } + + applyOptions(this, options); } -const parseOptions = function(aliases, options, value) { - let out = {}, - key, - alias, - len, - end, - i, - k +// Use bright blue on Windows as the normal blue color is illegible +if (isSimpleWindowsTerm) { + ansiStyles.blue.open = '\u001B[94m'; +} - if (options !== undefined) { - for (i = 0, len = options.length; i < len; i++) { - key = options[i] - alias = aliases[key] - - out[key] = value - - if (alias === undefined) { - aliases[key] = EMPTYARR - } else { - for (k = 0, end = alias.length; k < end; k++) { - out[alias[k]] = value - } - } - } - } +for (const key of Object.keys(ansiStyles)) { + ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); - return out + styles[key] = { + get() { + const codes = ansiStyles[key]; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); + } + }; } -const write = function(out, key, value, aliases, unknown) { - let i, - prev, - alias = aliases[key], - len = alias === undefined ? -1 : alias.length - - if (len >= 0 || unknown === undefined || unknown(key)) { - prev = out[key] +styles.visible = { + get() { + return build.call(this, this._styles || [], true, 'visible'); + } +}; - if (prev === undefined) { - out[key] = value - } else { - if (isArray(prev)) { - prev.push(value) - } else { - out[key] = [prev, value] - } - } +ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); +for (const model of Object.keys(ansiStyles.color.ansi)) { + if (skipModels.has(model)) { + continue; + } - for (i = 0; i < len; i++) { - out[alias[i]] = out[key] - } - } + styles[model] = { + get() { + const level = this.level; + return function () { + const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); + const codes = { + open, + close: ansiStyles.color.close, + closeRe: ansiStyles.color.closeRe + }; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + }; + } + }; } -const getopts = function(argv, opts) { - let unknown = (opts = opts || {}).unknown, - aliases = parseAlias(opts.alias), - strings = parseOptions(aliases, opts.string, ""), - values = parseDefault(aliases, opts.default), - bools = parseOptions(aliases, opts.boolean, false), - stopEarly = opts.stopEarly, - _ = [], - out = { _ }, - i = 0, - k = 0, - len = argv.length, - key, - arg, - end, - match, - value - - for (; i < len; i++) { - arg = argv[i] - - if (arg[0] !== "-" || arg === "-") { - if (stopEarly) while (i < len) _.push(argv[i++]) - else _.push(arg) - } else if (arg === "--") { - while (++i < len) _.push(argv[i]) - } else if (arg[1] === "-") { - end = arg.indexOf("=", 2) - if (arg[2] === "n" && arg[3] === "o" && arg[4] === "-") { - key = arg.slice(5, end >= 0 ? end : undefined) - value = false - } else if (end >= 0) { - key = arg.slice(2, end) - value = - bools[key] !== undefined || - (strings[key] === undefined - ? parseValue(arg.slice(end + 1)) - : arg.slice(end + 1)) - } else { - key = arg.slice(2) - value = - bools[key] !== undefined || - (len === i + 1 || argv[i + 1][0] === "-" - ? strings[key] === undefined - ? true - : "" - : strings[key] === undefined - ? parseValue(argv[++i]) - : argv[++i]) - } - write(out, key, value, aliases, unknown) - } else { - SHORTSPLIT.lastIndex = 2 - match = SHORTSPLIT.exec(arg) - end = match.index - value = match[0] - - for (k = 1; k < end; k++) { - write( - out, - (key = arg[k]), - k + 1 < end - ? strings[key] === undefined || - arg.substring(k + 1, (k = end)) + value - : value === "" - ? len === i + 1 || argv[i + 1][0] === "-" - ? strings[key] === undefined || "" - : bools[key] !== undefined || - (strings[key] === undefined ? parseValue(argv[++i]) : argv[++i]) - : bools[key] !== undefined || - (strings[key] === undefined ? parseValue(value) : value), - aliases, - unknown - ) - } - } - } - - for (key in values) if (out[key] === undefined) out[key] = values[key] - for (key in bools) if (out[key] === undefined) out[key] = false - for (key in strings) if (out[key] === undefined) out[key] = "" +ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); +for (const model of Object.keys(ansiStyles.bgColor.ansi)) { + if (skipModels.has(model)) { + continue; + } - return out + const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); + styles[bgModel] = { + get() { + const level = this.level; + return function () { + const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); + const codes = { + open, + close: ansiStyles.bgColor.close, + closeRe: ansiStyles.bgColor.closeRe + }; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + }; + } + }; } -module.exports = getopts - - -/***/ }), -/* 449 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -var kbn_client_1 = __webpack_require__(450); -exports.KbnClient = kbn_client_1.KbnClient; -var kbn_client_requester_1 = __webpack_require__(451); -exports.uriencode = kbn_client_requester_1.uriencode; +const proto = Object.defineProperties(() => {}, styles); +function build(_styles, _empty, key) { + const builder = function () { + return applyStyle.apply(builder, arguments); + }; -/***/ }), -/* 450 */ -/***/ (function(module, exports, __webpack_require__) { + builder._styles = _styles; + builder._empty = _empty; -"use strict"; + const self = this; -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const kbn_client_requester_1 = __webpack_require__(451); -const kbn_client_status_1 = __webpack_require__(494); -const kbn_client_plugins_1 = __webpack_require__(495); -const kbn_client_version_1 = __webpack_require__(496); -const kbn_client_saved_objects_1 = __webpack_require__(497); -const kbn_client_ui_settings_1 = __webpack_require__(498); -class KbnClient { - /** - * Basic Kibana server client that implements common behaviors for talking - * to the Kibana server from dev tooling. - * - * @param log ToolingLog - * @param kibanaUrls Array of kibana server urls to send requests to - * @param uiSettingDefaults Map of uiSetting values that will be merged with all uiSetting resets - */ - constructor(log, kibanaUrls, uiSettingDefaults) { - this.log = log; - this.kibanaUrls = kibanaUrls; - this.uiSettingDefaults = uiSettingDefaults; - this.requester = new kbn_client_requester_1.KbnClientRequester(this.log, this.kibanaUrls); - this.status = new kbn_client_status_1.KbnClientStatus(this.requester); - this.plugins = new kbn_client_plugins_1.KbnClientPlugins(this.status); - this.version = new kbn_client_version_1.KbnClientVersion(this.status); - this.savedObjects = new kbn_client_saved_objects_1.KbnClientSavedObjects(this.log, this.requester); - this.uiSettings = new kbn_client_ui_settings_1.KbnClientUiSettings(this.log, this.requester, this.uiSettingDefaults); - if (!kibanaUrls.length) { - throw new Error('missing Kibana urls'); - } - } - /** - * Make a direct request to the Kibana server - */ - async request(options) { - return await this.requester.request(options); - } - resolveUrl(relativeUrl) { - return this.requester.resolveUrl(relativeUrl); - } -} -exports.KbnClient = KbnClient; + Object.defineProperty(builder, 'level', { + enumerable: true, + get() { + return self.level; + }, + set(level) { + self.level = level; + } + }); + Object.defineProperty(builder, 'enabled', { + enumerable: true, + get() { + return self.enabled; + }, + set(enabled) { + self.enabled = enabled; + } + }); -/***/ }), -/* 451 */ -/***/ (function(module, exports, __webpack_require__) { + // See below for fix regarding invisible grey/dim combination on Windows + builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; -"use strict"; + // `__proto__` is used because we must return a function, but there is + // no way to create a function with a different prototype + builder.__proto__ = proto; // eslint-disable-line no-proto -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const tslib_1 = __webpack_require__(36); -const url_1 = tslib_1.__importDefault(__webpack_require__(452)); -const axios_1 = tslib_1.__importDefault(__webpack_require__(453)); -const axios_2 = __webpack_require__(492); -const isConcliftOnGetError = (error) => { - return (axios_2.isAxiosResponseError(error) && error.config.method === 'GET' && error.response.status === 409); -}; -exports.uriencode = (strings, ...values) => { - const queue = strings.slice(); - if (queue.length === 0) { - throw new Error('how could strings passed to `uriencode` template tag be empty?'); - } - if (queue.length !== values.length + 1) { - throw new Error('strings and values passed to `uriencode` template tag are unbalanced'); - } - // pull the first string off the queue, there is one less item in `values` - // since the values are always wrapped in strings, so we shift the extra string - // off the queue to balance the queue and values array. - const leadingString = queue.shift(); - return queue.reduce((acc, string, i) => `${acc}${encodeURIComponent(values[i])}${string}`, leadingString); -}; -const DEFAULT_MAX_ATTEMPTS = 5; -const delay = (ms) => new Promise((resolve) => { - setTimeout(resolve, ms); -}); -class KbnClientRequester { - constructor(log, kibanaUrls) { - this.log = log; - this.kibanaUrls = kibanaUrls; - } - pickUrl() { - const url = this.kibanaUrls.shift(); - this.kibanaUrls.push(url); - return url; - } - resolveUrl(relativeUrl = '/') { - return url_1.default.resolve(this.pickUrl(), relativeUrl); - } - async request(options) { - var _a; - const url = url_1.default.resolve(this.pickUrl(), options.path); - const description = options.description || `${options.method} ${url}`; - let attempt = 0; - const maxAttempts = (_a = options.retries, (_a !== null && _a !== void 0 ? _a : DEFAULT_MAX_ATTEMPTS)); - while (true) { - attempt += 1; - try { - const response = await axios_1.default.request({ - method: options.method, - url, - data: options.body, - params: options.query, - headers: { - 'kbn-xsrf': 'kbn-client', - }, - }); - return response.data; - } - catch (error) { - const conflictOnGet = isConcliftOnGetError(error); - const requestedRetries = options.retries !== undefined; - const failedToGetResponse = axios_2.isAxiosRequestError(error); - let errorMessage; - if (conflictOnGet) { - errorMessage = `Conflict on GET (path=${options.path}, attempt=${attempt}/${maxAttempts})`; - this.log.error(errorMessage); - } - else if (requestedRetries || failedToGetResponse) { - errorMessage = `[${description}] request failed (attempt=${attempt}/${maxAttempts})`; - this.log.error(errorMessage); - } - else { - throw error; - } - if (attempt < maxAttempts) { - await delay(1000 * attempt); - continue; - } - throw new Error(`${errorMessage} -- and ran out of retries`); - } - } - } + return builder; } -exports.KbnClientRequester = KbnClientRequester; - - -/***/ }), -/* 452 */ -/***/ (function(module, exports) { - -module.exports = require("url"); - -/***/ }), -/* 453 */ -/***/ (function(module, exports, __webpack_require__) { -module.exports = __webpack_require__(454); +function applyStyle() { + // Support varags, but simply cast to string in case there's only one arg + const args = arguments; + const argsLen = args.length; + let str = String(arguments[0]); -/***/ }), -/* 454 */ -/***/ (function(module, exports, __webpack_require__) { + if (argsLen === 0) { + return ''; + } -"use strict"; + if (argsLen > 1) { + // Don't slice `arguments`, it prevents V8 optimizations + for (let a = 1; a < argsLen; a++) { + str += ' ' + args[a]; + } + } + if (!this.enabled || this.level <= 0 || !str) { + return this._empty ? '' : str; + } -var utils = __webpack_require__(455); -var bind = __webpack_require__(456); -var Axios = __webpack_require__(457); -var mergeConfig = __webpack_require__(488); -var defaults = __webpack_require__(463); + // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, + // see https://github.com/chalk/chalk/issues/58 + // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. + const originalDim = ansiStyles.dim.open; + if (isSimpleWindowsTerm && this.hasGrey) { + ansiStyles.dim.open = ''; + } -/** - * Create an instance of Axios - * - * @param {Object} defaultConfig The default config for the instance - * @return {Axios} A new instance of Axios - */ -function createInstance(defaultConfig) { - var context = new Axios(defaultConfig); - var instance = bind(Axios.prototype.request, context); + for (const code of this._styles.slice().reverse()) { + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code + // will be colored, and the rest will simply be 'plain'. + str = code.open + str.replace(code.closeRe, code.open) + code.close; - // Copy axios.prototype to instance - utils.extend(instance, Axios.prototype, context); + // Close the styling before a linebreak and reopen + // after next line to fix a bleed issue on macOS + // https://github.com/chalk/chalk/pull/92 + str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); + } - // Copy context to instance - utils.extend(instance, context); + // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue + ansiStyles.dim.open = originalDim; - return instance; + return str; } -// Create the default instance to be exported -var axios = createInstance(defaults); - -// Expose Axios class to allow class inheritance -axios.Axios = Axios; +function chalkTag(chalk, strings) { + if (!Array.isArray(strings)) { + // If chalk() was called by itself or with a string, + // return the string itself as a string. + return [].slice.call(arguments, 1).join(' '); + } -// Factory for creating new instances -axios.create = function create(instanceConfig) { - return createInstance(mergeConfig(axios.defaults, instanceConfig)); -}; + const args = [].slice.call(arguments, 2); + const parts = [strings.raw[0]]; -// Expose Cancel & CancelToken -axios.Cancel = __webpack_require__(489); -axios.CancelToken = __webpack_require__(490); -axios.isCancel = __webpack_require__(462); + for (let i = 1; i < strings.length; i++) { + parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); + parts.push(String(strings.raw[i])); + } -// Expose all/spread -axios.all = function all(promises) { - return Promise.all(promises); -}; -axios.spread = __webpack_require__(491); + return template(chalk, parts.join('')); +} -module.exports = axios; +Object.defineProperties(Chalk.prototype, styles); -// Allow use of default import syntax in TypeScript -module.exports.default = axios; +module.exports = Chalk(); // eslint-disable-line new-cap +module.exports.supportsColor = stdoutColor; +module.exports.default = module.exports; // For TypeScript /***/ }), -/* 455 */ +/* 427 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +/* WEBPACK VAR INJECTION */(function(module) { +const colorConvert = __webpack_require__(389); +const wrapAnsi16 = (fn, offset) => function () { + const code = fn.apply(colorConvert, arguments); + return `\u001B[${code + offset}m`; +}; -var bind = __webpack_require__(456); - -/*global toString:true*/ - -// utils is a library of generic helper functions non-specific to axios +const wrapAnsi256 = (fn, offset) => function () { + const code = fn.apply(colorConvert, arguments); + return `\u001B[${38 + offset};5;${code}m`; +}; -var toString = Object.prototype.toString; +const wrapAnsi16m = (fn, offset) => function () { + const rgb = fn.apply(colorConvert, arguments); + return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; +}; -/** - * Determine if a value is an Array - * - * @param {Object} val The value to test - * @returns {boolean} True if value is an Array, otherwise false - */ -function isArray(val) { - return toString.call(val) === '[object Array]'; -} - -/** - * Determine if a value is undefined - * - * @param {Object} val The value to test - * @returns {boolean} True if the value is undefined, otherwise false - */ -function isUndefined(val) { - return typeof val === 'undefined'; -} - -/** - * Determine if a value is a Buffer - * - * @param {Object} val The value to test - * @returns {boolean} True if value is a Buffer, otherwise false - */ -function isBuffer(val) { - return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) - && typeof val.constructor.isBuffer === 'function' && val.constructor.isBuffer(val); -} - -/** - * Determine if a value is an ArrayBuffer - * - * @param {Object} val The value to test - * @returns {boolean} True if value is an ArrayBuffer, otherwise false - */ -function isArrayBuffer(val) { - return toString.call(val) === '[object ArrayBuffer]'; -} +function assembleStyles() { + const codes = new Map(); + const styles = { + modifier: { + reset: [0, 0], + // 21 isn't widely supported and 22 does the same thing + bold: [1, 22], + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29] + }, + color: { + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], + gray: [90, 39], -/** - * Determine if a value is a FormData - * - * @param {Object} val The value to test - * @returns {boolean} True if value is an FormData, otherwise false - */ -function isFormData(val) { - return (typeof FormData !== 'undefined') && (val instanceof FormData); -} + // Bright color + redBright: [91, 39], + greenBright: [92, 39], + yellowBright: [93, 39], + blueBright: [94, 39], + magentaBright: [95, 39], + cyanBright: [96, 39], + whiteBright: [97, 39] + }, + bgColor: { + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], -/** - * Determine if a value is a view on an ArrayBuffer - * - * @param {Object} val The value to test - * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false - */ -function isArrayBufferView(val) { - var result; - if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) { - result = ArrayBuffer.isView(val); - } else { - result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer); - } - return result; -} + // Bright color + bgBlackBright: [100, 49], + bgRedBright: [101, 49], + bgGreenBright: [102, 49], + bgYellowBright: [103, 49], + bgBlueBright: [104, 49], + bgMagentaBright: [105, 49], + bgCyanBright: [106, 49], + bgWhiteBright: [107, 49] + } + }; -/** - * Determine if a value is a String - * - * @param {Object} val The value to test - * @returns {boolean} True if value is a String, otherwise false - */ -function isString(val) { - return typeof val === 'string'; -} + // Fix humans + styles.color.grey = styles.color.gray; -/** - * Determine if a value is a Number - * - * @param {Object} val The value to test - * @returns {boolean} True if value is a Number, otherwise false - */ -function isNumber(val) { - return typeof val === 'number'; -} + for (const groupName of Object.keys(styles)) { + const group = styles[groupName]; -/** - * Determine if a value is an Object - * - * @param {Object} val The value to test - * @returns {boolean} True if value is an Object, otherwise false - */ -function isObject(val) { - return val !== null && typeof val === 'object'; -} + for (const styleName of Object.keys(group)) { + const style = group[styleName]; -/** - * Determine if a value is a Date - * - * @param {Object} val The value to test - * @returns {boolean} True if value is a Date, otherwise false - */ -function isDate(val) { - return toString.call(val) === '[object Date]'; -} + styles[styleName] = { + open: `\u001B[${style[0]}m`, + close: `\u001B[${style[1]}m` + }; -/** - * Determine if a value is a File - * - * @param {Object} val The value to test - * @returns {boolean} True if value is a File, otherwise false - */ -function isFile(val) { - return toString.call(val) === '[object File]'; -} + group[styleName] = styles[styleName]; -/** - * Determine if a value is a Blob - * - * @param {Object} val The value to test - * @returns {boolean} True if value is a Blob, otherwise false - */ -function isBlob(val) { - return toString.call(val) === '[object Blob]'; -} + codes.set(style[0], style[1]); + } -/** - * Determine if a value is a Function - * - * @param {Object} val The value to test - * @returns {boolean} True if value is a Function, otherwise false - */ -function isFunction(val) { - return toString.call(val) === '[object Function]'; -} + Object.defineProperty(styles, groupName, { + value: group, + enumerable: false + }); -/** - * Determine if a value is a Stream - * - * @param {Object} val The value to test - * @returns {boolean} True if value is a Stream, otherwise false - */ -function isStream(val) { - return isObject(val) && isFunction(val.pipe); -} + Object.defineProperty(styles, 'codes', { + value: codes, + enumerable: false + }); + } -/** - * Determine if a value is a URLSearchParams object - * - * @param {Object} val The value to test - * @returns {boolean} True if value is a URLSearchParams object, otherwise false - */ -function isURLSearchParams(val) { - return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams; -} + const ansi2ansi = n => n; + const rgb2rgb = (r, g, b) => [r, g, b]; -/** - * Trim excess whitespace off the beginning and end of a string - * - * @param {String} str The String to trim - * @returns {String} The String freed of excess whitespace - */ -function trim(str) { - return str.replace(/^\s*/, '').replace(/\s*$/, ''); -} + styles.color.close = '\u001B[39m'; + styles.bgColor.close = '\u001B[49m'; -/** - * Determine if we're running in a standard browser environment - * - * This allows axios to run in a web worker, and react-native. - * Both environments support XMLHttpRequest, but not fully standard globals. - * - * web workers: - * typeof window -> undefined - * typeof document -> undefined - * - * react-native: - * navigator.product -> 'ReactNative' - * nativescript - * navigator.product -> 'NativeScript' or 'NS' - */ -function isStandardBrowserEnv() { - if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' || - navigator.product === 'NativeScript' || - navigator.product === 'NS')) { - return false; - } - return ( - typeof window !== 'undefined' && - typeof document !== 'undefined' - ); -} + styles.color.ansi = { + ansi: wrapAnsi16(ansi2ansi, 0) + }; + styles.color.ansi256 = { + ansi256: wrapAnsi256(ansi2ansi, 0) + }; + styles.color.ansi16m = { + rgb: wrapAnsi16m(rgb2rgb, 0) + }; -/** - * Iterate over an Array or an Object invoking a function for each item. - * - * If `obj` is an Array callback will be called passing - * the value, index, and complete array for each item. - * - * If 'obj' is an Object callback will be called passing - * the value, key, and complete object for each property. - * - * @param {Object|Array} obj The object to iterate - * @param {Function} fn The callback to invoke for each item - */ -function forEach(obj, fn) { - // Don't bother if no value provided - if (obj === null || typeof obj === 'undefined') { - return; - } + styles.bgColor.ansi = { + ansi: wrapAnsi16(ansi2ansi, 10) + }; + styles.bgColor.ansi256 = { + ansi256: wrapAnsi256(ansi2ansi, 10) + }; + styles.bgColor.ansi16m = { + rgb: wrapAnsi16m(rgb2rgb, 10) + }; - // Force an array if not already something iterable - if (typeof obj !== 'object') { - /*eslint no-param-reassign:0*/ - obj = [obj]; - } + for (let key of Object.keys(colorConvert)) { + if (typeof colorConvert[key] !== 'object') { + continue; + } - if (isArray(obj)) { - // Iterate over array values - for (var i = 0, l = obj.length; i < l; i++) { - fn.call(null, obj[i], i, obj); - } - } else { - // Iterate over object keys - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - fn.call(null, obj[key], key, obj); - } - } - } -} + const suite = colorConvert[key]; -/** - * Accepts varargs expecting each argument to be an object, then - * immutably merges the properties of each object and returns result. - * - * When multiple objects contain the same key the later object in - * the arguments list will take precedence. - * - * Example: - * - * ```js - * var result = merge({foo: 123}, {foo: 456}); - * console.log(result.foo); // outputs 456 - * ``` - * - * @param {Object} obj1 Object to merge - * @returns {Object} Result of all merge properties - */ -function merge(/* obj1, obj2, obj3, ... */) { - var result = {}; - function assignValue(val, key) { - if (typeof result[key] === 'object' && typeof val === 'object') { - result[key] = merge(result[key], val); - } else { - result[key] = val; - } - } + if (key === 'ansi16') { + key = 'ansi'; + } - for (var i = 0, l = arguments.length; i < l; i++) { - forEach(arguments[i], assignValue); - } - return result; -} + if ('ansi16' in suite) { + styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); + styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); + } -/** - * Function equal to merge with the difference being that no reference - * to original objects is kept. - * - * @see merge - * @param {Object} obj1 Object to merge - * @returns {Object} Result of all merge properties - */ -function deepMerge(/* obj1, obj2, obj3, ... */) { - var result = {}; - function assignValue(val, key) { - if (typeof result[key] === 'object' && typeof val === 'object') { - result[key] = deepMerge(result[key], val); - } else if (typeof val === 'object') { - result[key] = deepMerge({}, val); - } else { - result[key] = val; - } - } + if ('ansi256' in suite) { + styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); + styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); + } - for (var i = 0, l = arguments.length; i < l; i++) { - forEach(arguments[i], assignValue); - } - return result; -} + if ('rgb' in suite) { + styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); + styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); + } + } -/** - * Extends object a by mutably adding to it the properties of object b. - * - * @param {Object} a The object to be extended - * @param {Object} b The object to copy properties from - * @param {Object} thisArg The object to bind function to - * @return {Object} The resulting value of object a - */ -function extend(a, b, thisArg) { - forEach(b, function assignValue(val, key) { - if (thisArg && typeof val === 'function') { - a[key] = bind(val, thisArg); - } else { - a[key] = val; - } - }); - return a; + return styles; } -module.exports = { - isArray: isArray, - isArrayBuffer: isArrayBuffer, - isBuffer: isBuffer, - isFormData: isFormData, - isArrayBufferView: isArrayBufferView, - isString: isString, - isNumber: isNumber, - isObject: isObject, - isUndefined: isUndefined, - isDate: isDate, - isFile: isFile, - isBlob: isBlob, - isFunction: isFunction, - isStream: isStream, - isURLSearchParams: isURLSearchParams, - isStandardBrowserEnv: isStandardBrowserEnv, - forEach: forEach, - merge: merge, - deepMerge: deepMerge, - extend: extend, - trim: trim -}; +// Make the export immutable +Object.defineProperty(module, 'exports', { + enumerable: true, + get: assembleStyles +}); +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(11)(module))) /***/ }), -/* 456 */ +/* 428 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const os = __webpack_require__(364); +const hasFlag = __webpack_require__(394); -module.exports = function bind(fn, thisArg) { - return function wrap() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i]; - } - return fn.apply(thisArg, args); - }; -}; - - -/***/ }), -/* 457 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; +const env = process.env; +let forceColor; +if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false')) { + forceColor = false; +} else if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + forceColor = true; +} +if ('FORCE_COLOR' in env) { + forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; +} -var utils = __webpack_require__(455); -var buildURL = __webpack_require__(458); -var InterceptorManager = __webpack_require__(459); -var dispatchRequest = __webpack_require__(460); -var mergeConfig = __webpack_require__(488); +function translateLevel(level) { + if (level === 0) { + return false; + } -/** - * Create a new instance of Axios - * - * @param {Object} instanceConfig The default config for the instance - */ -function Axios(instanceConfig) { - this.defaults = instanceConfig; - this.interceptors = { - request: new InterceptorManager(), - response: new InterceptorManager() - }; + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; } -/** - * Dispatch a request - * - * @param {Object} config The config specific for this request (merged with this.defaults) - */ -Axios.prototype.request = function request(config) { - /*eslint no-param-reassign:0*/ - // Allow for axios('example/url'[, config]) a la fetch API - if (typeof config === 'string') { - config = arguments[1] || {}; - config.url = arguments[0]; - } else { - config = config || {}; - } +function supportsColor(stream) { + if (forceColor === false) { + return 0; + } - config = mergeConfig(this.defaults, config); + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } - // Set config.method - if (config.method) { - config.method = config.method.toLowerCase(); - } else if (this.defaults.method) { - config.method = this.defaults.method.toLowerCase(); - } else { - config.method = 'get'; - } + if (hasFlag('color=256')) { + return 2; + } - // Hook up interceptors middleware - var chain = [dispatchRequest, undefined]; - var promise = Promise.resolve(config); + if (stream && !stream.isTTY && forceColor !== true) { + // VS code debugger doesn't have isTTY set + if (env.VSCODE_PID) { + return 1; + } + return 0; + } - this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { - chain.unshift(interceptor.fulfilled, interceptor.rejected); - }); + const min = forceColor ? 1 : 0; - this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { - chain.push(interceptor.fulfilled, interceptor.rejected); - }); + if (process.platform === 'win32') { + // Node.js 7.5.0 is the first version of Node.js to include a patch to + // libuv that enables 256 color output on Windows. Anything earlier and it + // won't work. However, here we target Node.js 8 at minimum as it is an LTS + // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows + // release that supports 256 colors. Windows 10 build 14931 is the first release + // that supports 16m/TrueColor. + const osRelease = os.release().split('.'); + if ( + Number(process.versions.node.split('.')[0]) >= 8 && + Number(osRelease[0]) >= 10 && + Number(osRelease[2]) >= 10586 + ) { + return Number(osRelease[2]) >= 14931 ? 3 : 2; + } - while (chain.length) { - promise = promise.then(chain.shift(), chain.shift()); - } + return 1; + } - return promise; -}; + if ('CI' in env) { + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } -Axios.prototype.getUri = function getUri(config) { - config = mergeConfig(this.defaults, config); - return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\?/, ''); -}; + return min; + } -// Provide aliases for supported request methods -utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) { - /*eslint func-names:0*/ - Axios.prototype[method] = function(url, config) { - return this.request(utils.merge(config || {}, { - method: method, - url: url - })); - }; -}); + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } -utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { - /*eslint func-names:0*/ - Axios.prototype[method] = function(url, data, config) { - return this.request(utils.merge(config || {}, { - method: method, - url: url, - data: data - })); - }; -}); + if (env.COLORTERM === 'truecolor') { + return 3; + } -module.exports = Axios; + if ('TERM_PROGRAM' in env) { + const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + switch (env.TERM_PROGRAM) { + case 'iTerm.app': + return version >= 3 ? 3 : 2; + case 'Apple_Terminal': + return 2; + // No default + } + } -/***/ }), -/* 458 */ -/***/ (function(module, exports, __webpack_require__) { + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } -"use strict"; + if (/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } + if ('COLORTERM' in env) { + return 1; + } -var utils = __webpack_require__(455); + if (env.TERM === 'dumb') { + return min; + } -function encode(val) { - return encodeURIComponent(val). - replace(/%40/gi, '@'). - replace(/%3A/gi, ':'). - replace(/%24/g, '$'). - replace(/%2C/gi, ','). - replace(/%20/g, '+'). - replace(/%5B/gi, '['). - replace(/%5D/gi, ']'); + return min; } -/** - * Build a URL by appending params to the end - * - * @param {string} url The base of the url (e.g., http://www.google.com) - * @param {object} [params] The params to be appended - * @returns {string} The formatted url - */ -module.exports = function buildURL(url, params, paramsSerializer) { - /*eslint no-param-reassign:0*/ - if (!params) { - return url; - } - - var serializedParams; - if (paramsSerializer) { - serializedParams = paramsSerializer(params); - } else if (utils.isURLSearchParams(params)) { - serializedParams = params.toString(); - } else { - var parts = []; - - utils.forEach(params, function serialize(val, key) { - if (val === null || typeof val === 'undefined') { - return; - } - - if (utils.isArray(val)) { - key = key + '[]'; - } else { - val = [val]; - } - - utils.forEach(val, function parseValue(v) { - if (utils.isDate(v)) { - v = v.toISOString(); - } else if (utils.isObject(v)) { - v = JSON.stringify(v); - } - parts.push(encode(key) + '=' + encode(v)); - }); - }); - - serializedParams = parts.join('&'); - } - - if (serializedParams) { - var hashmarkIndex = url.indexOf('#'); - if (hashmarkIndex !== -1) { - url = url.slice(0, hashmarkIndex); - } - - url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams; - } +function getSupportLevel(stream) { + const level = supportsColor(stream); + return translateLevel(level); +} - return url; +module.exports = { + supportsColor: getSupportLevel, + stdout: getSupportLevel(process.stdout), + stderr: getSupportLevel(process.stderr) }; /***/ }), -/* 459 */ +/* 429 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; +const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; +const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; +const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; -var utils = __webpack_require__(455); - -function InterceptorManager() { - this.handlers = []; -} +const ESCAPES = new Map([ + ['n', '\n'], + ['r', '\r'], + ['t', '\t'], + ['b', '\b'], + ['f', '\f'], + ['v', '\v'], + ['0', '\0'], + ['\\', '\\'], + ['e', '\u001B'], + ['a', '\u0007'] +]); -/** - * Add a new interceptor to the stack - * - * @param {Function} fulfilled The function to handle `then` for a `Promise` - * @param {Function} rejected The function to handle `reject` for a `Promise` - * - * @return {Number} An ID used to remove interceptor later - */ -InterceptorManager.prototype.use = function use(fulfilled, rejected) { - this.handlers.push({ - fulfilled: fulfilled, - rejected: rejected - }); - return this.handlers.length - 1; -}; +function unescape(c) { + if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { + return String.fromCharCode(parseInt(c.slice(1), 16)); + } -/** - * Remove an interceptor from the stack - * - * @param {Number} id The ID that was returned by `use` - */ -InterceptorManager.prototype.eject = function eject(id) { - if (this.handlers[id]) { - this.handlers[id] = null; - } -}; + return ESCAPES.get(c) || c; +} -/** - * Iterate over all the registered interceptors - * - * This method is particularly useful for skipping over any - * interceptors that may have become `null` calling `eject`. - * - * @param {Function} fn The function to call for each interceptor - */ -InterceptorManager.prototype.forEach = function forEach(fn) { - utils.forEach(this.handlers, function forEachHandler(h) { - if (h !== null) { - fn(h); - } - }); -}; +function parseArguments(name, args) { + const results = []; + const chunks = args.trim().split(/\s*,\s*/g); + let matches; -module.exports = InterceptorManager; + for (const chunk of chunks) { + if (!isNaN(chunk)) { + results.push(Number(chunk)); + } else if ((matches = chunk.match(STRING_REGEX))) { + results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); + } else { + throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); + } + } + return results; +} -/***/ }), -/* 460 */ -/***/ (function(module, exports, __webpack_require__) { +function parseStyle(style) { + STYLE_REGEX.lastIndex = 0; -"use strict"; + const results = []; + let matches; + while ((matches = STYLE_REGEX.exec(style)) !== null) { + const name = matches[1]; -var utils = __webpack_require__(455); -var transformData = __webpack_require__(461); -var isCancel = __webpack_require__(462); -var defaults = __webpack_require__(463); + if (matches[2]) { + const args = parseArguments(name, matches[2]); + results.push([name].concat(args)); + } else { + results.push([name]); + } + } -/** - * Throws a `Cancel` if cancellation has been requested. - */ -function throwIfCancellationRequested(config) { - if (config.cancelToken) { - config.cancelToken.throwIfRequested(); - } + return results; } -/** - * Dispatch a request to the server using the configured adapter. - * - * @param {object} config The config that is to be used for the request - * @returns {Promise} The Promise to be fulfilled - */ -module.exports = function dispatchRequest(config) { - throwIfCancellationRequested(config); +function buildStyle(chalk, styles) { + const enabled = {}; - // Ensure headers exist - config.headers = config.headers || {}; + for (const layer of styles) { + for (const style of layer.styles) { + enabled[style[0]] = layer.inverse ? null : style.slice(1); + } + } - // Transform request data - config.data = transformData( - config.data, - config.headers, - config.transformRequest - ); + let current = chalk; + for (const styleName of Object.keys(enabled)) { + if (Array.isArray(enabled[styleName])) { + if (!(styleName in current)) { + throw new Error(`Unknown Chalk style: ${styleName}`); + } - // Flatten headers - config.headers = utils.merge( - config.headers.common || {}, - config.headers[config.method] || {}, - config.headers - ); + if (enabled[styleName].length > 0) { + current = current[styleName].apply(current, enabled[styleName]); + } else { + current = current[styleName]; + } + } + } - utils.forEach( - ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'], - function cleanHeaderConfig(method) { - delete config.headers[method]; - } - ); + return current; +} - var adapter = config.adapter || defaults.adapter; +module.exports = (chalk, tmp) => { + const styles = []; + const chunks = []; + let chunk = []; - return adapter(config).then(function onAdapterResolution(response) { - throwIfCancellationRequested(config); + // eslint-disable-next-line max-params + tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { + if (escapeChar) { + chunk.push(unescape(escapeChar)); + } else if (style) { + const str = chunk.join(''); + chunk = []; + chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); + styles.push({inverse, styles: parseStyle(style)}); + } else if (close) { + if (styles.length === 0) { + throw new Error('Found extraneous } in Chalk template literal'); + } - // Transform response data - response.data = transformData( - response.data, - response.headers, - config.transformResponse - ); + chunks.push(buildStyle(chalk, styles)(chunk.join(''))); + chunk = []; + styles.pop(); + } else { + chunk.push(chr); + } + }); - return response; - }, function onAdapterRejection(reason) { - if (!isCancel(reason)) { - throwIfCancellationRequested(config); + chunks.push(chunk.join('')); - // Transform response data - if (reason && reason.response) { - reason.response.data = transformData( - reason.response.data, - reason.response.headers, - config.transformResponse - ); - } - } + if (styles.length > 0) { + const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; + throw new Error(errMsg); + } - return Promise.reject(reason); - }); + return chunks.join(''); }; /***/ }), -/* 461 */ +/* 430 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var utils = __webpack_require__(455); - -/** - * Transform the data for a request or a response +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * @param {Object|String} data The data to be transformed - * @param {Array} headers The headers for the request or response - * @param {Array|Function} fns A single function or Array of functions - * @returns {*} The resulting transformed data + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ -module.exports = function transformData(data, headers, fns) { - /*eslint no-param-reassign:0*/ - utils.forEach(fns, function transform(fn) { - data = fn(data, headers); - }); - - return data; -}; +Object.defineProperty(exports, "__esModule", { value: true }); +const path_1 = __webpack_require__(4); +exports.CA_CERT_PATH = path_1.resolve(__dirname, '../certs/ca.crt'); +exports.ES_KEY_PATH = path_1.resolve(__dirname, '../certs/elasticsearch.key'); +exports.ES_CERT_PATH = path_1.resolve(__dirname, '../certs/elasticsearch.crt'); +exports.ES_P12_PATH = path_1.resolve(__dirname, '../certs/elasticsearch.p12'); +exports.ES_P12_PASSWORD = 'storepass'; +exports.ES_EMPTYPASSWORD_P12_PATH = path_1.resolve(__dirname, '../certs/elasticsearch_emptypassword.p12'); +exports.ES_NOPASSWORD_P12_PATH = path_1.resolve(__dirname, '../certs/elasticsearch_nopassword.p12'); +exports.KBN_KEY_PATH = path_1.resolve(__dirname, '../certs/kibana.key'); +exports.KBN_CERT_PATH = path_1.resolve(__dirname, '../certs/kibana.crt'); +exports.KBN_P12_PATH = path_1.resolve(__dirname, '../certs/kibana.p12'); +exports.KBN_P12_PASSWORD = 'storepass'; /***/ }), -/* 462 */ +/* 431 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -module.exports = function isCancel(value) { - return !!(value && value.__CANCEL__); -}; +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +var run_1 = __webpack_require__(432); +exports.run = run_1.run; +var fail_1 = __webpack_require__(433); +exports.createFailError = fail_1.createFailError; +exports.createFlagError = fail_1.createFlagError; +exports.combineErrors = fail_1.combineErrors; +exports.isFailError = fail_1.isFailError; /***/ }), -/* 463 */ +/* 432 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var utils = __webpack_require__(455); -var normalizeHeaderName = __webpack_require__(464); - -var DEFAULT_CONTENT_TYPE = { - 'Content-Type': 'application/x-www-form-urlencoded' -}; - -function setContentTypeIfUnset(headers, value) { - if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) { - headers['Content-Type'] = value; - } -} - -function getDefaultAdapter() { - var adapter; - if (typeof XMLHttpRequest !== 'undefined') { - // For browsers use XHR adapter - adapter = __webpack_require__(465); - } else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') { - // For node use HTTP adapter - adapter = __webpack_require__(475); - } - return adapter; -} - -var defaults = { - adapter: getDefaultAdapter(), - - transformRequest: [function transformRequest(data, headers) { - normalizeHeaderName(headers, 'Accept'); - normalizeHeaderName(headers, 'Content-Type'); - if (utils.isFormData(data) || - utils.isArrayBuffer(data) || - utils.isBuffer(data) || - utils.isStream(data) || - utils.isFile(data) || - utils.isBlob(data) - ) { - return data; - } - if (utils.isArrayBufferView(data)) { - return data.buffer; - } - if (utils.isURLSearchParams(data)) { - setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8'); - return data.toString(); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(6); +const util_1 = __webpack_require__(397); +// @ts-ignore @types are outdated and module is super simple +const exit_hook_1 = tslib_1.__importDefault(__webpack_require__(339)); +const tooling_log_1 = __webpack_require__(400); +const fail_1 = __webpack_require__(433); +const flags_1 = __webpack_require__(434); +const proc_runner_1 = __webpack_require__(7); +async function run(fn, options = {}) { + var _a; + const flags = flags_1.getFlags(process.argv.slice(2), options); + if (flags.help) { + process.stderr.write(flags_1.getHelp(options)); + process.exit(1); } - if (utils.isObject(data)) { - setContentTypeIfUnset(headers, 'application/json;charset=utf-8'); - return JSON.stringify(data); + const log = new tooling_log_1.ToolingLog({ + level: tooling_log_1.pickLevelFromFlags(flags), + writeTo: process.stdout, + }); + process.on('unhandledRejection', (error) => { + log.error('UNHANDLED PROMISE REJECTION'); + log.error(error instanceof Error + ? error + : new Error(`non-Error type rejection value: ${util_1.inspect(error)}`)); + process.exit(1); + }); + const handleErrorWithoutExit = (error) => { + if (fail_1.isFailError(error)) { + log.error(error.message); + if (error.showHelp) { + log.write(flags_1.getHelp(options)); + } + process.exitCode = error.exitCode; + } + else { + log.error('UNHANDLED ERROR'); + log.error(error); + process.exitCode = 1; + } + }; + const doCleanup = () => { + const tasks = cleanupTasks.slice(0); + cleanupTasks.length = 0; + for (const task of tasks) { + try { + task(); + } + catch (error) { + handleErrorWithoutExit(error); + } + } + }; + const unhookExit = exit_hook_1.default(doCleanup); + const cleanupTasks = [unhookExit]; + try { + if (!((_a = options.flags) === null || _a === void 0 ? void 0 : _a.allowUnexpected) && flags.unexpected.length) { + throw fail_1.createFlagError(`Unknown flag(s) "${flags.unexpected.join('", "')}"`); + } + try { + await proc_runner_1.withProcRunner(log, async (procRunner) => { + await fn({ + log, + flags, + procRunner, + addCleanupTask: (task) => cleanupTasks.push(task), + }); + }); + } + finally { + doCleanup(); + } } - return data; - }], - - transformResponse: [function transformResponse(data) { - /*eslint no-param-reassign:0*/ - if (typeof data === 'string') { - try { - data = JSON.parse(data); - } catch (e) { /* Ignore */ } + catch (error) { + handleErrorWithoutExit(error); + process.exit(); } - return data; - }], - - /** - * A timeout in milliseconds to abort a request. If set to 0 (default) a - * timeout is not created. - */ - timeout: 0, - - xsrfCookieName: 'XSRF-TOKEN', - xsrfHeaderName: 'X-XSRF-TOKEN', - - maxContentLength: -1, - - validateStatus: function validateStatus(status) { - return status >= 200 && status < 300; - } -}; +} +exports.run = run; -defaults.headers = { - common: { - 'Accept': 'application/json, text/plain, */*' - } -}; -utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) { - defaults.headers[method] = {}; -}); +/***/ }), +/* 433 */ +/***/ (function(module, exports, __webpack_require__) { -utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { - defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE); -}); +"use strict"; -module.exports = defaults; +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const util_1 = __webpack_require__(397); +const FAIL_TAG = Symbol('fail error'); +function createFailError(reason, options = {}) { + const { exitCode = 1, showHelp = false } = options; + return Object.assign(new Error(reason), { + exitCode, + showHelp, + [FAIL_TAG]: true, + }); +} +exports.createFailError = createFailError; +function createFlagError(reason) { + return createFailError(reason, { + showHelp: true, + }); +} +exports.createFlagError = createFlagError; +function isFailError(error) { + return Boolean(error && error[FAIL_TAG]); +} +exports.isFailError = isFailError; +function combineErrors(errors) { + if (errors.length === 1) { + return errors[0]; + } + const exitCode = errors + .filter(isFailError) + .reduce((acc, error) => Math.max(acc, error.exitCode), 1); + const showHelp = errors.some((error) => isFailError(error) && error.showHelp); + const message = errors.reduce((acc, error) => { + if (isFailError(error)) { + return acc + '\n' + error.message; + } + return acc + `\nUNHANDLED ERROR\n${util_1.inspect(error)}`; + }, ''); + return createFailError(`${errors.length} errors:\n${message}`, { + exitCode, + showHelp, + }); +} +exports.combineErrors = combineErrors; /***/ }), -/* 464 */ +/* 434 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(6); +const path_1 = __webpack_require__(4); +const dedent_1 = tslib_1.__importDefault(__webpack_require__(2)); +const getopts_1 = tslib_1.__importDefault(__webpack_require__(435)); +function getFlags(argv, options) { + const unexpectedNames = new Set(); + const flagOpts = options.flags || {}; + const { verbose, quiet, silent, debug, help, _, ...others } = getopts_1.default(argv, { + string: flagOpts.string, + boolean: [...(flagOpts.boolean || []), 'verbose', 'quiet', 'silent', 'debug', 'help'], + alias: { + ...(flagOpts.alias || {}), + v: 'verbose', + }, + default: flagOpts.default, + unknown: (name) => { + unexpectedNames.add(name); + return flagOpts.guessTypesForUnexpectedFlags; + }, + }); + const unexpected = []; + for (const unexpectedName of unexpectedNames) { + const matchingArgv = []; + iterArgv: for (const [i, v] of argv.entries()) { + for (const prefix of ['--', '-']) { + if (v.startsWith(prefix)) { + // -/--name=value + if (v.startsWith(`${prefix}${unexpectedName}=`)) { + matchingArgv.push(v); + continue iterArgv; + } + // -/--name (value possibly follows) + if (v === `${prefix}${unexpectedName}`) { + matchingArgv.push(v); + // value follows -/--name + if (argv.length > i + 1 && !argv[i + 1].startsWith('-')) { + matchingArgv.push(argv[i + 1]); + } + continue iterArgv; + } + } + } + // special case for `--no-{flag}` disabling of boolean flags + if (v === `--no-${unexpectedName}`) { + matchingArgv.push(v); + continue iterArgv; + } + // special case for shortcut flags formatted as `-abc` where `a`, `b`, + // and `c` will be three separate unexpected flags + if (unexpectedName.length === 1 && + v[0] === '-' && + v[1] !== '-' && + !v.includes('=') && + v.includes(unexpectedName)) { + matchingArgv.push(`-${unexpectedName}`); + continue iterArgv; + } + } + if (matchingArgv.length) { + unexpected.push(...matchingArgv); + } + else { + throw new Error(`unable to find unexpected flag named "${unexpectedName}"`); + } + } + return { + verbose, + quiet, + silent, + debug, + help, + _, + unexpected, + ...others, + }; +} +exports.getFlags = getFlags; +function getHelp(options) { + var _a, _b; + const usage = options.usage || `node ${path_1.relative(process.cwd(), process.argv[1])}`; + const optionHelp = (dedent_1.default(((_b = (_a = options) === null || _a === void 0 ? void 0 : _a.flags) === null || _b === void 0 ? void 0 : _b.help) || '') + + '\n' + + dedent_1.default ` + --verbose, -v Log verbosely + --debug Log debug messages (less than verbose) + --quiet Only log errors + --silent Don't log anything + --help Show this message + `) + .split('\n') + .filter(Boolean) + .join('\n '); + return ` + ${usage} -var utils = __webpack_require__(455); + ${dedent_1.default(options.description || 'Runs a dev task') + .split('\n') + .join('\n ')} -module.exports = function normalizeHeaderName(headers, normalizedName) { - utils.forEach(headers, function processHeader(value, name) { - if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) { - headers[normalizedName] = value; - delete headers[name]; - } - }); -}; + Options: + ${optionHelp + '\n\n'}`; +} +exports.getHelp = getHelp; /***/ }), -/* 465 */ +/* 435 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(455); -var settle = __webpack_require__(466); -var buildURL = __webpack_require__(458); -var buildFullPath = __webpack_require__(469); -var parseHeaders = __webpack_require__(472); -var isURLSameOrigin = __webpack_require__(473); -var createError = __webpack_require__(467); - -module.exports = function xhrAdapter(config) { - return new Promise(function dispatchXhrRequest(resolve, reject) { - var requestData = config.data; - var requestHeaders = config.headers; - - if (utils.isFormData(requestData)) { - delete requestHeaders['Content-Type']; // Let the browser set it - } +const EMPTYARR = [] +const SHORTSPLIT = /$|[!-@[-`{-~][\s\S]*/g +const isArray = Array.isArray - var request = new XMLHttpRequest(); +const parseValue = function(any) { + if (any === "") return "" + if (any === "false") return false + const maybe = Number(any) + return maybe * 0 === 0 ? maybe : any +} - // HTTP basic authentication - if (config.auth) { - var username = config.auth.username || ''; - var password = config.auth.password || ''; - requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password); - } +const parseAlias = function(aliases) { + let out = {}, + key, + alias, + prev, + len, + any, + i, + k - var fullPath = buildFullPath(config.baseURL, config.url); - request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true); + for (key in aliases) { + any = aliases[key] + alias = out[key] = isArray(any) ? any : [any] - // Set the request timeout in MS - request.timeout = config.timeout; + for (i = 0, len = alias.length; i < len; i++) { + prev = out[alias[i]] = [key] - // Listen for ready state - request.onreadystatechange = function handleLoad() { - if (!request || request.readyState !== 4) { - return; + for (k = 0; k < len; k++) { + if (i !== k) prev.push(alias[k]) } + } + } - // The request errored out and we didn't get a response, this will be - // handled by onerror instead - // With one exception: request that using file: protocol, most browsers - // will return status as 0 even though it's a successful request - if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { - return; - } + return out +} - // Prepare the response - var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null; - var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response; - var response = { - data: responseData, - status: request.status, - statusText: request.statusText, - headers: responseHeaders, - config: config, - request: request - }; +const parseDefault = function(aliases, defaults) { + let out = {}, + key, + alias, + value, + len, + i - settle(resolve, reject, response); + for (key in defaults) { + value = defaults[key] + alias = aliases[key] - // Clean up request - request = null; - }; + out[key] = value - // Handle browser request cancellation (as opposed to a manual cancellation) - request.onabort = function handleAbort() { - if (!request) { - return; + if (alias === undefined) { + aliases[key] = EMPTYARR + } else { + for (i = 0, len = alias.length; i < len; i++) { + out[alias[i]] = value } + } + } - reject(createError('Request aborted', config, 'ECONNABORTED', request)); + return out +} - // Clean up request - request = null; - }; +const parseOptions = function(aliases, options, value) { + let out = {}, + key, + alias, + len, + end, + i, + k - // Handle low level network errors - request.onerror = function handleError() { - // Real errors are hidden from us by the browser - // onerror should only fire if it's a network error - reject(createError('Network Error', config, null, request)); + if (options !== undefined) { + for (i = 0, len = options.length; i < len; i++) { + key = options[i] + alias = aliases[key] - // Clean up request - request = null; - }; + out[key] = value - // Handle timeout - request.ontimeout = function handleTimeout() { - var timeoutErrorMessage = 'timeout of ' + config.timeout + 'ms exceeded'; - if (config.timeoutErrorMessage) { - timeoutErrorMessage = config.timeoutErrorMessage; + if (alias === undefined) { + aliases[key] = EMPTYARR + } else { + for (k = 0, end = alias.length; k < end; k++) { + out[alias[k]] = value + } } - reject(createError(timeoutErrorMessage, config, 'ECONNABORTED', - request)); + } + } - // Clean up request - request = null; - }; + return out +} - // Add xsrf header - // This is only done if running in a standard browser environment. - // Specifically not if we're in a web worker, or react-native. - if (utils.isStandardBrowserEnv()) { - var cookies = __webpack_require__(474); +const write = function(out, key, value, aliases, unknown) { + let i, + prev, + alias = aliases[key], + len = alias === undefined ? -1 : alias.length - // Add xsrf header - var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ? - cookies.read(config.xsrfCookieName) : - undefined; + if (len >= 0 || unknown === undefined || unknown(key)) { + prev = out[key] - if (xsrfValue) { - requestHeaders[config.xsrfHeaderName] = xsrfValue; + if (prev === undefined) { + out[key] = value + } else { + if (isArray(prev)) { + prev.push(value) + } else { + out[key] = [prev, value] } } - // Add headers to the request - if ('setRequestHeader' in request) { - utils.forEach(requestHeaders, function setRequestHeader(val, key) { - if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') { - // Remove Content-Type if data is undefined - delete requestHeaders[key]; - } else { - // Otherwise add header to the request - request.setRequestHeader(key, val); - } - }); + for (i = 0; i < len; i++) { + out[alias[i]] = out[key] } + } +} - // Add withCredentials to request if needed - if (!utils.isUndefined(config.withCredentials)) { - request.withCredentials = !!config.withCredentials; - } +const getopts = function(argv, opts) { + let unknown = (opts = opts || {}).unknown, + aliases = parseAlias(opts.alias), + strings = parseOptions(aliases, opts.string, ""), + values = parseDefault(aliases, opts.default), + bools = parseOptions(aliases, opts.boolean, false), + stopEarly = opts.stopEarly, + _ = [], + out = { _ }, + i = 0, + k = 0, + len = argv.length, + key, + arg, + end, + match, + value - // Add responseType to request if needed - if (config.responseType) { - try { - request.responseType = config.responseType; - } catch (e) { - // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2. - // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function. - if (config.responseType !== 'json') { - throw e; - } - } - } + for (; i < len; i++) { + arg = argv[i] - // Handle progress if needed - if (typeof config.onDownloadProgress === 'function') { - request.addEventListener('progress', config.onDownloadProgress); - } + if (arg[0] !== "-" || arg === "-") { + if (stopEarly) while (i < len) _.push(argv[i++]) + else _.push(arg) + } else if (arg === "--") { + while (++i < len) _.push(argv[i]) + } else if (arg[1] === "-") { + end = arg.indexOf("=", 2) + if (arg[2] === "n" && arg[3] === "o" && arg[4] === "-") { + key = arg.slice(5, end >= 0 ? end : undefined) + value = false + } else if (end >= 0) { + key = arg.slice(2, end) + value = + bools[key] !== undefined || + (strings[key] === undefined + ? parseValue(arg.slice(end + 1)) + : arg.slice(end + 1)) + } else { + key = arg.slice(2) + value = + bools[key] !== undefined || + (len === i + 1 || argv[i + 1][0] === "-" + ? strings[key] === undefined + ? true + : "" + : strings[key] === undefined + ? parseValue(argv[++i]) + : argv[++i]) + } + write(out, key, value, aliases, unknown) + } else { + SHORTSPLIT.lastIndex = 2 + match = SHORTSPLIT.exec(arg) + end = match.index + value = match[0] - // Not all browsers support upload events - if (typeof config.onUploadProgress === 'function' && request.upload) { - request.upload.addEventListener('progress', config.onUploadProgress); + for (k = 1; k < end; k++) { + write( + out, + (key = arg[k]), + k + 1 < end + ? strings[key] === undefined || + arg.substring(k + 1, (k = end)) + value + : value === "" + ? len === i + 1 || argv[i + 1][0] === "-" + ? strings[key] === undefined || "" + : bools[key] !== undefined || + (strings[key] === undefined ? parseValue(argv[++i]) : argv[++i]) + : bools[key] !== undefined || + (strings[key] === undefined ? parseValue(value) : value), + aliases, + unknown + ) + } } + } - if (config.cancelToken) { - // Handle cancellation - config.cancelToken.promise.then(function onCanceled(cancel) { - if (!request) { - return; - } - - request.abort(); - reject(cancel); - // Clean up request - request = null; - }); - } + for (key in values) if (out[key] === undefined) out[key] = values[key] + for (key in bools) if (out[key] === undefined) out[key] = false + for (key in strings) if (out[key] === undefined) out[key] = "" - if (requestData === undefined) { - requestData = null; - } + return out +} - // Send the request - request.send(requestData); - }); -}; +module.exports = getopts /***/ }), -/* 466 */ +/* 436 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var createError = __webpack_require__(467); - -/** - * Resolve or reject a Promise based on response status. +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * @param {Function} resolve A function that resolves the promise. - * @param {Function} reject A function that rejects the promise. - * @param {object} response The response. + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ -module.exports = function settle(resolve, reject, response) { - var validateStatus = response.config.validateStatus; - if (!validateStatus || validateStatus(response.status)) { - resolve(response); - } else { - reject(createError( - 'Request failed with status code ' + response.status, - response.config, - null, - response.request, - response - )); - } -}; +Object.defineProperty(exports, "__esModule", { value: true }); +var kbn_client_1 = __webpack_require__(437); +exports.KbnClient = kbn_client_1.KbnClient; +var kbn_client_requester_1 = __webpack_require__(438); +exports.uriencode = kbn_client_requester_1.uriencode; /***/ }), -/* 467 */ +/* 437 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var enhanceError = __webpack_require__(468); - -/** - * Create an Error with the specified message, config, error code, request and response. +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * @param {string} message The error message. - * @param {Object} config The config. - * @param {string} [code] The error code (for example, 'ECONNABORTED'). - * @param {Object} [request] The request. - * @param {Object} [response] The response. - * @returns {Error} The created error. + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ -module.exports = function createError(message, config, code, request, response) { - var error = new Error(message); - return enhanceError(error, config, code, request, response); -}; +Object.defineProperty(exports, "__esModule", { value: true }); +const kbn_client_requester_1 = __webpack_require__(438); +const kbn_client_status_1 = __webpack_require__(481); +const kbn_client_plugins_1 = __webpack_require__(482); +const kbn_client_version_1 = __webpack_require__(483); +const kbn_client_saved_objects_1 = __webpack_require__(484); +const kbn_client_ui_settings_1 = __webpack_require__(485); +class KbnClient { + /** + * Basic Kibana server client that implements common behaviors for talking + * to the Kibana server from dev tooling. + * + * @param log ToolingLog + * @param kibanaUrls Array of kibana server urls to send requests to + * @param uiSettingDefaults Map of uiSetting values that will be merged with all uiSetting resets + */ + constructor(log, kibanaUrls, uiSettingDefaults) { + this.log = log; + this.kibanaUrls = kibanaUrls; + this.uiSettingDefaults = uiSettingDefaults; + this.requester = new kbn_client_requester_1.KbnClientRequester(this.log, this.kibanaUrls); + this.status = new kbn_client_status_1.KbnClientStatus(this.requester); + this.plugins = new kbn_client_plugins_1.KbnClientPlugins(this.status); + this.version = new kbn_client_version_1.KbnClientVersion(this.status); + this.savedObjects = new kbn_client_saved_objects_1.KbnClientSavedObjects(this.log, this.requester); + this.uiSettings = new kbn_client_ui_settings_1.KbnClientUiSettings(this.log, this.requester, this.uiSettingDefaults); + if (!kibanaUrls.length) { + throw new Error('missing Kibana urls'); + } + } + /** + * Make a direct request to the Kibana server + */ + async request(options) { + return await this.requester.request(options); + } + resolveUrl(relativeUrl) { + return this.requester.resolveUrl(relativeUrl); + } +} +exports.KbnClient = KbnClient; /***/ }), -/* 468 */ +/* 438 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -/** - * Update an Error with the specified config, error code, and response. +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * @param {Error} error The error to update. - * @param {Object} config The config. - * @param {string} [code] The error code (for example, 'ECONNABORTED'). - * @param {Object} [request] The request. - * @param {Object} [response] The response. - * @returns {Error} The error. + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ -module.exports = function enhanceError(error, config, code, request, response) { - error.config = config; - if (code) { - error.code = code; - } - - error.request = request; - error.response = response; - error.isAxiosError = true; - - error.toJSON = function() { - return { - // Standard - message: this.message, - name: this.name, - // Microsoft - description: this.description, - number: this.number, - // Mozilla - fileName: this.fileName, - lineNumber: this.lineNumber, - columnNumber: this.columnNumber, - stack: this.stack, - // Axios - config: this.config, - code: this.code - }; - }; - return error; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(6); +const url_1 = tslib_1.__importDefault(__webpack_require__(439)); +const axios_1 = tslib_1.__importDefault(__webpack_require__(440)); +const axios_2 = __webpack_require__(479); +const isConcliftOnGetError = (error) => { + return (axios_2.isAxiosResponseError(error) && error.config.method === 'GET' && error.response.status === 409); +}; +exports.uriencode = (strings, ...values) => { + const queue = strings.slice(); + if (queue.length === 0) { + throw new Error('how could strings passed to `uriencode` template tag be empty?'); + } + if (queue.length !== values.length + 1) { + throw new Error('strings and values passed to `uriencode` template tag are unbalanced'); + } + // pull the first string off the queue, there is one less item in `values` + // since the values are always wrapped in strings, so we shift the extra string + // off the queue to balance the queue and values array. + const leadingString = queue.shift(); + return queue.reduce((acc, string, i) => `${acc}${encodeURIComponent(values[i])}${string}`, leadingString); }; +const DEFAULT_MAX_ATTEMPTS = 5; +const delay = (ms) => new Promise((resolve) => { + setTimeout(resolve, ms); +}); +class KbnClientRequester { + constructor(log, kibanaUrls) { + this.log = log; + this.kibanaUrls = kibanaUrls; + } + pickUrl() { + const url = this.kibanaUrls.shift(); + this.kibanaUrls.push(url); + return url; + } + resolveUrl(relativeUrl = '/') { + return url_1.default.resolve(this.pickUrl(), relativeUrl); + } + async request(options) { + var _a; + const url = url_1.default.resolve(this.pickUrl(), options.path); + const description = options.description || `${options.method} ${url}`; + let attempt = 0; + const maxAttempts = (_a = options.retries, (_a !== null && _a !== void 0 ? _a : DEFAULT_MAX_ATTEMPTS)); + while (true) { + attempt += 1; + try { + const response = await axios_1.default.request({ + method: options.method, + url, + data: options.body, + params: options.query, + headers: { + 'kbn-xsrf': 'kbn-client', + }, + }); + return response.data; + } + catch (error) { + const conflictOnGet = isConcliftOnGetError(error); + const requestedRetries = options.retries !== undefined; + const failedToGetResponse = axios_2.isAxiosRequestError(error); + let errorMessage; + if (conflictOnGet) { + errorMessage = `Conflict on GET (path=${options.path}, attempt=${attempt}/${maxAttempts})`; + this.log.error(errorMessage); + } + else if (requestedRetries || failedToGetResponse) { + errorMessage = `[${description}] request failed (attempt=${attempt}/${maxAttempts})`; + this.log.error(errorMessage); + } + else { + throw error; + } + if (attempt < maxAttempts) { + await delay(1000 * attempt); + continue; + } + throw new Error(`${errorMessage} -- and ran out of retries`); + } + } + } +} +exports.KbnClientRequester = KbnClientRequester; /***/ }), -/* 469 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var isAbsoluteURL = __webpack_require__(470); -var combineURLs = __webpack_require__(471); - -/** - * Creates a new URL by combining the baseURL with the requestedURL, - * only when the requestedURL is not already an absolute URL. - * If the requestURL is absolute, this function returns the requestedURL untouched. - * - * @param {string} baseURL The base URL - * @param {string} requestedURL Absolute or relative URL to combine - * @returns {string} The combined full path - */ -module.exports = function buildFullPath(baseURL, requestedURL) { - if (baseURL && !isAbsoluteURL(requestedURL)) { - return combineURLs(baseURL, requestedURL); - } - return requestedURL; -}; +/* 439 */ +/***/ (function(module, exports) { +module.exports = require("url"); /***/ }), -/* 470 */ +/* 440 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - - -/** - * Determines whether the specified URL is absolute - * - * @param {string} url The URL to test - * @returns {boolean} True if the specified URL is absolute, otherwise false - */ -module.exports = function isAbsoluteURL(url) { - // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). - // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed - // by any combination of letters, digits, plus, period, or hyphen. - return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url); -}; - +module.exports = __webpack_require__(441); /***/ }), -/* 471 */ +/* 441 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +var utils = __webpack_require__(442); +var bind = __webpack_require__(443); +var Axios = __webpack_require__(444); +var mergeConfig = __webpack_require__(475); +var defaults = __webpack_require__(450); + /** - * Creates a new URL by combining the specified URLs + * Create an instance of Axios * - * @param {string} baseURL The base URL - * @param {string} relativeURL The relative URL - * @returns {string} The combined URL + * @param {Object} defaultConfig The default config for the instance + * @return {Axios} A new instance of Axios */ -module.exports = function combineURLs(baseURL, relativeURL) { - return relativeURL - ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') - : baseURL; -}; - +function createInstance(defaultConfig) { + var context = new Axios(defaultConfig); + var instance = bind(Axios.prototype.request, context); -/***/ }), -/* 472 */ -/***/ (function(module, exports, __webpack_require__) { + // Copy axios.prototype to instance + utils.extend(instance, Axios.prototype, context); -"use strict"; + // Copy context to instance + utils.extend(instance, context); + return instance; +} -var utils = __webpack_require__(455); +// Create the default instance to be exported +var axios = createInstance(defaults); -// Headers whose duplicates are ignored by node -// c.f. https://nodejs.org/api/http.html#http_message_headers -var ignoreDuplicateOf = [ - 'age', 'authorization', 'content-length', 'content-type', 'etag', - 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since', - 'last-modified', 'location', 'max-forwards', 'proxy-authorization', - 'referer', 'retry-after', 'user-agent' -]; +// Expose Axios class to allow class inheritance +axios.Axios = Axios; -/** - * Parse headers into an object - * - * ``` - * Date: Wed, 27 Aug 2014 08:58:49 GMT - * Content-Type: application/json - * Connection: keep-alive - * Transfer-Encoding: chunked - * ``` - * - * @param {String} headers Headers needing to be parsed - * @returns {Object} Headers parsed into an object - */ -module.exports = function parseHeaders(headers) { - var parsed = {}; - var key; - var val; - var i; +// Factory for creating new instances +axios.create = function create(instanceConfig) { + return createInstance(mergeConfig(axios.defaults, instanceConfig)); +}; - if (!headers) { return parsed; } +// Expose Cancel & CancelToken +axios.Cancel = __webpack_require__(476); +axios.CancelToken = __webpack_require__(477); +axios.isCancel = __webpack_require__(449); - utils.forEach(headers.split('\n'), function parser(line) { - i = line.indexOf(':'); - key = utils.trim(line.substr(0, i)).toLowerCase(); - val = utils.trim(line.substr(i + 1)); +// Expose all/spread +axios.all = function all(promises) { + return Promise.all(promises); +}; +axios.spread = __webpack_require__(478); - if (key) { - if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) { - return; - } - if (key === 'set-cookie') { - parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]); - } else { - parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; - } - } - }); +module.exports = axios; - return parsed; -}; +// Allow use of default import syntax in TypeScript +module.exports.default = axios; /***/ }), -/* 473 */ +/* 442 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(455); +var bind = __webpack_require__(443); -module.exports = ( - utils.isStandardBrowserEnv() ? +/*global toString:true*/ - // Standard browser envs have full support of the APIs needed to test - // whether the request URL is of the same origin as current location. - (function standardBrowserEnv() { - var msie = /(msie|trident)/i.test(navigator.userAgent); - var urlParsingNode = document.createElement('a'); - var originURL; +// utils is a library of generic helper functions non-specific to axios - /** - * Parse a URL to discover it's components - * - * @param {String} url The URL to be parsed - * @returns {Object} - */ - function resolveURL(url) { - var href = url; +var toString = Object.prototype.toString; - if (msie) { - // IE needs attribute set twice to normalize properties - urlParsingNode.setAttribute('href', href); - href = urlParsingNode.href; - } +/** + * Determine if a value is an Array + * + * @param {Object} val The value to test + * @returns {boolean} True if value is an Array, otherwise false + */ +function isArray(val) { + return toString.call(val) === '[object Array]'; +} - urlParsingNode.setAttribute('href', href); +/** + * Determine if a value is undefined + * + * @param {Object} val The value to test + * @returns {boolean} True if the value is undefined, otherwise false + */ +function isUndefined(val) { + return typeof val === 'undefined'; +} - // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils - return { - href: urlParsingNode.href, - protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '', - host: urlParsingNode.host, - search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '', - hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '', - hostname: urlParsingNode.hostname, - port: urlParsingNode.port, - pathname: (urlParsingNode.pathname.charAt(0) === '/') ? - urlParsingNode.pathname : - '/' + urlParsingNode.pathname - }; - } +/** + * Determine if a value is a Buffer + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a Buffer, otherwise false + */ +function isBuffer(val) { + return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) + && typeof val.constructor.isBuffer === 'function' && val.constructor.isBuffer(val); +} - originURL = resolveURL(window.location.href); +/** + * Determine if a value is an ArrayBuffer + * + * @param {Object} val The value to test + * @returns {boolean} True if value is an ArrayBuffer, otherwise false + */ +function isArrayBuffer(val) { + return toString.call(val) === '[object ArrayBuffer]'; +} - /** - * Determine if a URL shares the same origin as the current location - * - * @param {String} requestURL The URL to test - * @returns {boolean} True if URL shares the same origin, otherwise false - */ - return function isURLSameOrigin(requestURL) { - var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL; - return (parsed.protocol === originURL.protocol && - parsed.host === originURL.host); - }; - })() : +/** + * Determine if a value is a FormData + * + * @param {Object} val The value to test + * @returns {boolean} True if value is an FormData, otherwise false + */ +function isFormData(val) { + return (typeof FormData !== 'undefined') && (val instanceof FormData); +} - // Non standard browser envs (web workers, react-native) lack needed support. - (function nonStandardBrowserEnv() { - return function isURLSameOrigin() { - return true; - }; - })() -); +/** + * Determine if a value is a view on an ArrayBuffer + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false + */ +function isArrayBufferView(val) { + var result; + if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) { + result = ArrayBuffer.isView(val); + } else { + result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer); + } + return result; +} +/** + * Determine if a value is a String + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a String, otherwise false + */ +function isString(val) { + return typeof val === 'string'; +} -/***/ }), -/* 474 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Determine if a value is a Number + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a Number, otherwise false + */ +function isNumber(val) { + return typeof val === 'number'; +} -"use strict"; +/** + * Determine if a value is an Object + * + * @param {Object} val The value to test + * @returns {boolean} True if value is an Object, otherwise false + */ +function isObject(val) { + return val !== null && typeof val === 'object'; +} +/** + * Determine if a value is a Date + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a Date, otherwise false + */ +function isDate(val) { + return toString.call(val) === '[object Date]'; +} -var utils = __webpack_require__(455); +/** + * Determine if a value is a File + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a File, otherwise false + */ +function isFile(val) { + return toString.call(val) === '[object File]'; +} -module.exports = ( - utils.isStandardBrowserEnv() ? +/** + * Determine if a value is a Blob + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a Blob, otherwise false + */ +function isBlob(val) { + return toString.call(val) === '[object Blob]'; +} - // Standard browser envs support document.cookie - (function standardBrowserEnv() { - return { - write: function write(name, value, expires, path, domain, secure) { - var cookie = []; - cookie.push(name + '=' + encodeURIComponent(value)); +/** + * Determine if a value is a Function + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a Function, otherwise false + */ +function isFunction(val) { + return toString.call(val) === '[object Function]'; +} - if (utils.isNumber(expires)) { - cookie.push('expires=' + new Date(expires).toGMTString()); - } +/** + * Determine if a value is a Stream + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a Stream, otherwise false + */ +function isStream(val) { + return isObject(val) && isFunction(val.pipe); +} - if (utils.isString(path)) { - cookie.push('path=' + path); - } +/** + * Determine if a value is a URLSearchParams object + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a URLSearchParams object, otherwise false + */ +function isURLSearchParams(val) { + return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams; +} - if (utils.isString(domain)) { - cookie.push('domain=' + domain); - } +/** + * Trim excess whitespace off the beginning and end of a string + * + * @param {String} str The String to trim + * @returns {String} The String freed of excess whitespace + */ +function trim(str) { + return str.replace(/^\s*/, '').replace(/\s*$/, ''); +} - if (secure === true) { - cookie.push('secure'); - } +/** + * Determine if we're running in a standard browser environment + * + * This allows axios to run in a web worker, and react-native. + * Both environments support XMLHttpRequest, but not fully standard globals. + * + * web workers: + * typeof window -> undefined + * typeof document -> undefined + * + * react-native: + * navigator.product -> 'ReactNative' + * nativescript + * navigator.product -> 'NativeScript' or 'NS' + */ +function isStandardBrowserEnv() { + if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' || + navigator.product === 'NativeScript' || + navigator.product === 'NS')) { + return false; + } + return ( + typeof window !== 'undefined' && + typeof document !== 'undefined' + ); +} - document.cookie = cookie.join('; '); - }, +/** + * Iterate over an Array or an Object invoking a function for each item. + * + * If `obj` is an Array callback will be called passing + * the value, index, and complete array for each item. + * + * If 'obj' is an Object callback will be called passing + * the value, key, and complete object for each property. + * + * @param {Object|Array} obj The object to iterate + * @param {Function} fn The callback to invoke for each item + */ +function forEach(obj, fn) { + // Don't bother if no value provided + if (obj === null || typeof obj === 'undefined') { + return; + } - read: function read(name) { - var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)')); - return (match ? decodeURIComponent(match[3]) : null); - }, + // Force an array if not already something iterable + if (typeof obj !== 'object') { + /*eslint no-param-reassign:0*/ + obj = [obj]; + } - remove: function remove(name) { - this.write(name, '', Date.now() - 86400000); - } - }; - })() : + if (isArray(obj)) { + // Iterate over array values + for (var i = 0, l = obj.length; i < l; i++) { + fn.call(null, obj[i], i, obj); + } + } else { + // Iterate over object keys + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + fn.call(null, obj[key], key, obj); + } + } + } +} - // Non standard browser env (web workers, react-native) lack needed support. - (function nonStandardBrowserEnv() { - return { - write: function write() {}, - read: function read() { return null; }, - remove: function remove() {} - }; - })() -); +/** + * Accepts varargs expecting each argument to be an object, then + * immutably merges the properties of each object and returns result. + * + * When multiple objects contain the same key the later object in + * the arguments list will take precedence. + * + * Example: + * + * ```js + * var result = merge({foo: 123}, {foo: 456}); + * console.log(result.foo); // outputs 456 + * ``` + * + * @param {Object} obj1 Object to merge + * @returns {Object} Result of all merge properties + */ +function merge(/* obj1, obj2, obj3, ... */) { + var result = {}; + function assignValue(val, key) { + if (typeof result[key] === 'object' && typeof val === 'object') { + result[key] = merge(result[key], val); + } else { + result[key] = val; + } + } + + for (var i = 0, l = arguments.length; i < l; i++) { + forEach(arguments[i], assignValue); + } + return result; +} + +/** + * Function equal to merge with the difference being that no reference + * to original objects is kept. + * + * @see merge + * @param {Object} obj1 Object to merge + * @returns {Object} Result of all merge properties + */ +function deepMerge(/* obj1, obj2, obj3, ... */) { + var result = {}; + function assignValue(val, key) { + if (typeof result[key] === 'object' && typeof val === 'object') { + result[key] = deepMerge(result[key], val); + } else if (typeof val === 'object') { + result[key] = deepMerge({}, val); + } else { + result[key] = val; + } + } + + for (var i = 0, l = arguments.length; i < l; i++) { + forEach(arguments[i], assignValue); + } + return result; +} + +/** + * Extends object a by mutably adding to it the properties of object b. + * + * @param {Object} a The object to be extended + * @param {Object} b The object to copy properties from + * @param {Object} thisArg The object to bind function to + * @return {Object} The resulting value of object a + */ +function extend(a, b, thisArg) { + forEach(b, function assignValue(val, key) { + if (thisArg && typeof val === 'function') { + a[key] = bind(val, thisArg); + } else { + a[key] = val; + } + }); + return a; +} + +module.exports = { + isArray: isArray, + isArrayBuffer: isArrayBuffer, + isBuffer: isBuffer, + isFormData: isFormData, + isArrayBufferView: isArrayBufferView, + isString: isString, + isNumber: isNumber, + isObject: isObject, + isUndefined: isUndefined, + isDate: isDate, + isFile: isFile, + isBlob: isBlob, + isFunction: isFunction, + isStream: isStream, + isURLSearchParams: isURLSearchParams, + isStandardBrowserEnv: isStandardBrowserEnv, + forEach: forEach, + merge: merge, + deepMerge: deepMerge, + extend: extend, + trim: trim +}; /***/ }), -/* 475 */ +/* 443 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(455); -var settle = __webpack_require__(466); -var buildFullPath = __webpack_require__(469); -var buildURL = __webpack_require__(458); -var http = __webpack_require__(476); -var https = __webpack_require__(477); -var httpFollow = __webpack_require__(478).http; -var httpsFollow = __webpack_require__(478).https; -var url = __webpack_require__(452); -var zlib = __webpack_require__(486); -var pkg = __webpack_require__(487); -var createError = __webpack_require__(467); -var enhanceError = __webpack_require__(468); +module.exports = function bind(fn, thisArg) { + return function wrap() { + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + return fn.apply(thisArg, args); + }; +}; -var isHttps = /https:?/; -/*eslint consistent-return:0*/ -module.exports = function httpAdapter(config) { - return new Promise(function dispatchHttpRequest(resolvePromise, rejectPromise) { - var resolve = function resolve(value) { - resolvePromise(value); - }; - var reject = function reject(value) { - rejectPromise(value); - }; - var data = config.data; - var headers = config.headers; +/***/ }), +/* 444 */ +/***/ (function(module, exports, __webpack_require__) { - // Set User-Agent (required by some servers) - // Only set header if it hasn't been set in config - // See https://github.com/axios/axios/issues/69 - if (!headers['User-Agent'] && !headers['user-agent']) { - headers['User-Agent'] = 'axios/' + pkg.version; - } +"use strict"; - if (data && !utils.isStream(data)) { - if (Buffer.isBuffer(data)) { - // Nothing to do... - } else if (utils.isArrayBuffer(data)) { - data = Buffer.from(new Uint8Array(data)); - } else if (utils.isString(data)) { - data = Buffer.from(data, 'utf-8'); - } else { - return reject(createError( - 'Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream', - config - )); - } - // Add Content-Length header if data exists - headers['Content-Length'] = data.length; - } +var utils = __webpack_require__(442); +var buildURL = __webpack_require__(445); +var InterceptorManager = __webpack_require__(446); +var dispatchRequest = __webpack_require__(447); +var mergeConfig = __webpack_require__(475); - // HTTP basic authentication - var auth = undefined; - if (config.auth) { - var username = config.auth.username || ''; - var password = config.auth.password || ''; - auth = username + ':' + password; - } +/** + * Create a new instance of Axios + * + * @param {Object} instanceConfig The default config for the instance + */ +function Axios(instanceConfig) { + this.defaults = instanceConfig; + this.interceptors = { + request: new InterceptorManager(), + response: new InterceptorManager() + }; +} - // Parse url - var fullPath = buildFullPath(config.baseURL, config.url); - var parsed = url.parse(fullPath); - var protocol = parsed.protocol || 'http:'; +/** + * Dispatch a request + * + * @param {Object} config The config specific for this request (merged with this.defaults) + */ +Axios.prototype.request = function request(config) { + /*eslint no-param-reassign:0*/ + // Allow for axios('example/url'[, config]) a la fetch API + if (typeof config === 'string') { + config = arguments[1] || {}; + config.url = arguments[0]; + } else { + config = config || {}; + } - if (!auth && parsed.auth) { - var urlAuth = parsed.auth.split(':'); - var urlUsername = urlAuth[0] || ''; - var urlPassword = urlAuth[1] || ''; - auth = urlUsername + ':' + urlPassword; - } + config = mergeConfig(this.defaults, config); - if (auth) { - delete headers.Authorization; - } + // Set config.method + if (config.method) { + config.method = config.method.toLowerCase(); + } else if (this.defaults.method) { + config.method = this.defaults.method.toLowerCase(); + } else { + config.method = 'get'; + } - var isHttpsRequest = isHttps.test(protocol); - var agent = isHttpsRequest ? config.httpsAgent : config.httpAgent; + // Hook up interceptors middleware + var chain = [dispatchRequest, undefined]; + var promise = Promise.resolve(config); - var options = { - path: buildURL(parsed.path, config.params, config.paramsSerializer).replace(/^\?/, ''), - method: config.method.toUpperCase(), - headers: headers, - agent: agent, - agents: { http: config.httpAgent, https: config.httpsAgent }, - auth: auth - }; + this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { + chain.unshift(interceptor.fulfilled, interceptor.rejected); + }); - if (config.socketPath) { - options.socketPath = config.socketPath; - } else { - options.hostname = parsed.hostname; - options.port = parsed.port; - } + this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { + chain.push(interceptor.fulfilled, interceptor.rejected); + }); - var proxy = config.proxy; - if (!proxy && proxy !== false) { - var proxyEnv = protocol.slice(0, -1) + '_proxy'; - var proxyUrl = process.env[proxyEnv] || process.env[proxyEnv.toUpperCase()]; - if (proxyUrl) { - var parsedProxyUrl = url.parse(proxyUrl); - var noProxyEnv = process.env.no_proxy || process.env.NO_PROXY; - var shouldProxy = true; + while (chain.length) { + promise = promise.then(chain.shift(), chain.shift()); + } - if (noProxyEnv) { - var noProxy = noProxyEnv.split(',').map(function trim(s) { - return s.trim(); - }); + return promise; +}; - shouldProxy = !noProxy.some(function proxyMatch(proxyElement) { - if (!proxyElement) { - return false; - } - if (proxyElement === '*') { - return true; - } - if (proxyElement[0] === '.' && - parsed.hostname.substr(parsed.hostname.length - proxyElement.length) === proxyElement) { - return true; - } +Axios.prototype.getUri = function getUri(config) { + config = mergeConfig(this.defaults, config); + return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\?/, ''); +}; - return parsed.hostname === proxyElement; - }); - } +// Provide aliases for supported request methods +utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) { + /*eslint func-names:0*/ + Axios.prototype[method] = function(url, config) { + return this.request(utils.merge(config || {}, { + method: method, + url: url + })); + }; +}); +utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { + /*eslint func-names:0*/ + Axios.prototype[method] = function(url, data, config) { + return this.request(utils.merge(config || {}, { + method: method, + url: url, + data: data + })); + }; +}); - if (shouldProxy) { - proxy = { - host: parsedProxyUrl.hostname, - port: parsedProxyUrl.port - }; +module.exports = Axios; - if (parsedProxyUrl.auth) { - var proxyUrlAuth = parsedProxyUrl.auth.split(':'); - proxy.auth = { - username: proxyUrlAuth[0], - password: proxyUrlAuth[1] - }; - } - } - } - } - if (proxy) { - options.hostname = proxy.host; - options.host = proxy.host; - options.headers.host = parsed.hostname + (parsed.port ? ':' + parsed.port : ''); - options.port = proxy.port; - options.path = protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path; +/***/ }), +/* 445 */ +/***/ (function(module, exports, __webpack_require__) { - // Basic proxy authorization - if (proxy.auth) { - var base64 = Buffer.from(proxy.auth.username + ':' + proxy.auth.password, 'utf8').toString('base64'); - options.headers['Proxy-Authorization'] = 'Basic ' + base64; - } - } +"use strict"; - var transport; - var isHttpsProxy = isHttpsRequest && (proxy ? isHttps.test(proxy.protocol) : true); - if (config.transport) { - transport = config.transport; - } else if (config.maxRedirects === 0) { - transport = isHttpsProxy ? https : http; - } else { - if (config.maxRedirects) { - options.maxRedirects = config.maxRedirects; - } - transport = isHttpsProxy ? httpsFollow : httpFollow; - } - if (config.maxContentLength && config.maxContentLength > -1) { - options.maxBodyLength = config.maxContentLength; - } +var utils = __webpack_require__(442); - // Create the request - var req = transport.request(options, function handleResponse(res) { - if (req.aborted) return; +function encode(val) { + return encodeURIComponent(val). + replace(/%40/gi, '@'). + replace(/%3A/gi, ':'). + replace(/%24/g, '$'). + replace(/%2C/gi, ','). + replace(/%20/g, '+'). + replace(/%5B/gi, '['). + replace(/%5D/gi, ']'); +} - // uncompress the response body transparently if required - var stream = res; - switch (res.headers['content-encoding']) { - /*eslint default-case:0*/ - case 'gzip': - case 'compress': - case 'deflate': - // add the unzipper to the body stream processing pipeline - stream = (res.statusCode === 204) ? stream : stream.pipe(zlib.createUnzip()); +/** + * Build a URL by appending params to the end + * + * @param {string} url The base of the url (e.g., http://www.google.com) + * @param {object} [params] The params to be appended + * @returns {string} The formatted url + */ +module.exports = function buildURL(url, params, paramsSerializer) { + /*eslint no-param-reassign:0*/ + if (!params) { + return url; + } - // remove the content-encoding in order to not confuse downstream operations - delete res.headers['content-encoding']; - break; + var serializedParams; + if (paramsSerializer) { + serializedParams = paramsSerializer(params); + } else if (utils.isURLSearchParams(params)) { + serializedParams = params.toString(); + } else { + var parts = []; + + utils.forEach(params, function serialize(val, key) { + if (val === null || typeof val === 'undefined') { + return; } - // return the last request in case of redirects - var lastRequest = res.req || req; + if (utils.isArray(val)) { + key = key + '[]'; + } else { + val = [val]; + } - var response = { - status: res.statusCode, - statusText: res.statusMessage, - headers: res.headers, - config: config, - request: lastRequest - }; + utils.forEach(val, function parseValue(v) { + if (utils.isDate(v)) { + v = v.toISOString(); + } else if (utils.isObject(v)) { + v = JSON.stringify(v); + } + parts.push(encode(key) + '=' + encode(v)); + }); + }); - if (config.responseType === 'stream') { - response.data = stream; - settle(resolve, reject, response); - } else { - var responseBuffer = []; - stream.on('data', function handleStreamData(chunk) { - responseBuffer.push(chunk); + serializedParams = parts.join('&'); + } - // make sure the content length is not over the maxContentLength if specified - if (config.maxContentLength > -1 && Buffer.concat(responseBuffer).length > config.maxContentLength) { - stream.destroy(); - reject(createError('maxContentLength size of ' + config.maxContentLength + ' exceeded', - config, null, lastRequest)); - } - }); + if (serializedParams) { + var hashmarkIndex = url.indexOf('#'); + if (hashmarkIndex !== -1) { + url = url.slice(0, hashmarkIndex); + } - stream.on('error', function handleStreamError(err) { - if (req.aborted) return; - reject(enhanceError(err, config, null, lastRequest)); - }); + url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams; + } - stream.on('end', function handleStreamEnd() { - var responseData = Buffer.concat(responseBuffer); - if (config.responseType !== 'arraybuffer') { - responseData = responseData.toString(config.responseEncoding); - } + return url; +}; - response.data = responseData; - settle(resolve, reject, response); - }); - } - }); - // Handle errors - req.on('error', function handleRequestError(err) { - if (req.aborted) return; - reject(enhanceError(err, config, null, req)); - }); +/***/ }), +/* 446 */ +/***/ (function(module, exports, __webpack_require__) { - // Handle request timeout - if (config.timeout) { - // Sometime, the response will be very slow, and does not respond, the connect event will be block by event loop system. - // And timer callback will be fired, and abort() will be invoked before connection, then get "socket hang up" and code ECONNRESET. - // At this time, if we have a large number of request, nodejs will hang up some socket on background. and the number will up and up. - // And then these socket which be hang up will devoring CPU little by little. - // ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect. - req.setTimeout(config.timeout, function handleRequestTimeout() { - req.abort(); - reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED', req)); - }); - } +"use strict"; - if (config.cancelToken) { - // Handle cancellation - config.cancelToken.promise.then(function onCanceled(cancel) { - if (req.aborted) return; - req.abort(); - reject(cancel); - }); - } +var utils = __webpack_require__(442); - // Send the request - if (utils.isStream(data)) { - data.on('error', function handleStreamError(err) { - reject(enhanceError(err, config, null, req)); - }).pipe(req); - } else { - req.end(data); - } +function InterceptorManager() { + this.handlers = []; +} + +/** + * Add a new interceptor to the stack + * + * @param {Function} fulfilled The function to handle `then` for a `Promise` + * @param {Function} rejected The function to handle `reject` for a `Promise` + * + * @return {Number} An ID used to remove interceptor later + */ +InterceptorManager.prototype.use = function use(fulfilled, rejected) { + this.handlers.push({ + fulfilled: fulfilled, + rejected: rejected }); + return this.handlers.length - 1; }; +/** + * Remove an interceptor from the stack + * + * @param {Number} id The ID that was returned by `use` + */ +InterceptorManager.prototype.eject = function eject(id) { + if (this.handlers[id]) { + this.handlers[id] = null; + } +}; -/***/ }), -/* 476 */ -/***/ (function(module, exports) { - -module.exports = require("http"); +/** + * Iterate over all the registered interceptors + * + * This method is particularly useful for skipping over any + * interceptors that may have become `null` calling `eject`. + * + * @param {Function} fn The function to call for each interceptor + */ +InterceptorManager.prototype.forEach = function forEach(fn) { + utils.forEach(this.handlers, function forEachHandler(h) { + if (h !== null) { + fn(h); + } + }); +}; -/***/ }), -/* 477 */ -/***/ (function(module, exports) { +module.exports = InterceptorManager; -module.exports = require("https"); /***/ }), -/* 478 */ +/* 447 */ /***/ (function(module, exports, __webpack_require__) { -var url = __webpack_require__(452); -var http = __webpack_require__(476); -var https = __webpack_require__(477); -var assert = __webpack_require__(30); -var Writable = __webpack_require__(27).Writable; -var debug = __webpack_require__(479)("follow-redirects"); - -// RFC7231§4.2.1: Of the request methods defined by this specification, -// the GET, HEAD, OPTIONS, and TRACE methods are defined to be safe. -var SAFE_METHODS = { GET: true, HEAD: true, OPTIONS: true, TRACE: true }; +"use strict"; -// Create handlers that pass events from native requests -var eventHandlers = Object.create(null); -["abort", "aborted", "error", "socket", "timeout"].forEach(function (event) { - eventHandlers[event] = function (arg) { - this._redirectable.emit(event, arg); - }; -}); -// An HTTP(S) request that can be redirected -function RedirectableRequest(options, responseCallback) { - // Initialize the request - Writable.call(this); - options.headers = options.headers || {}; - this._options = options; - this._redirectCount = 0; - this._redirects = []; - this._requestBodyLength = 0; - this._requestBodyBuffers = []; +var utils = __webpack_require__(442); +var transformData = __webpack_require__(448); +var isCancel = __webpack_require__(449); +var defaults = __webpack_require__(450); - // Since http.request treats host as an alias of hostname, - // but the url module interprets host as hostname plus port, - // eliminate the host property to avoid confusion. - if (options.host) { - // Use hostname if set, because it has precedence - if (!options.hostname) { - options.hostname = options.host; - } - delete options.host; +/** + * Throws a `Cancel` if cancellation has been requested. + */ +function throwIfCancellationRequested(config) { + if (config.cancelToken) { + config.cancelToken.throwIfRequested(); } +} - // Attach a callback if passed - if (responseCallback) { - this.on("response", responseCallback); - } +/** + * Dispatch a request to the server using the configured adapter. + * + * @param {object} config The config that is to be used for the request + * @returns {Promise} The Promise to be fulfilled + */ +module.exports = function dispatchRequest(config) { + throwIfCancellationRequested(config); - // React to responses of native requests - var self = this; - this._onNativeResponse = function (response) { - self._processResponse(response); - }; + // Ensure headers exist + config.headers = config.headers || {}; - // Complete the URL object when necessary - if (!options.pathname && options.path) { - var searchPos = options.path.indexOf("?"); - if (searchPos < 0) { - options.pathname = options.path; - } - else { - options.pathname = options.path.substring(0, searchPos); - options.search = options.path.substring(searchPos); + // Transform request data + config.data = transformData( + config.data, + config.headers, + config.transformRequest + ); + + // Flatten headers + config.headers = utils.merge( + config.headers.common || {}, + config.headers[config.method] || {}, + config.headers + ); + + utils.forEach( + ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'], + function cleanHeaderConfig(method) { + delete config.headers[method]; } - } + ); - // Perform the first request - this._performRequest(); -} -RedirectableRequest.prototype = Object.create(Writable.prototype); + var adapter = config.adapter || defaults.adapter; -// Writes buffered data to the current native request -RedirectableRequest.prototype.write = function (data, encoding, callback) { - // Validate input and shift parameters if necessary - if (!(typeof data === "string" || typeof data === "object" && ("length" in data))) { - throw new Error("data should be a string, Buffer or Uint8Array"); - } - if (typeof encoding === "function") { - callback = encoding; - encoding = null; - } + return adapter(config).then(function onAdapterResolution(response) { + throwIfCancellationRequested(config); - // Ignore empty buffers, since writing them doesn't invoke the callback - // https://github.com/nodejs/node/issues/22066 - if (data.length === 0) { - if (callback) { - callback(); - } - return; - } - // Only write when we don't exceed the maximum body length - if (this._requestBodyLength + data.length <= this._options.maxBodyLength) { - this._requestBodyLength += data.length; - this._requestBodyBuffers.push({ data: data, encoding: encoding }); - this._currentRequest.write(data, encoding, callback); - } - // Error when we exceed the maximum body length - else { - this.emit("error", new Error("Request body larger than maxBodyLength limit")); - this.abort(); - } -}; + // Transform response data + response.data = transformData( + response.data, + response.headers, + config.transformResponse + ); -// Ends the current native request -RedirectableRequest.prototype.end = function (data, encoding, callback) { - // Shift parameters if necessary - if (typeof data === "function") { - callback = data; - data = encoding = null; - } - else if (typeof encoding === "function") { - callback = encoding; - encoding = null; - } + return response; + }, function onAdapterRejection(reason) { + if (!isCancel(reason)) { + throwIfCancellationRequested(config); - // Write data and end - var currentRequest = this._currentRequest; - this.write(data || "", encoding, function () { - currentRequest.end(null, null, callback); + // Transform response data + if (reason && reason.response) { + reason.response.data = transformData( + reason.response.data, + reason.response.headers, + config.transformResponse + ); + } + } + + return Promise.reject(reason); }); }; -// Sets a header value on the current native request -RedirectableRequest.prototype.setHeader = function (name, value) { - this._options.headers[name] = value; - this._currentRequest.setHeader(name, value); -}; -// Clears a header value on the current native request -RedirectableRequest.prototype.removeHeader = function (name) { - delete this._options.headers[name]; - this._currentRequest.removeHeader(name); -}; +/***/ }), +/* 448 */ +/***/ (function(module, exports, __webpack_require__) { -// Proxy all other public ClientRequest methods -[ - "abort", "flushHeaders", "getHeader", - "setNoDelay", "setSocketKeepAlive", "setTimeout", -].forEach(function (method) { - RedirectableRequest.prototype[method] = function (a, b) { - return this._currentRequest[method](a, b); - }; -}); +"use strict"; -// Proxy all public ClientRequest properties -["aborted", "connection", "socket"].forEach(function (property) { - Object.defineProperty(RedirectableRequest.prototype, property, { - get: function () { return this._currentRequest[property]; }, - }); -}); -// Executes the next native request (initial or redirect) -RedirectableRequest.prototype._performRequest = function () { - // Load the native protocol - var protocol = this._options.protocol; - var nativeProtocol = this._options.nativeProtocols[protocol]; - if (!nativeProtocol) { - this.emit("error", new Error("Unsupported protocol " + protocol)); - return; - } - - // If specified, use the agent corresponding to the protocol - // (HTTP and HTTPS use different types of agents) - if (this._options.agents) { - var scheme = protocol.substr(0, protocol.length - 1); - this._options.agent = this._options.agents[scheme]; - } - - // Create the native request - var request = this._currentRequest = - nativeProtocol.request(this._options, this._onNativeResponse); - this._currentUrl = url.format(this._options); +var utils = __webpack_require__(442); - // Set up event handlers - request._redirectable = this; - for (var event in eventHandlers) { - /* istanbul ignore else */ - if (event) { - request.on(event, eventHandlers[event]); - } - } +/** + * Transform the data for a request or a response + * + * @param {Object|String} data The data to be transformed + * @param {Array} headers The headers for the request or response + * @param {Array|Function} fns A single function or Array of functions + * @returns {*} The resulting transformed data + */ +module.exports = function transformData(data, headers, fns) { + /*eslint no-param-reassign:0*/ + utils.forEach(fns, function transform(fn) { + data = fn(data, headers); + }); - // End a redirected request - // (The first request must be ended explicitly with RedirectableRequest#end) - if (this._isRedirect) { - // Write the request entity and end. - var i = 0; - var buffers = this._requestBodyBuffers; - (function writeNext() { - if (i < buffers.length) { - var buffer = buffers[i++]; - request.write(buffer.data, buffer.encoding, writeNext); - } - else { - request.end(); - } - }()); - } + return data; }; -// Processes a response from the current native request -RedirectableRequest.prototype._processResponse = function (response) { - // Store the redirected response - if (this._options.trackRedirects) { - this._redirects.push({ - url: this._currentUrl, - headers: response.headers, - statusCode: response.statusCode, - }); - } - - // RFC7231§6.4: The 3xx (Redirection) class of status code indicates - // that further action needs to be taken by the user agent in order to - // fulfill the request. If a Location header field is provided, - // the user agent MAY automatically redirect its request to the URI - // referenced by the Location field value, - // even if the specific status code is not understood. - var location = response.headers.location; - if (location && this._options.followRedirects !== false && - response.statusCode >= 300 && response.statusCode < 400) { - // RFC7231§6.4: A client SHOULD detect and intervene - // in cyclical redirections (i.e., "infinite" redirection loops). - if (++this._redirectCount > this._options.maxRedirects) { - this.emit("error", new Error("Max redirects exceeded.")); - return; - } - - // RFC7231§6.4: Automatic redirection needs to done with - // care for methods not known to be safe […], - // since the user might not wish to redirect an unsafe request. - // RFC7231§6.4.7: The 307 (Temporary Redirect) status code indicates - // that the target resource resides temporarily under a different URI - // and the user agent MUST NOT change the request method - // if it performs an automatic redirection to that URI. - var header; - var headers = this._options.headers; - if (response.statusCode !== 307 && !(this._options.method in SAFE_METHODS)) { - this._options.method = "GET"; - // Drop a possible entity and headers related to it - this._requestBodyBuffers = []; - for (header in headers) { - if (/^content-/i.test(header)) { - delete headers[header]; - } - } - } - // Drop the Host header, as the redirect might lead to a different host - if (!this._isRedirect) { - for (header in headers) { - if (/^host$/i.test(header)) { - delete headers[header]; - } - } - } +/***/ }), +/* 449 */ +/***/ (function(module, exports, __webpack_require__) { - // Perform the redirected request - var redirectUrl = url.resolve(this._currentUrl, location); - debug("redirecting to", redirectUrl); - Object.assign(this._options, url.parse(redirectUrl)); - this._isRedirect = true; - this._performRequest(); +"use strict"; - // Discard the remainder of the response to avoid waiting for data - response.destroy(); - } - else { - // The response is not a redirect; return it as-is - response.responseUrl = this._currentUrl; - response.redirects = this._redirects; - this.emit("response", response); - // Clean up - this._requestBodyBuffers = []; - } +module.exports = function isCancel(value) { + return !!(value && value.__CANCEL__); }; -// Wraps the key/value object of protocols with redirect functionality -function wrap(protocols) { - // Default settings - var exports = { - maxRedirects: 21, - maxBodyLength: 10 * 1024 * 1024, - }; - - // Wrap each protocol - var nativeProtocols = {}; - Object.keys(protocols).forEach(function (scheme) { - var protocol = scheme + ":"; - var nativeProtocol = nativeProtocols[protocol] = protocols[scheme]; - var wrappedProtocol = exports[scheme] = Object.create(nativeProtocol); - - // Executes a request, following redirects - wrappedProtocol.request = function (options, callback) { - if (typeof options === "string") { - options = url.parse(options); - options.maxRedirects = exports.maxRedirects; - } - else { - options = Object.assign({ - protocol: protocol, - maxRedirects: exports.maxRedirects, - maxBodyLength: exports.maxBodyLength, - }, options); - } - options.nativeProtocols = nativeProtocols; - assert.equal(options.protocol, protocol, "protocol mismatch"); - debug("options", options); - return new RedirectableRequest(options, callback); - }; - // Executes a GET request, following redirects - wrappedProtocol.get = function (options, callback) { - var request = wrappedProtocol.request(options, callback); - request.end(); - return request; - }; - }); - return exports; -} +/***/ }), +/* 450 */ +/***/ (function(module, exports, __webpack_require__) { -// Exports -module.exports = wrap({ http: http, https: https }); -module.exports.wrap = wrap; +"use strict"; -/***/ }), -/* 479 */ -/***/ (function(module, exports, __webpack_require__) { +var utils = __webpack_require__(442); +var normalizeHeaderName = __webpack_require__(451); -/** - * Detect Electron renderer process, which is node, but we should - * treat as a browser. - */ +var DEFAULT_CONTENT_TYPE = { + 'Content-Type': 'application/x-www-form-urlencoded' +}; -if (typeof process === 'undefined' || process.type === 'renderer') { - module.exports = __webpack_require__(480); -} else { - module.exports = __webpack_require__(483); +function setContentTypeIfUnset(headers, value) { + if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) { + headers['Content-Type'] = value; + } } +function getDefaultAdapter() { + var adapter; + if (typeof XMLHttpRequest !== 'undefined') { + // For browsers use XHR adapter + adapter = __webpack_require__(452); + } else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') { + // For node use HTTP adapter + adapter = __webpack_require__(462); + } + return adapter; +} -/***/ }), -/* 480 */ -/***/ (function(module, exports, __webpack_require__) { +var defaults = { + adapter: getDefaultAdapter(), -/** - * This is the web browser implementation of `debug()`. - * - * Expose `debug()` as the module. - */ + transformRequest: [function transformRequest(data, headers) { + normalizeHeaderName(headers, 'Accept'); + normalizeHeaderName(headers, 'Content-Type'); + if (utils.isFormData(data) || + utils.isArrayBuffer(data) || + utils.isBuffer(data) || + utils.isStream(data) || + utils.isFile(data) || + utils.isBlob(data) + ) { + return data; + } + if (utils.isArrayBufferView(data)) { + return data.buffer; + } + if (utils.isURLSearchParams(data)) { + setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8'); + return data.toString(); + } + if (utils.isObject(data)) { + setContentTypeIfUnset(headers, 'application/json;charset=utf-8'); + return JSON.stringify(data); + } + return data; + }], -exports = module.exports = __webpack_require__(481); -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.storage = 'undefined' != typeof chrome - && 'undefined' != typeof chrome.storage - ? chrome.storage.local - : localstorage(); + transformResponse: [function transformResponse(data) { + /*eslint no-param-reassign:0*/ + if (typeof data === 'string') { + try { + data = JSON.parse(data); + } catch (e) { /* Ignore */ } + } + return data; + }], -/** - * Colors. - */ + /** + * A timeout in milliseconds to abort a request. If set to 0 (default) a + * timeout is not created. + */ + timeout: 0, -exports.colors = [ - '#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', - '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', - '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', - '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', - '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', - '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', - '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', - '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', - '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', - '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', - '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33' -]; + xsrfCookieName: 'XSRF-TOKEN', + xsrfHeaderName: 'X-XSRF-TOKEN', -/** - * Currently only WebKit-based Web Inspectors, Firefox >= v31, - * and the Firebug extension (any Firefox version) are known - * to support "%c" CSS customizations. - * - * TODO: add a `localStorage` variable to explicitly enable/disable colors - */ + maxContentLength: -1, -function useColors() { - // NB: In an Electron preload script, document will be defined but not fully - // initialized. Since we know we're in Chrome, we'll just detect this case - // explicitly - if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') { - return true; + validateStatus: function validateStatus(status) { + return status >= 200 && status < 300; } +}; - // Internet Explorer and Edge do not support colors. - if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { - return false; +defaults.headers = { + common: { + 'Accept': 'application/json, text/plain, */*' } +}; - // is webkit? http://stackoverflow.com/a/16459606/376773 - // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 - return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || - // is firebug? http://stackoverflow.com/a/398120/376773 - (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || - // is firefox >= v31? - // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || - // double check webkit in userAgent just in case we are in a worker - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); -} - -/** - * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. - */ +utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) { + defaults.headers[method] = {}; +}); -exports.formatters.j = function(v) { - try { - return JSON.stringify(v); - } catch (err) { - return '[UnexpectedJSONParseError]: ' + err.message; - } -}; +utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { + defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE); +}); +module.exports = defaults; -/** - * Colorize log arguments if enabled. - * - * @api public - */ -function formatArgs(args) { - var useColors = this.useColors; +/***/ }), +/* 451 */ +/***/ (function(module, exports, __webpack_require__) { - args[0] = (useColors ? '%c' : '') - + this.namespace - + (useColors ? ' %c' : ' ') - + args[0] - + (useColors ? '%c ' : ' ') - + '+' + exports.humanize(this.diff); +"use strict"; - if (!useColors) return; - var c = 'color: ' + this.color; - args.splice(1, 0, c, 'color: inherit') +var utils = __webpack_require__(442); - // the final "%c" is somewhat tricky, because there could be other - // arguments passed either before or after the %c, so we need to - // figure out the correct index to insert the CSS into - var index = 0; - var lastC = 0; - args[0].replace(/%[a-zA-Z%]/g, function(match) { - if ('%%' === match) return; - index++; - if ('%c' === match) { - // we only are interested in the *last* %c - // (the user may have provided their own) - lastC = index; +module.exports = function normalizeHeaderName(headers, normalizedName) { + utils.forEach(headers, function processHeader(value, name) { + if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) { + headers[normalizedName] = value; + delete headers[name]; } }); +}; - args.splice(lastC, 0, c); -} -/** - * Invokes `console.log()` when available. - * No-op when `console.log` is not a "function". - * - * @api public - */ +/***/ }), +/* 452 */ +/***/ (function(module, exports, __webpack_require__) { -function log() { - // this hackery is required for IE8/9, where - // the `console.log` function doesn't have 'apply' - return 'object' === typeof console - && console.log - && Function.prototype.apply.call(console.log, console, arguments); -} +"use strict"; -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ -function save(namespaces) { - try { - if (null == namespaces) { - exports.storage.removeItem('debug'); - } else { - exports.storage.debug = namespaces; - } - } catch(e) {} -} +var utils = __webpack_require__(442); +var settle = __webpack_require__(453); +var buildURL = __webpack_require__(445); +var buildFullPath = __webpack_require__(456); +var parseHeaders = __webpack_require__(459); +var isURLSameOrigin = __webpack_require__(460); +var createError = __webpack_require__(454); -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ +module.exports = function xhrAdapter(config) { + return new Promise(function dispatchXhrRequest(resolve, reject) { + var requestData = config.data; + var requestHeaders = config.headers; -function load() { - var r; - try { - r = exports.storage.debug; - } catch(e) {} + if (utils.isFormData(requestData)) { + delete requestHeaders['Content-Type']; // Let the browser set it + } - // If debug isn't set in LS, and we're in Electron, try to load $DEBUG - if (!r && typeof process !== 'undefined' && 'env' in process) { - r = process.env.DEBUG; - } + var request = new XMLHttpRequest(); - return r; -} + // HTTP basic authentication + if (config.auth) { + var username = config.auth.username || ''; + var password = config.auth.password || ''; + requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password); + } -/** - * Enable namespaces listed in `localStorage.debug` initially. - */ + var fullPath = buildFullPath(config.baseURL, config.url); + request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true); -exports.enable(load()); + // Set the request timeout in MS + request.timeout = config.timeout; -/** - * Localstorage attempts to return the localstorage. - * - * This is necessary because safari throws - * when a user disables cookies/localstorage - * and you attempt to access it. - * - * @return {LocalStorage} - * @api private - */ + // Listen for ready state + request.onreadystatechange = function handleLoad() { + if (!request || request.readyState !== 4) { + return; + } -function localstorage() { - try { - return window.localStorage; - } catch (e) {} -} + // The request errored out and we didn't get a response, this will be + // handled by onerror instead + // With one exception: request that using file: protocol, most browsers + // will return status as 0 even though it's a successful request + if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { + return; + } + // Prepare the response + var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null; + var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response; + var response = { + data: responseData, + status: request.status, + statusText: request.statusText, + headers: responseHeaders, + config: config, + request: request + }; -/***/ }), -/* 481 */ -/***/ (function(module, exports, __webpack_require__) { + settle(resolve, reject, response); + // Clean up request + request = null; + }; -/** - * This is the common logic for both the Node.js and web browser - * implementations of `debug()`. - * - * Expose `debug()` as the module. - */ + // Handle browser request cancellation (as opposed to a manual cancellation) + request.onabort = function handleAbort() { + if (!request) { + return; + } -exports = module.exports = createDebug.debug = createDebug['default'] = createDebug; -exports.coerce = coerce; -exports.disable = disable; -exports.enable = enable; -exports.enabled = enabled; -exports.humanize = __webpack_require__(482); + reject(createError('Request aborted', config, 'ECONNABORTED', request)); -/** - * Active `debug` instances. - */ -exports.instances = []; - -/** - * The currently active debug mode names, and names to skip. - */ - -exports.names = []; -exports.skips = []; - -/** - * Map of special "%n" handling functions, for the debug "format" argument. - * - * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". - */ - -exports.formatters = {}; - -/** - * Select a color. - * @param {String} namespace - * @return {Number} - * @api private - */ + // Clean up request + request = null; + }; -function selectColor(namespace) { - var hash = 0, i; + // Handle low level network errors + request.onerror = function handleError() { + // Real errors are hidden from us by the browser + // onerror should only fire if it's a network error + reject(createError('Network Error', config, null, request)); - for (i in namespace) { - hash = ((hash << 5) - hash) + namespace.charCodeAt(i); - hash |= 0; // Convert to 32bit integer - } + // Clean up request + request = null; + }; - return exports.colors[Math.abs(hash) % exports.colors.length]; -} + // Handle timeout + request.ontimeout = function handleTimeout() { + var timeoutErrorMessage = 'timeout of ' + config.timeout + 'ms exceeded'; + if (config.timeoutErrorMessage) { + timeoutErrorMessage = config.timeoutErrorMessage; + } + reject(createError(timeoutErrorMessage, config, 'ECONNABORTED', + request)); -/** - * Create a debugger with the given `namespace`. - * - * @param {String} namespace - * @return {Function} - * @api public - */ + // Clean up request + request = null; + }; -function createDebug(namespace) { + // Add xsrf header + // This is only done if running in a standard browser environment. + // Specifically not if we're in a web worker, or react-native. + if (utils.isStandardBrowserEnv()) { + var cookies = __webpack_require__(461); - var prevTime; + // Add xsrf header + var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ? + cookies.read(config.xsrfCookieName) : + undefined; - function debug() { - // disabled? - if (!debug.enabled) return; + if (xsrfValue) { + requestHeaders[config.xsrfHeaderName] = xsrfValue; + } + } - var self = debug; + // Add headers to the request + if ('setRequestHeader' in request) { + utils.forEach(requestHeaders, function setRequestHeader(val, key) { + if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') { + // Remove Content-Type if data is undefined + delete requestHeaders[key]; + } else { + // Otherwise add header to the request + request.setRequestHeader(key, val); + } + }); + } - // set `diff` timestamp - var curr = +new Date(); - var ms = curr - (prevTime || curr); - self.diff = ms; - self.prev = prevTime; - self.curr = curr; - prevTime = curr; + // Add withCredentials to request if needed + if (!utils.isUndefined(config.withCredentials)) { + request.withCredentials = !!config.withCredentials; + } - // turn the `arguments` into a proper Array - var args = new Array(arguments.length); - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i]; + // Add responseType to request if needed + if (config.responseType) { + try { + request.responseType = config.responseType; + } catch (e) { + // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2. + // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function. + if (config.responseType !== 'json') { + throw e; + } + } } - args[0] = exports.coerce(args[0]); + // Handle progress if needed + if (typeof config.onDownloadProgress === 'function') { + request.addEventListener('progress', config.onDownloadProgress); + } - if ('string' !== typeof args[0]) { - // anything else let's inspect with %O - args.unshift('%O'); + // Not all browsers support upload events + if (typeof config.onUploadProgress === 'function' && request.upload) { + request.upload.addEventListener('progress', config.onUploadProgress); } - // apply any `formatters` transformations - var index = 0; - args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { - // if we encounter an escaped % then don't increase the array index - if (match === '%%') return match; - index++; - var formatter = exports.formatters[format]; - if ('function' === typeof formatter) { - var val = args[index]; - match = formatter.call(self, val); + if (config.cancelToken) { + // Handle cancellation + config.cancelToken.promise.then(function onCanceled(cancel) { + if (!request) { + return; + } - // now we need to remove `args[index]` since it's inlined in the `format` - args.splice(index, 1); - index--; - } - return match; - }); + request.abort(); + reject(cancel); + // Clean up request + request = null; + }); + } - // apply env-specific formatting (colors, etc.) - exports.formatArgs.call(self, args); + if (requestData === undefined) { + requestData = null; + } - var logFn = debug.log || exports.log || console.log.bind(console); - logFn.apply(self, args); - } + // Send the request + request.send(requestData); + }); +}; - debug.namespace = namespace; - debug.enabled = exports.enabled(namespace); - debug.useColors = exports.useColors(); - debug.color = selectColor(namespace); - debug.destroy = destroy; - // env-specific initialization logic for debug instances - if ('function' === typeof exports.init) { - exports.init(debug); - } +/***/ }), +/* 453 */ +/***/ (function(module, exports, __webpack_require__) { - exports.instances.push(debug); +"use strict"; - return debug; -} -function destroy () { - var index = exports.instances.indexOf(this); - if (index !== -1) { - exports.instances.splice(index, 1); - return true; - } else { - return false; - } -} +var createError = __webpack_require__(454); /** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. + * Resolve or reject a Promise based on response status. * - * @param {String} namespaces - * @api public + * @param {Function} resolve A function that resolves the promise. + * @param {Function} reject A function that rejects the promise. + * @param {object} response The response. */ +module.exports = function settle(resolve, reject, response) { + var validateStatus = response.config.validateStatus; + if (!validateStatus || validateStatus(response.status)) { + resolve(response); + } else { + reject(createError( + 'Request failed with status code ' + response.status, + response.config, + null, + response.request, + response + )); + } +}; -function enable(namespaces) { - exports.save(namespaces); - exports.names = []; - exports.skips = []; +/***/ }), +/* 454 */ +/***/ (function(module, exports, __webpack_require__) { - var i; - var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); - var len = split.length; +"use strict"; - for (i = 0; i < len; i++) { - if (!split[i]) continue; // ignore empty strings - namespaces = split[i].replace(/\*/g, '.*?'); - if (namespaces[0] === '-') { - exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - exports.names.push(new RegExp('^' + namespaces + '$')); - } - } - for (i = 0; i < exports.instances.length; i++) { - var instance = exports.instances[i]; - instance.enabled = exports.enabled(instance.namespace); - } -} +var enhanceError = __webpack_require__(455); /** - * Disable debug output. + * Create an Error with the specified message, config, error code, request and response. * - * @api public + * @param {string} message The error message. + * @param {Object} config The config. + * @param {string} [code] The error code (for example, 'ECONNABORTED'). + * @param {Object} [request] The request. + * @param {Object} [response] The response. + * @returns {Error} The created error. */ +module.exports = function createError(message, config, code, request, response) { + var error = new Error(message); + return enhanceError(error, config, code, request, response); +}; -function disable() { - exports.enable(''); -} -/** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ +/***/ }), +/* 455 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; -function enabled(name) { - if (name[name.length - 1] === '*') { - return true; - } - var i, len; - for (i = 0, len = exports.skips.length; i < len; i++) { - if (exports.skips[i].test(name)) { - return false; - } - } - for (i = 0, len = exports.names.length; i < len; i++) { - if (exports.names[i].test(name)) { - return true; - } - } - return false; -} /** - * Coerce `val`. + * Update an Error with the specified config, error code, and response. * - * @param {Mixed} val - * @return {Mixed} - * @api private + * @param {Error} error The error to update. + * @param {Object} config The config. + * @param {string} [code] The error code (for example, 'ECONNABORTED'). + * @param {Object} [request] The request. + * @param {Object} [response] The response. + * @returns {Error} The error. */ +module.exports = function enhanceError(error, config, code, request, response) { + error.config = config; + if (code) { + error.code = code; + } -function coerce(val) { - if (val instanceof Error) return val.stack || val.message; - return val; -} + error.request = request; + error.response = response; + error.isAxiosError = true; + + error.toJSON = function() { + return { + // Standard + message: this.message, + name: this.name, + // Microsoft + description: this.description, + number: this.number, + // Mozilla + fileName: this.fileName, + lineNumber: this.lineNumber, + columnNumber: this.columnNumber, + stack: this.stack, + // Axios + config: this.config, + code: this.code + }; + }; + return error; +}; /***/ }), -/* 482 */ -/***/ (function(module, exports) { +/* 456 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Helpers. - */ +"use strict"; -var s = 1000; -var m = s * 60; -var h = m * 60; -var d = h * 24; -var y = d * 365.25; + +var isAbsoluteURL = __webpack_require__(457); +var combineURLs = __webpack_require__(458); /** - * Parse or format the given `val`. - * - * Options: - * - * - `long` verbose formatting [false] + * Creates a new URL by combining the baseURL with the requestedURL, + * only when the requestedURL is not already an absolute URL. + * If the requestURL is absolute, this function returns the requestedURL untouched. * - * @param {String|Number} val - * @param {Object} [options] - * @throws {Error} throw an error if val is not a non-empty string or a number - * @return {String|Number} - * @api public + * @param {string} baseURL The base URL + * @param {string} requestedURL Absolute or relative URL to combine + * @returns {string} The combined full path */ - -module.exports = function(val, options) { - options = options || {}; - var type = typeof val; - if (type === 'string' && val.length > 0) { - return parse(val); - } else if (type === 'number' && isNaN(val) === false) { - return options.long ? fmtLong(val) : fmtShort(val); +module.exports = function buildFullPath(baseURL, requestedURL) { + if (baseURL && !isAbsoluteURL(requestedURL)) { + return combineURLs(baseURL, requestedURL); } - throw new Error( - 'val is not a non-empty string or a valid number. val=' + - JSON.stringify(val) - ); + return requestedURL; }; -/** - * Parse the given `str` and return milliseconds. - * - * @param {String} str - * @return {Number} - * @api private - */ -function parse(str) { - str = String(str); - if (str.length > 100) { - return; - } - var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec( - str - ); - if (!match) { - return; - } - var n = parseFloat(match[1]); - var type = (match[2] || 'ms').toLowerCase(); - switch (type) { - case 'years': - case 'year': - case 'yrs': - case 'yr': - case 'y': - return n * y; - case 'days': - case 'day': - case 'd': - return n * d; - case 'hours': - case 'hour': - case 'hrs': - case 'hr': - case 'h': - return n * h; - case 'minutes': - case 'minute': - case 'mins': - case 'min': - case 'm': - return n * m; - case 'seconds': - case 'second': - case 'secs': - case 'sec': - case 's': - return n * s; - case 'milliseconds': - case 'millisecond': - case 'msecs': - case 'msec': - case 'ms': - return n; - default: - return undefined; - } -} +/***/ }), +/* 457 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Short format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ +"use strict"; -function fmtShort(ms) { - if (ms >= d) { - return Math.round(ms / d) + 'd'; - } - if (ms >= h) { - return Math.round(ms / h) + 'h'; - } - if (ms >= m) { - return Math.round(ms / m) + 'm'; - } - if (ms >= s) { - return Math.round(ms / s) + 's'; - } - return ms + 'ms'; -} /** - * Long format for `ms`. + * Determines whether the specified URL is absolute * - * @param {Number} ms - * @return {String} - * @api private - */ - -function fmtLong(ms) { - return plural(ms, d, 'day') || - plural(ms, h, 'hour') || - plural(ms, m, 'minute') || - plural(ms, s, 'second') || - ms + ' ms'; -} - -/** - * Pluralization helper. + * @param {string} url The URL to test + * @returns {boolean} True if the specified URL is absolute, otherwise false */ - -function plural(ms, n, name) { - if (ms < n) { - return; - } - if (ms < n * 1.5) { - return Math.floor(ms / n) + ' ' + name; - } - return Math.ceil(ms / n) + ' ' + name + 's'; -} +module.exports = function isAbsoluteURL(url) { + // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). + // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed + // by any combination of letters, digits, plus, period, or hyphen. + return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url); +}; /***/ }), -/* 483 */ +/* 458 */ /***/ (function(module, exports, __webpack_require__) { -/** - * Module dependencies. - */ +"use strict"; -var tty = __webpack_require__(484); -var util = __webpack_require__(29); /** - * This is the Node.js implementation of `debug()`. + * Creates a new URL by combining the specified URLs * - * Expose `debug()` as the module. - */ - -exports = module.exports = __webpack_require__(481); -exports.init = init; -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; - -/** - * Colors. + * @param {string} baseURL The base URL + * @param {string} relativeURL The relative URL + * @returns {string} The combined URL */ +module.exports = function combineURLs(baseURL, relativeURL) { + return relativeURL + ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') + : baseURL; +}; -exports.colors = [ 6, 2, 3, 4, 5, 1 ]; -try { - var supportsColor = __webpack_require__(485); - if (supportsColor && supportsColor.level >= 2) { - exports.colors = [ - 20, 21, 26, 27, 32, 33, 38, 39, 40, 41, 42, 43, 44, 45, 56, 57, 62, 63, 68, - 69, 74, 75, 76, 77, 78, 79, 80, 81, 92, 93, 98, 99, 112, 113, 128, 129, 134, - 135, 148, 149, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 178, 179, 184, 185, 196, 197, 198, 199, 200, 201, 202, 203, 204, - 205, 206, 207, 208, 209, 214, 215, 220, 221 - ]; - } -} catch (err) { - // swallow - we only care if `supports-color` is available; it doesn't have to be. -} +/***/ }), +/* 459 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Build up the default `inspectOpts` object from the environment variables. - * - * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js - */ +"use strict"; -exports.inspectOpts = Object.keys(process.env).filter(function (key) { - return /^debug_/i.test(key); -}).reduce(function (obj, key) { - // camel-case - var prop = key - .substring(6) - .toLowerCase() - .replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() }); - // coerce string value into JS value - var val = process.env[key]; - if (/^(yes|on|true|enabled)$/i.test(val)) val = true; - else if (/^(no|off|false|disabled)$/i.test(val)) val = false; - else if (val === 'null') val = null; - else val = Number(val); +var utils = __webpack_require__(442); - obj[prop] = val; - return obj; -}, {}); +// Headers whose duplicates are ignored by node +// c.f. https://nodejs.org/api/http.html#http_message_headers +var ignoreDuplicateOf = [ + 'age', 'authorization', 'content-length', 'content-type', 'etag', + 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since', + 'last-modified', 'location', 'max-forwards', 'proxy-authorization', + 'referer', 'retry-after', 'user-agent' +]; /** - * Is stdout a TTY? Colored output is enabled when `true`. + * Parse headers into an object + * + * ``` + * Date: Wed, 27 Aug 2014 08:58:49 GMT + * Content-Type: application/json + * Connection: keep-alive + * Transfer-Encoding: chunked + * ``` + * + * @param {String} headers Headers needing to be parsed + * @returns {Object} Headers parsed into an object */ +module.exports = function parseHeaders(headers) { + var parsed = {}; + var key; + var val; + var i; -function useColors() { - return 'colors' in exports.inspectOpts - ? Boolean(exports.inspectOpts.colors) - : tty.isatty(process.stderr.fd); -} - -/** - * Map %o to `util.inspect()`, all on a single line. - */ + if (!headers) { return parsed; } -exports.formatters.o = function(v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts) - .split('\n').map(function(str) { - return str.trim() - }).join(' '); -}; + utils.forEach(headers.split('\n'), function parser(line) { + i = line.indexOf(':'); + key = utils.trim(line.substr(0, i)).toLowerCase(); + val = utils.trim(line.substr(i + 1)); -/** - * Map %o to `util.inspect()`, allowing multiple lines if needed. - */ + if (key) { + if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) { + return; + } + if (key === 'set-cookie') { + parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]); + } else { + parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; + } + } + }); -exports.formatters.O = function(v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts); + return parsed; }; -/** - * Adds ANSI color escape codes if enabled. - * - * @api public - */ - -function formatArgs(args) { - var name = this.namespace; - var useColors = this.useColors; - - if (useColors) { - var c = this.color; - var colorCode = '\u001b[3' + (c < 8 ? c : '8;5;' + c); - var prefix = ' ' + colorCode + ';1m' + name + ' ' + '\u001b[0m'; - - args[0] = prefix + args[0].split('\n').join('\n' + prefix); - args.push(colorCode + 'm+' + exports.humanize(this.diff) + '\u001b[0m'); - } else { - args[0] = getDate() + name + ' ' + args[0]; - } -} - -function getDate() { - if (exports.inspectOpts.hideDate) { - return ''; - } else { - return new Date().toISOString() + ' '; - } -} -/** - * Invokes `util.format()` with the specified arguments and writes to stderr. - */ +/***/ }), +/* 460 */ +/***/ (function(module, exports, __webpack_require__) { -function log() { - return process.stderr.write(util.format.apply(util, arguments) + '\n'); -} +"use strict"; -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ -function save(namespaces) { - if (null == namespaces) { - // If you set a process.env field to null or undefined, it gets cast to the - // string 'null' or 'undefined'. Just delete instead. - delete process.env.DEBUG; - } else { - process.env.DEBUG = namespaces; - } -} +var utils = __webpack_require__(442); -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ +module.exports = ( + utils.isStandardBrowserEnv() ? -function load() { - return process.env.DEBUG; -} + // Standard browser envs have full support of the APIs needed to test + // whether the request URL is of the same origin as current location. + (function standardBrowserEnv() { + var msie = /(msie|trident)/i.test(navigator.userAgent); + var urlParsingNode = document.createElement('a'); + var originURL; -/** - * Init logic for `debug` instances. - * - * Create a new `inspectOpts` object in case `useColors` is set - * differently for a particular `debug` instance. - */ + /** + * Parse a URL to discover it's components + * + * @param {String} url The URL to be parsed + * @returns {Object} + */ + function resolveURL(url) { + var href = url; -function init (debug) { - debug.inspectOpts = {}; + if (msie) { + // IE needs attribute set twice to normalize properties + urlParsingNode.setAttribute('href', href); + href = urlParsingNode.href; + } - var keys = Object.keys(exports.inspectOpts); - for (var i = 0; i < keys.length; i++) { - debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; - } -} + urlParsingNode.setAttribute('href', href); -/** - * Enable namespaces listed in `process.env.DEBUG` initially. - */ + // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils + return { + href: urlParsingNode.href, + protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '', + host: urlParsingNode.host, + search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '', + hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '', + hostname: urlParsingNode.hostname, + port: urlParsingNode.port, + pathname: (urlParsingNode.pathname.charAt(0) === '/') ? + urlParsingNode.pathname : + '/' + urlParsingNode.pathname + }; + } -exports.enable(load()); + originURL = resolveURL(window.location.href); + /** + * Determine if a URL shares the same origin as the current location + * + * @param {String} requestURL The URL to test + * @returns {boolean} True if URL shares the same origin, otherwise false + */ + return function isURLSameOrigin(requestURL) { + var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL; + return (parsed.protocol === originURL.protocol && + parsed.host === originURL.host); + }; + })() : -/***/ }), -/* 484 */ -/***/ (function(module, exports) { + // Non standard browser envs (web workers, react-native) lack needed support. + (function nonStandardBrowserEnv() { + return function isURLSameOrigin() { + return true; + }; + })() +); -module.exports = require("tty"); /***/ }), -/* 485 */ +/* 461 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const os = __webpack_require__(11); -const hasFlag = __webpack_require__(12); - -const env = process.env; -let forceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false')) { - forceColor = false; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - forceColor = true; -} -if ('FORCE_COLOR' in env) { - forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; -} +var utils = __webpack_require__(442); -function translateLevel(level) { - if (level === 0) { - return false; - } +module.exports = ( + utils.isStandardBrowserEnv() ? - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} + // Standard browser envs support document.cookie + (function standardBrowserEnv() { + return { + write: function write(name, value, expires, path, domain, secure) { + var cookie = []; + cookie.push(name + '=' + encodeURIComponent(value)); -function supportsColor(stream) { - if (forceColor === false) { - return 0; - } + if (utils.isNumber(expires)) { + cookie.push('expires=' + new Date(expires).toGMTString()); + } - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } + if (utils.isString(path)) { + cookie.push('path=' + path); + } - if (hasFlag('color=256')) { - return 2; - } + if (utils.isString(domain)) { + cookie.push('domain=' + domain); + } - if (stream && !stream.isTTY && forceColor !== true) { - return 0; - } + if (secure === true) { + cookie.push('secure'); + } - const min = forceColor ? 1 : 0; + document.cookie = cookie.join('; '); + }, - if (process.platform === 'win32') { - // Node.js 7.5.0 is the first version of Node.js to include a patch to - // libuv that enables 256 color output on Windows. Anything earlier and it - // won't work. However, here we target Node.js 8 at minimum as it is an LTS - // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows - // release that supports 256 colors. Windows 10 build 14931 is the first release - // that supports 16m/TrueColor. - const osRelease = os.release().split('.'); - if ( - Number(process.versions.node.split('.')[0]) >= 8 && - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } + read: function read(name) { + var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)')); + return (match ? decodeURIComponent(match[3]) : null); + }, - return 1; - } + remove: function remove(name) { + this.write(name, '', Date.now() - 86400000); + } + }; + })() : - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; - } + // Non standard browser env (web workers, react-native) lack needed support. + (function nonStandardBrowserEnv() { + return { + write: function write() {}, + read: function read() { return null; }, + remove: function remove() {} + }; + })() +); - return min; - } - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } +/***/ }), +/* 462 */ +/***/ (function(module, exports, __webpack_require__) { - if (env.COLORTERM === 'truecolor') { - return 3; - } +"use strict"; - if ('TERM_PROGRAM' in env) { - const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } +var utils = __webpack_require__(442); +var settle = __webpack_require__(453); +var buildFullPath = __webpack_require__(456); +var buildURL = __webpack_require__(445); +var http = __webpack_require__(463); +var https = __webpack_require__(464); +var httpFollow = __webpack_require__(465).http; +var httpsFollow = __webpack_require__(465).https; +var url = __webpack_require__(439); +var zlib = __webpack_require__(473); +var pkg = __webpack_require__(474); +var createError = __webpack_require__(454); +var enhanceError = __webpack_require__(455); - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } +var isHttps = /https:?/; - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } +/*eslint consistent-return:0*/ +module.exports = function httpAdapter(config) { + return new Promise(function dispatchHttpRequest(resolvePromise, rejectPromise) { + var resolve = function resolve(value) { + resolvePromise(value); + }; + var reject = function reject(value) { + rejectPromise(value); + }; + var data = config.data; + var headers = config.headers; - if ('COLORTERM' in env) { - return 1; - } + // Set User-Agent (required by some servers) + // Only set header if it hasn't been set in config + // See https://github.com/axios/axios/issues/69 + if (!headers['User-Agent'] && !headers['user-agent']) { + headers['User-Agent'] = 'axios/' + pkg.version; + } - if (env.TERM === 'dumb') { - return min; - } + if (data && !utils.isStream(data)) { + if (Buffer.isBuffer(data)) { + // Nothing to do... + } else if (utils.isArrayBuffer(data)) { + data = Buffer.from(new Uint8Array(data)); + } else if (utils.isString(data)) { + data = Buffer.from(data, 'utf-8'); + } else { + return reject(createError( + 'Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream', + config + )); + } - return min; -} + // Add Content-Length header if data exists + headers['Content-Length'] = data.length; + } -function getSupportLevel(stream) { - const level = supportsColor(stream); - return translateLevel(level); -} + // HTTP basic authentication + var auth = undefined; + if (config.auth) { + var username = config.auth.username || ''; + var password = config.auth.password || ''; + auth = username + ':' + password; + } -module.exports = { - supportsColor: getSupportLevel, - stdout: getSupportLevel(process.stdout), - stderr: getSupportLevel(process.stderr) -}; + // Parse url + var fullPath = buildFullPath(config.baseURL, config.url); + var parsed = url.parse(fullPath); + var protocol = parsed.protocol || 'http:'; + if (!auth && parsed.auth) { + var urlAuth = parsed.auth.split(':'); + var urlUsername = urlAuth[0] || ''; + var urlPassword = urlAuth[1] || ''; + auth = urlUsername + ':' + urlPassword; + } -/***/ }), -/* 486 */ -/***/ (function(module, exports) { + if (auth) { + delete headers.Authorization; + } -module.exports = require("zlib"); + var isHttpsRequest = isHttps.test(protocol); + var agent = isHttpsRequest ? config.httpsAgent : config.httpAgent; -/***/ }), -/* 487 */ -/***/ (function(module) { + var options = { + path: buildURL(parsed.path, config.params, config.paramsSerializer).replace(/^\?/, ''), + method: config.method.toUpperCase(), + headers: headers, + agent: agent, + agents: { http: config.httpAgent, https: config.httpsAgent }, + auth: auth + }; -module.exports = JSON.parse("{\"name\":\"axios\",\"version\":\"0.19.2\",\"description\":\"Promise based HTTP client for the browser and node.js\",\"main\":\"index.js\",\"scripts\":{\"test\":\"grunt test && bundlesize\",\"start\":\"node ./sandbox/server.js\",\"build\":\"NODE_ENV=production grunt build\",\"preversion\":\"npm test\",\"version\":\"npm run build && grunt version && git add -A dist && git add CHANGELOG.md bower.json package.json\",\"postversion\":\"git push && git push --tags\",\"examples\":\"node ./examples/server.js\",\"coveralls\":\"cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js\",\"fix\":\"eslint --fix lib/**/*.js\"},\"repository\":{\"type\":\"git\",\"url\":\"https://github.com/axios/axios.git\"},\"keywords\":[\"xhr\",\"http\",\"ajax\",\"promise\",\"node\"],\"author\":\"Matt Zabriskie\",\"license\":\"MIT\",\"bugs\":{\"url\":\"https://github.com/axios/axios/issues\"},\"homepage\":\"https://github.com/axios/axios\",\"devDependencies\":{\"bundlesize\":\"^0.17.0\",\"coveralls\":\"^3.0.0\",\"es6-promise\":\"^4.2.4\",\"grunt\":\"^1.0.2\",\"grunt-banner\":\"^0.6.0\",\"grunt-cli\":\"^1.2.0\",\"grunt-contrib-clean\":\"^1.1.0\",\"grunt-contrib-watch\":\"^1.0.0\",\"grunt-eslint\":\"^20.1.0\",\"grunt-karma\":\"^2.0.0\",\"grunt-mocha-test\":\"^0.13.3\",\"grunt-ts\":\"^6.0.0-beta.19\",\"grunt-webpack\":\"^1.0.18\",\"istanbul-instrumenter-loader\":\"^1.0.0\",\"jasmine-core\":\"^2.4.1\",\"karma\":\"^1.3.0\",\"karma-chrome-launcher\":\"^2.2.0\",\"karma-coverage\":\"^1.1.1\",\"karma-firefox-launcher\":\"^1.1.0\",\"karma-jasmine\":\"^1.1.1\",\"karma-jasmine-ajax\":\"^0.1.13\",\"karma-opera-launcher\":\"^1.0.0\",\"karma-safari-launcher\":\"^1.0.0\",\"karma-sauce-launcher\":\"^1.2.0\",\"karma-sinon\":\"^1.0.5\",\"karma-sourcemap-loader\":\"^0.3.7\",\"karma-webpack\":\"^1.7.0\",\"load-grunt-tasks\":\"^3.5.2\",\"minimist\":\"^1.2.0\",\"mocha\":\"^5.2.0\",\"sinon\":\"^4.5.0\",\"typescript\":\"^2.8.1\",\"url-search-params\":\"^0.10.0\",\"webpack\":\"^1.13.1\",\"webpack-dev-server\":\"^1.14.1\"},\"browser\":{\"./lib/adapters/http.js\":\"./lib/adapters/xhr.js\"},\"typings\":\"./index.d.ts\",\"dependencies\":{\"follow-redirects\":\"1.5.10\"},\"bundlesize\":[{\"path\":\"./dist/axios.min.js\",\"threshold\":\"5kB\"}]}"); + if (config.socketPath) { + options.socketPath = config.socketPath; + } else { + options.hostname = parsed.hostname; + options.port = parsed.port; + } -/***/ }), -/* 488 */ -/***/ (function(module, exports, __webpack_require__) { + var proxy = config.proxy; + if (!proxy && proxy !== false) { + var proxyEnv = protocol.slice(0, -1) + '_proxy'; + var proxyUrl = process.env[proxyEnv] || process.env[proxyEnv.toUpperCase()]; + if (proxyUrl) { + var parsedProxyUrl = url.parse(proxyUrl); + var noProxyEnv = process.env.no_proxy || process.env.NO_PROXY; + var shouldProxy = true; -"use strict"; + if (noProxyEnv) { + var noProxy = noProxyEnv.split(',').map(function trim(s) { + return s.trim(); + }); + shouldProxy = !noProxy.some(function proxyMatch(proxyElement) { + if (!proxyElement) { + return false; + } + if (proxyElement === '*') { + return true; + } + if (proxyElement[0] === '.' && + parsed.hostname.substr(parsed.hostname.length - proxyElement.length) === proxyElement) { + return true; + } -var utils = __webpack_require__(455); + return parsed.hostname === proxyElement; + }); + } -/** - * Config-specific merge-function which creates a new config-object - * by merging two configuration objects together. - * - * @param {Object} config1 - * @param {Object} config2 - * @returns {Object} New object resulting from merging config2 to config1 - */ -module.exports = function mergeConfig(config1, config2) { - // eslint-disable-next-line no-param-reassign - config2 = config2 || {}; - var config = {}; - var valueFromConfig2Keys = ['url', 'method', 'params', 'data']; - var mergeDeepPropertiesKeys = ['headers', 'auth', 'proxy']; - var defaultToConfig2Keys = [ - 'baseURL', 'url', 'transformRequest', 'transformResponse', 'paramsSerializer', - 'timeout', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName', - 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', - 'maxContentLength', 'validateStatus', 'maxRedirects', 'httpAgent', - 'httpsAgent', 'cancelToken', 'socketPath' - ]; + if (shouldProxy) { + proxy = { + host: parsedProxyUrl.hostname, + port: parsedProxyUrl.port + }; - utils.forEach(valueFromConfig2Keys, function valueFromConfig2(prop) { - if (typeof config2[prop] !== 'undefined') { - config[prop] = config2[prop]; + if (parsedProxyUrl.auth) { + var proxyUrlAuth = parsedProxyUrl.auth.split(':'); + proxy.auth = { + username: proxyUrlAuth[0], + password: proxyUrlAuth[1] + }; + } + } + } } - }); - utils.forEach(mergeDeepPropertiesKeys, function mergeDeepProperties(prop) { - if (utils.isObject(config2[prop])) { - config[prop] = utils.deepMerge(config1[prop], config2[prop]); - } else if (typeof config2[prop] !== 'undefined') { - config[prop] = config2[prop]; - } else if (utils.isObject(config1[prop])) { - config[prop] = utils.deepMerge(config1[prop]); - } else if (typeof config1[prop] !== 'undefined') { - config[prop] = config1[prop]; - } - }); + if (proxy) { + options.hostname = proxy.host; + options.host = proxy.host; + options.headers.host = parsed.hostname + (parsed.port ? ':' + parsed.port : ''); + options.port = proxy.port; + options.path = protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path; - utils.forEach(defaultToConfig2Keys, function defaultToConfig2(prop) { - if (typeof config2[prop] !== 'undefined') { - config[prop] = config2[prop]; - } else if (typeof config1[prop] !== 'undefined') { - config[prop] = config1[prop]; + // Basic proxy authorization + if (proxy.auth) { + var base64 = Buffer.from(proxy.auth.username + ':' + proxy.auth.password, 'utf8').toString('base64'); + options.headers['Proxy-Authorization'] = 'Basic ' + base64; + } } - }); - - var axiosKeys = valueFromConfig2Keys - .concat(mergeDeepPropertiesKeys) - .concat(defaultToConfig2Keys); - - var otherKeys = Object - .keys(config2) - .filter(function filterAxiosKeys(key) { - return axiosKeys.indexOf(key) === -1; - }); - utils.forEach(otherKeys, function otherKeysDefaultToConfig2(prop) { - if (typeof config2[prop] !== 'undefined') { - config[prop] = config2[prop]; - } else if (typeof config1[prop] !== 'undefined') { - config[prop] = config1[prop]; + var transport; + var isHttpsProxy = isHttpsRequest && (proxy ? isHttps.test(proxy.protocol) : true); + if (config.transport) { + transport = config.transport; + } else if (config.maxRedirects === 0) { + transport = isHttpsProxy ? https : http; + } else { + if (config.maxRedirects) { + options.maxRedirects = config.maxRedirects; + } + transport = isHttpsProxy ? httpsFollow : httpFollow; } - }); - - return config; -}; + if (config.maxContentLength && config.maxContentLength > -1) { + options.maxBodyLength = config.maxContentLength; + } -/***/ }), -/* 489 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; + // Create the request + var req = transport.request(options, function handleResponse(res) { + if (req.aborted) return; + // uncompress the response body transparently if required + var stream = res; + switch (res.headers['content-encoding']) { + /*eslint default-case:0*/ + case 'gzip': + case 'compress': + case 'deflate': + // add the unzipper to the body stream processing pipeline + stream = (res.statusCode === 204) ? stream : stream.pipe(zlib.createUnzip()); -/** - * A `Cancel` is an object that is thrown when an operation is canceled. - * - * @class - * @param {string=} message The message. - */ -function Cancel(message) { - this.message = message; -} + // remove the content-encoding in order to not confuse downstream operations + delete res.headers['content-encoding']; + break; + } -Cancel.prototype.toString = function toString() { - return 'Cancel' + (this.message ? ': ' + this.message : ''); -}; + // return the last request in case of redirects + var lastRequest = res.req || req; -Cancel.prototype.__CANCEL__ = true; + var response = { + status: res.statusCode, + statusText: res.statusMessage, + headers: res.headers, + config: config, + request: lastRequest + }; -module.exports = Cancel; + if (config.responseType === 'stream') { + response.data = stream; + settle(resolve, reject, response); + } else { + var responseBuffer = []; + stream.on('data', function handleStreamData(chunk) { + responseBuffer.push(chunk); + // make sure the content length is not over the maxContentLength if specified + if (config.maxContentLength > -1 && Buffer.concat(responseBuffer).length > config.maxContentLength) { + stream.destroy(); + reject(createError('maxContentLength size of ' + config.maxContentLength + ' exceeded', + config, null, lastRequest)); + } + }); -/***/ }), -/* 490 */ -/***/ (function(module, exports, __webpack_require__) { + stream.on('error', function handleStreamError(err) { + if (req.aborted) return; + reject(enhanceError(err, config, null, lastRequest)); + }); -"use strict"; + stream.on('end', function handleStreamEnd() { + var responseData = Buffer.concat(responseBuffer); + if (config.responseType !== 'arraybuffer') { + responseData = responseData.toString(config.responseEncoding); + } + response.data = responseData; + settle(resolve, reject, response); + }); + } + }); -var Cancel = __webpack_require__(489); + // Handle errors + req.on('error', function handleRequestError(err) { + if (req.aborted) return; + reject(enhanceError(err, config, null, req)); + }); -/** - * A `CancelToken` is an object that can be used to request cancellation of an operation. - * - * @class - * @param {Function} executor The executor function. - */ -function CancelToken(executor) { - if (typeof executor !== 'function') { - throw new TypeError('executor must be a function.'); - } + // Handle request timeout + if (config.timeout) { + // Sometime, the response will be very slow, and does not respond, the connect event will be block by event loop system. + // And timer callback will be fired, and abort() will be invoked before connection, then get "socket hang up" and code ECONNRESET. + // At this time, if we have a large number of request, nodejs will hang up some socket on background. and the number will up and up. + // And then these socket which be hang up will devoring CPU little by little. + // ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect. + req.setTimeout(config.timeout, function handleRequestTimeout() { + req.abort(); + reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED', req)); + }); + } - var resolvePromise; - this.promise = new Promise(function promiseExecutor(resolve) { - resolvePromise = resolve; - }); + if (config.cancelToken) { + // Handle cancellation + config.cancelToken.promise.then(function onCanceled(cancel) { + if (req.aborted) return; - var token = this; - executor(function cancel(message) { - if (token.reason) { - // Cancellation has already been requested - return; + req.abort(); + reject(cancel); + }); } - token.reason = new Cancel(message); - resolvePromise(token.reason); + // Send the request + if (utils.isStream(data)) { + data.on('error', function handleStreamError(err) { + reject(enhanceError(err, config, null, req)); + }).pipe(req); + } else { + req.end(data); + } }); -} - -/** - * Throws a `Cancel` if cancellation has been requested. - */ -CancelToken.prototype.throwIfRequested = function throwIfRequested() { - if (this.reason) { - throw this.reason; - } }; -/** - * Returns an object that contains a new `CancelToken` and a function that, when called, - * cancels the `CancelToken`. - */ -CancelToken.source = function source() { - var cancel; - var token = new CancelToken(function executor(c) { - cancel = c; - }); - return { - token: token, - cancel: cancel - }; -}; -module.exports = CancelToken; +/***/ }), +/* 463 */ +/***/ (function(module, exports) { +module.exports = require("http"); /***/ }), -/* 491 */ +/* 464 */ +/***/ (function(module, exports) { + +module.exports = require("https"); + +/***/ }), +/* 465 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var url = __webpack_require__(439); +var http = __webpack_require__(463); +var https = __webpack_require__(464); +var assert = __webpack_require__(371); +var Writable = __webpack_require__(382).Writable; +var debug = __webpack_require__(466)("follow-redirects"); +// RFC7231§4.2.1: Of the request methods defined by this specification, +// the GET, HEAD, OPTIONS, and TRACE methods are defined to be safe. +var SAFE_METHODS = { GET: true, HEAD: true, OPTIONS: true, TRACE: true }; -/** - * Syntactic sugar for invoking a function and expanding an array for arguments. - * - * Common use case would be to use `Function.prototype.apply`. - * - * ```js - * function f(x, y, z) {} - * var args = [1, 2, 3]; - * f.apply(null, args); - * ``` - * - * With `spread` this example can be re-written. - * - * ```js - * spread(function(x, y, z) {})([1, 2, 3]); - * ``` - * - * @param {Function} callback - * @returns {Function} - */ -module.exports = function spread(callback) { - return function wrap(arr) { - return callback.apply(null, arr); +// Create handlers that pass events from native requests +var eventHandlers = Object.create(null); +["abort", "aborted", "error", "socket", "timeout"].forEach(function (event) { + eventHandlers[event] = function (arg) { + this._redirectable.emit(event, arg); }; -}; +}); +// An HTTP(S) request that can be redirected +function RedirectableRequest(options, responseCallback) { + // Initialize the request + Writable.call(this); + options.headers = options.headers || {}; + this._options = options; + this._redirectCount = 0; + this._redirects = []; + this._requestBodyLength = 0; + this._requestBodyBuffers = []; -/***/ }), -/* 492 */ -/***/ (function(module, exports, __webpack_require__) { + // Since http.request treats host as an alias of hostname, + // but the url module interprets host as hostname plus port, + // eliminate the host property to avoid confusion. + if (options.host) { + // Use hostname if set, because it has precedence + if (!options.hostname) { + options.hostname = options.host; + } + delete options.host; + } -"use strict"; + // Attach a callback if passed + if (responseCallback) { + this.on("response", responseCallback); + } -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const tslib_1 = __webpack_require__(36); -tslib_1.__exportStar(__webpack_require__(493), exports); + // React to responses of native requests + var self = this; + this._onNativeResponse = function (response) { + self._processResponse(response); + }; + // Complete the URL object when necessary + if (!options.pathname && options.path) { + var searchPos = options.path.indexOf("?"); + if (searchPos < 0) { + options.pathname = options.path; + } + else { + options.pathname = options.path.substring(0, searchPos); + options.search = options.path.substring(searchPos); + } + } -/***/ }), -/* 493 */ -/***/ (function(module, exports, __webpack_require__) { + // Perform the first request + this._performRequest(); +} +RedirectableRequest.prototype = Object.create(Writable.prototype); -"use strict"; +// Writes buffered data to the current native request +RedirectableRequest.prototype.write = function (data, encoding, callback) { + // Validate input and shift parameters if necessary + if (!(typeof data === "string" || typeof data === "object" && ("length" in data))) { + throw new Error("data should be a string, Buffer or Uint8Array"); + } + if (typeof encoding === "function") { + callback = encoding; + encoding = null; + } -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -exports.isAxiosRequestError = (error) => { - return error && error.config && error.response === undefined; -}; -exports.isAxiosResponseError = (error) => { - return error && error.response && error.response.status !== undefined; + // Ignore empty buffers, since writing them doesn't invoke the callback + // https://github.com/nodejs/node/issues/22066 + if (data.length === 0) { + if (callback) { + callback(); + } + return; + } + // Only write when we don't exceed the maximum body length + if (this._requestBodyLength + data.length <= this._options.maxBodyLength) { + this._requestBodyLength += data.length; + this._requestBodyBuffers.push({ data: data, encoding: encoding }); + this._currentRequest.write(data, encoding, callback); + } + // Error when we exceed the maximum body length + else { + this.emit("error", new Error("Request body larger than maxBodyLength limit")); + this.abort(); + } }; +// Ends the current native request +RedirectableRequest.prototype.end = function (data, encoding, callback) { + // Shift parameters if necessary + if (typeof data === "function") { + callback = data; + data = encoding = null; + } + else if (typeof encoding === "function") { + callback = encoding; + encoding = null; + } -/***/ }), -/* 494 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; + // Write data and end + var currentRequest = this._currentRequest; + this.write(data || "", encoding, function () { + currentRequest.end(null, null, callback); + }); +}; -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -class KbnClientStatus { - constructor(requester) { - this.requester = requester; - } - /** - * Get the full server status - */ - async get() { - return await this.requester.request({ - method: 'GET', - path: 'api/status', - }); - } - /** - * Get the overall/merged state - */ - async getOverallState() { - const status = await this.get(); - return status.status.overall.state; - } -} -exports.KbnClientStatus = KbnClientStatus; +// Sets a header value on the current native request +RedirectableRequest.prototype.setHeader = function (name, value) { + this._options.headers[name] = value; + this._currentRequest.setHeader(name, value); +}; +// Clears a header value on the current native request +RedirectableRequest.prototype.removeHeader = function (name) { + delete this._options.headers[name]; + this._currentRequest.removeHeader(name); +}; -/***/ }), -/* 495 */ -/***/ (function(module, exports, __webpack_require__) { +// Proxy all other public ClientRequest methods +[ + "abort", "flushHeaders", "getHeader", + "setNoDelay", "setSocketKeepAlive", "setTimeout", +].forEach(function (method) { + RedirectableRequest.prototype[method] = function (a, b) { + return this._currentRequest[method](a, b); + }; +}); -"use strict"; +// Proxy all public ClientRequest properties +["aborted", "connection", "socket"].forEach(function (property) { + Object.defineProperty(RedirectableRequest.prototype, property, { + get: function () { return this._currentRequest[property]; }, + }); +}); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const PLUGIN_STATUS_ID = /^plugin:(.+?)@/; -class KbnClientPlugins { - constructor(status) { - this.status = status; - } - /** - * Get a list of plugin ids that are enabled on the server - */ - async getEnabledIds() { - const pluginIds = []; - const apiResp = await this.status.get(); - for (const status of apiResp.status.statuses) { - if (status.id) { - const match = status.id.match(PLUGIN_STATUS_ID); - if (match) { - pluginIds.push(match[1]); - } - } - } - return pluginIds; +// Executes the next native request (initial or redirect) +RedirectableRequest.prototype._performRequest = function () { + // Load the native protocol + var protocol = this._options.protocol; + var nativeProtocol = this._options.nativeProtocols[protocol]; + if (!nativeProtocol) { + this.emit("error", new Error("Unsupported protocol " + protocol)); + return; + } + + // If specified, use the agent corresponding to the protocol + // (HTTP and HTTPS use different types of agents) + if (this._options.agents) { + var scheme = protocol.substr(0, protocol.length - 1); + this._options.agent = this._options.agents[scheme]; + } + + // Create the native request + var request = this._currentRequest = + nativeProtocol.request(this._options, this._onNativeResponse); + this._currentUrl = url.format(this._options); + + // Set up event handlers + request._redirectable = this; + for (var event in eventHandlers) { + /* istanbul ignore else */ + if (event) { + request.on(event, eventHandlers[event]); } -} -exports.KbnClientPlugins = KbnClientPlugins; + } + // End a redirected request + // (The first request must be ended explicitly with RedirectableRequest#end) + if (this._isRedirect) { + // Write the request entity and end. + var i = 0; + var buffers = this._requestBodyBuffers; + (function writeNext() { + if (i < buffers.length) { + var buffer = buffers[i++]; + request.write(buffer.data, buffer.encoding, writeNext); + } + else { + request.end(); + } + }()); + } +}; -/***/ }), -/* 496 */ -/***/ (function(module, exports, __webpack_require__) { +// Processes a response from the current native request +RedirectableRequest.prototype._processResponse = function (response) { + // Store the redirected response + if (this._options.trackRedirects) { + this._redirects.push({ + url: this._currentUrl, + headers: response.headers, + statusCode: response.statusCode, + }); + } -"use strict"; + // RFC7231§6.4: The 3xx (Redirection) class of status code indicates + // that further action needs to be taken by the user agent in order to + // fulfill the request. If a Location header field is provided, + // the user agent MAY automatically redirect its request to the URI + // referenced by the Location field value, + // even if the specific status code is not understood. + var location = response.headers.location; + if (location && this._options.followRedirects !== false && + response.statusCode >= 300 && response.statusCode < 400) { + // RFC7231§6.4: A client SHOULD detect and intervene + // in cyclical redirections (i.e., "infinite" redirection loops). + if (++this._redirectCount > this._options.maxRedirects) { + this.emit("error", new Error("Max redirects exceeded.")); + return; + } -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -class KbnClientVersion { - constructor(status) { - this.status = status; + // RFC7231§6.4: Automatic redirection needs to done with + // care for methods not known to be safe […], + // since the user might not wish to redirect an unsafe request. + // RFC7231§6.4.7: The 307 (Temporary Redirect) status code indicates + // that the target resource resides temporarily under a different URI + // and the user agent MUST NOT change the request method + // if it performs an automatic redirection to that URI. + var header; + var headers = this._options.headers; + if (response.statusCode !== 307 && !(this._options.method in SAFE_METHODS)) { + this._options.method = "GET"; + // Drop a possible entity and headers related to it + this._requestBodyBuffers = []; + for (header in headers) { + if (/^content-/i.test(header)) { + delete headers[header]; + } + } } - async get() { - if (this.versionCache !== undefined) { - return this.versionCache; + + // Drop the Host header, as the redirect might lead to a different host + if (!this._isRedirect) { + for (header in headers) { + if (/^host$/i.test(header)) { + delete headers[header]; } - const status = await this.status.get(); - this.versionCache = status.version.number + (status.version.build_snapshot ? '-SNAPSHOT' : ''); - return this.versionCache; + } } -} -exports.KbnClientVersion = KbnClientVersion; + // Perform the redirected request + var redirectUrl = url.resolve(this._currentUrl, location); + debug("redirecting to", redirectUrl); + Object.assign(this._options, url.parse(redirectUrl)); + this._isRedirect = true; + this._performRequest(); -/***/ }), -/* 497 */ -/***/ (function(module, exports, __webpack_require__) { + // Discard the remainder of the response to avoid waiting for data + response.destroy(); + } + else { + // The response is not a redirect; return it as-is + response.responseUrl = this._currentUrl; + response.redirects = this._redirects; + this.emit("response", response); -"use strict"; + // Clean up + this._requestBodyBuffers = []; + } +}; -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -Object.defineProperty(exports, "__esModule", { value: true }); -const kbn_client_requester_1 = __webpack_require__(451); -class KbnClientSavedObjects { - constructor(log, requester) { - this.log = log; - this.requester = requester; - } - /** - * Run the saved objects migration - */ - async migrate() { - this.log.debug('Migrating saved objects'); - return await this.requester.request({ - description: 'migrate saved objects', - path: kbn_client_requester_1.uriencode `/internal/saved_objects/_migrate`, - method: 'POST', - body: {}, - }); - } - /** - * Get an object - */ - async get(options) { - this.log.debug('Gettings saved object: %j', options); - return await this.requester.request({ - description: 'get saved object', - path: kbn_client_requester_1.uriencode `/api/saved_objects/${options.type}/${options.id}`, - method: 'GET', - }); - } - /** - * Create a saved object - */ - async create(options) { - this.log.debug('Creating saved object: %j', options); - return await this.requester.request({ - description: 'update saved object', - path: options.id - ? kbn_client_requester_1.uriencode `/api/saved_objects/${options.type}/${options.id}` - : kbn_client_requester_1.uriencode `/api/saved_objects/${options.type}`, - query: { - overwrite: options.overwrite, - }, - method: 'POST', - body: { - attributes: options.attributes, - migrationVersion: options.migrationVersion, - references: options.references, - }, - }); - } - /** - * Update a saved object - */ - async update(options) { - this.log.debug('Updating saved object: %j', options); - return await this.requester.request({ - description: 'update saved object', - path: kbn_client_requester_1.uriencode `/api/saved_objects/${options.type}/${options.id}`, - query: { - overwrite: options.overwrite, - }, - method: 'PUT', - body: { - attributes: options.attributes, - migrationVersion: options.migrationVersion, - references: options.references, - }, - }); - } - /** - * Delete an object - */ - async delete(options) { - this.log.debug('Deleting saved object %s/%s', options); - return await this.requester.request({ - description: 'delete saved object', - path: kbn_client_requester_1.uriencode `/api/saved_objects/${options.type}/${options.id}`, - method: 'DELETE', - }); - } +// Wraps the key/value object of protocols with redirect functionality +function wrap(protocols) { + // Default settings + var exports = { + maxRedirects: 21, + maxBodyLength: 10 * 1024 * 1024, + }; + + // Wrap each protocol + var nativeProtocols = {}; + Object.keys(protocols).forEach(function (scheme) { + var protocol = scheme + ":"; + var nativeProtocol = nativeProtocols[protocol] = protocols[scheme]; + var wrappedProtocol = exports[scheme] = Object.create(nativeProtocol); + + // Executes a request, following redirects + wrappedProtocol.request = function (options, callback) { + if (typeof options === "string") { + options = url.parse(options); + options.maxRedirects = exports.maxRedirects; + } + else { + options = Object.assign({ + protocol: protocol, + maxRedirects: exports.maxRedirects, + maxBodyLength: exports.maxBodyLength, + }, options); + } + options.nativeProtocols = nativeProtocols; + assert.equal(options.protocol, protocol, "protocol mismatch"); + debug("options", options); + return new RedirectableRequest(options, callback); + }; + + // Executes a GET request, following redirects + wrappedProtocol.get = function (options, callback) { + var request = wrappedProtocol.request(options, callback); + request.end(); + return request; + }; + }); + return exports; } -exports.KbnClientSavedObjects = KbnClientSavedObjects; + +// Exports +module.exports = wrap({ http: http, https: https }); +module.exports.wrap = wrap; /***/ }), -/* 498 */ +/* 466 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. +/** + * Detect Electron renderer process, which is node, but we should + * treat as a browser. */ -Object.defineProperty(exports, "__esModule", { value: true }); -const kbn_client_requester_1 = __webpack_require__(451); -class KbnClientUiSettings { - constructor(log, requester, defaults) { - this.log = log; - this.requester = requester; - this.defaults = defaults; - } - async get(setting) { - var _a; - const all = await this.getAll(); - const value = (_a = all[setting]) === null || _a === void 0 ? void 0 : _a.userValue; - this.log.verbose('uiSettings.value: %j', value); - return value; - } - /** - * Gets defaultIndex from the config doc. - */ - async getDefaultIndex() { - return await this.get('defaultIndex'); - } - /** - * Unset a uiSetting - */ - async unset(setting) { - return await this.requester.request({ - path: kbn_client_requester_1.uriencode `/api/kibana/settings/${setting}`, - method: 'DELETE', - }); - } - /** - * Replace all uiSettings with the `doc` values, `doc` is merged - * with some defaults - */ - async replace(doc, { retries = 5 } = {}) { - this.log.debug('replacing kibana config doc: %j', doc); - const changes = { - ...this.defaults, - ...doc, - }; - for (const [name, { isOverridden }] of Object.entries(await this.getAll())) { - if (!isOverridden && !changes.hasOwnProperty(name)) { - changes[name] = null; - } - } - await this.requester.request({ - method: 'POST', - path: '/api/kibana/settings', - body: { changes }, - retries, - }); - } - /** - * Add fields to the config doc (like setting timezone and defaultIndex) - */ - async update(updates) { - this.log.debug('applying update to kibana config: %j', updates); - await this.requester.request({ - path: '/api/kibana/settings', - method: 'POST', - body: { - changes: updates, - }, - }); - } - async getAll() { - const resp = await this.requester.request({ - path: '/api/kibana/settings', - method: 'GET', - }); - return resp.settings; - } + +if (typeof process === 'undefined' || process.type === 'renderer') { + module.exports = __webpack_require__(467); +} else { + module.exports = __webpack_require__(470); } -exports.KbnClientUiSettings = KbnClientUiSettings; /***/ }), -/* 499 */ +/* 467 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/** + * This is the web browser implementation of `debug()`. * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Expose `debug()` as the module. */ -Object.defineProperty(exports, "__esModule", { value: true }); -const tslib_1 = __webpack_require__(36); -tslib_1.__exportStar(__webpack_require__(500), exports); +exports = module.exports = __webpack_require__(468); +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.storage = 'undefined' != typeof chrome + && 'undefined' != typeof chrome.storage + ? chrome.storage.local + : localstorage(); -/***/ }), -/* 500 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Colors. + */ -"use strict"; +exports.colors = [ + '#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', + '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', + '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', + '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', + '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', + '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', + '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', + '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', + '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', + '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', + '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33' +]; -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/** + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * TODO: add a `localStorage` variable to explicitly enable/disable colors */ -Object.defineProperty(exports, "__esModule", { value: true }); -const tslib_1 = __webpack_require__(36); -const util_1 = __webpack_require__(29); -const axios_1 = tslib_1.__importDefault(__webpack_require__(453)); -function parseConfig(log) { - const configJson = process.env.KIBANA_CI_STATS_CONFIG; - if (!configJson) { - log.debug('KIBANA_CI_STATS_CONFIG environment variable not found, disabling CiStatsReporter'); - return; - } - let config; - try { - config = JSON.parse(configJson); - } - catch (_) { - // handled below - } - if (typeof config === 'object' && config !== null) { - return validateConfig(log, config); - } - log.warning('KIBANA_CI_STATS_CONFIG is invalid, stats will not be reported'); - return; -} -function validateConfig(log, config) { - const validApiUrl = typeof config.apiUrl === 'string' && config.apiUrl.length !== 0; - if (!validApiUrl) { - log.warning('KIBANA_CI_STATS_CONFIG is missing a valid api url, stats will not be reported'); - return; - } - const validApiToken = typeof config.apiToken === 'string' && config.apiToken.length !== 0; - if (!validApiToken) { - log.warning('KIBANA_CI_STATS_CONFIG is missing a valid api token, stats will not be reported'); - return; - } - const validId = typeof config.buildId === 'string' && config.buildId.length !== 0; - if (!validId) { - log.warning('KIBANA_CI_STATS_CONFIG is missing a valid build id, stats will not be reported'); - return; - } - return config; -} -class CiStatsReporter { - constructor(config, log) { - this.config = config; - this.log = log; - } - static fromEnv(log) { - return new CiStatsReporter(parseConfig(log), log); - } - isEnabled() { - return !!this.config; - } - async metrics(metrics) { - var _a, _b, _c, _d; - if (!this.config) { - return; - } - let attempt = 0; - const maxAttempts = 5; - const bodySummary = metrics - .map(({ group, id, value }) => `[${group}/${id}=${value}]`) - .join(' '); - while (true) { - attempt += 1; - try { - await axios_1.default.request({ - method: 'POST', - url: '/v1/metrics', - baseURL: this.config.apiUrl, - headers: { - Authorization: `token ${this.config.apiToken}`, - }, - data: { - buildId: this.config.buildId, - metrics, - }, - }); - return; - } - catch (error) { - if (!((_a = error) === null || _a === void 0 ? void 0 : _a.request)) { - // not an axios error, must be a usage error that we should notify user about - throw error; - } - if (((_b = error) === null || _b === void 0 ? void 0 : _b.response) && error.response.status !== 502) { - // error response from service was received so warn the user and move on - this.log.warning(`error recording metric [status=${error.response.status}] [resp=${util_1.inspect(error.response.data)}] ${bodySummary}`); - return; - } - if (attempt === maxAttempts) { - this.log.warning(`failed to reach kibana-ci-stats service too many times, unable to record metric ${bodySummary}`); - return; - } - // we failed to reach the backend and we have remaining attempts, lets retry after a short delay - const reason = ((_d = (_c = error) === null || _c === void 0 ? void 0 : _c.response) === null || _d === void 0 ? void 0 : _d.status) ? `${error.response.status} response` - : 'no response'; - this.log.warning(`failed to reach kibana-ci-stats service [reason=${reason}], retrying in ${attempt} seconds`); - await new Promise((resolve) => setTimeout(resolve, attempt * 1000)); - } - } - } + +function useColors() { + // NB: In an Electron preload script, document will be defined but not fully + // initialized. Since we know we're in Chrome, we'll just detect this case + // explicitly + if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') { + return true; + } + + // Internet Explorer and Edge do not support colors. + if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } + + // is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || + // is firebug? http://stackoverflow.com/a/398120/376773 + (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || + // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || + // double check webkit in userAgent just in case we are in a worker + (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); } -exports.CiStatsReporter = CiStatsReporter; +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ -/***/ }), -/* 501 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +exports.formatters.j = function(v) { + try { + return JSON.stringify(v); + } catch (err) { + return '[UnexpectedJSONParseError]: ' + err.message; + } +}; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parallelizeBatches", function() { return parallelizeBatches; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parallelize", function() { return parallelize; }); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 + +/** + * Colorize log arguments if enabled. * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * @api public */ -async function parallelizeBatches(batches, fn) { - for (const batch of batches) { - // We need to make sure the entire batch has completed before we can move on - // to the next batch - await parallelize(batch, fn); - } -} -async function parallelize(items, fn, concurrency = 4) { - if (items.length === 0) { - return; - } - return new Promise((resolve, reject) => { - let activePromises = 0; - const values = items.slice(0); +function formatArgs(args) { + var useColors = this.useColors; - async function scheduleItem(item) { - activePromises++; + args[0] = (useColors ? '%c' : '') + + this.namespace + + (useColors ? ' %c' : ' ') + + args[0] + + (useColors ? '%c ' : ' ') + + '+' + exports.humanize(this.diff); - try { - await fn(item); - activePromises--; + if (!useColors) return; - if (values.length > 0) { - // We have more work to do, so we schedule the next promise - scheduleItem(values.shift()); - } else if (activePromises === 0) { - // We have no more values left, and all items have completed, so we've - // completed all the work. - resolve(); - } - } catch (error) { - reject(error); - } - } + var c = 'color: ' + this.color; + args.splice(1, 0, c, 'color: inherit') - values.splice(0, concurrency).map(scheduleItem); + // the final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + var index = 0; + var lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, function(match) { + if ('%%' === match) return; + index++; + if ('%c' === match) { + // we only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } }); -} -/***/ }), -/* 502 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + args.splice(lastC, 0, c); +} -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getProjects", function() { return getProjects; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buildProjectGraph", function() { return buildProjectGraph; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "topologicallyBatchProjects", function() { return topologicallyBatchProjects; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "includeTransitiveProjects", function() { return includeTransitiveProjects; }); -/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(503); -/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(glob__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(29); -/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(516); -/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(517); -/* harmony import */ var _workspaces__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(578); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at +/** + * Invokes `console.log()` when available. + * No-op when `console.log` is not a "function". * - * http://www.apache.org/licenses/LICENSE-2.0 + * @api public + */ + +function log() { + // this hackery is required for IE8/9, where + // the `console.log` function doesn't have 'apply' + return 'object' === typeof console + && console.log + && Function.prototype.apply.call(console.log, console, arguments); +} + +/** + * Save `namespaces`. * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * @param {String} namespaces + * @api private */ +function save(namespaces) { + try { + if (null == namespaces) { + exports.storage.removeItem('debug'); + } else { + exports.storage.debug = namespaces; + } + } catch(e) {} +} +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ +function load() { + var r; + try { + r = exports.storage.debug; + } catch(e) {} + // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + if (!r && typeof process !== 'undefined' && 'env' in process) { + r = process.env.DEBUG; + } + return r; +} -const glob = Object(util__WEBPACK_IMPORTED_MODULE_2__["promisify"])(glob__WEBPACK_IMPORTED_MODULE_0___default.a); -/** a Map of project names to Project instances */ +/** + * Enable namespaces listed in `localStorage.debug` initially. + */ -async function getProjects(rootPath, projectsPathsPatterns, { - include = [], - exclude = [] -} = {}) { - const projects = new Map(); - const workspaceProjectsPaths = await Object(_workspaces__WEBPACK_IMPORTED_MODULE_5__["workspacePackagePaths"])(rootPath); +exports.enable(load()); - for (const pattern of projectsPathsPatterns) { - const pathsToProcess = await packagesFromGlobPattern({ - pattern, - rootPath - }); +/** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ - for (const filePath of pathsToProcess) { - const projectConfigPath = normalize(filePath); - const projectDir = path__WEBPACK_IMPORTED_MODULE_1___default.a.dirname(projectConfigPath); - const project = await _project__WEBPACK_IMPORTED_MODULE_4__["Project"].fromPath(projectDir); +function localstorage() { + try { + return window.localStorage; + } catch (e) {} +} - if (workspaceProjectsPaths.indexOf(filePath) >= 0) { - project.isWorkspaceProject = true; - } - const excludeProject = exclude.includes(project.name) || include.length > 0 && !include.includes(project.name); +/***/ }), +/* 468 */ +/***/ (function(module, exports, __webpack_require__) { - if (excludeProject) { - continue; - } - if (projects.has(project.name)) { - throw new _errors__WEBPACK_IMPORTED_MODULE_3__["CliError"](`There are multiple projects with the same name [${project.name}]`, { - name: project.name, - paths: [project.path, projects.get(project.name).path] - }); - } +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + * + * Expose `debug()` as the module. + */ - projects.set(project.name, project); - } - } +exports = module.exports = createDebug.debug = createDebug['default'] = createDebug; +exports.coerce = coerce; +exports.disable = disable; +exports.enable = enable; +exports.enabled = enabled; +exports.humanize = __webpack_require__(469); - return projects; -} +/** + * Active `debug` instances. + */ +exports.instances = []; -function packagesFromGlobPattern({ - pattern, - rootPath -}) { - const globOptions = { - cwd: rootPath, - // Should throw in case of unusual errors when reading the file system - strict: true, - // Always returns absolute paths for matched files - absolute: true, - // Do not match ** against multiple filenames - // (This is only specified because we currently don't have a need for it.) - noglobstar: true - }; - return glob(path__WEBPACK_IMPORTED_MODULE_1___default.a.join(pattern, 'package.json'), globOptions); -} // https://github.com/isaacs/node-glob/blob/master/common.js#L104 -// glob always returns "\\" as "/" in windows, so everyone -// gets normalized because we can't have nice things. +/** + * The currently active debug mode names, and names to skip. + */ +exports.names = []; +exports.skips = []; -function normalize(dir) { - return path__WEBPACK_IMPORTED_MODULE_1___default.a.normalize(dir); -} +/** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". + */ -function buildProjectGraph(projects) { - const projectGraph = new Map(); +exports.formatters = {}; - for (const project of projects.values()) { - const projectDeps = []; - const dependencies = project.allDependencies; +/** + * Select a color. + * @param {String} namespace + * @return {Number} + * @api private + */ - for (const depName of Object.keys(dependencies)) { - if (projects.has(depName)) { - const dep = projects.get(depName); - const dependentProjectIsInWorkspace = project.isWorkspaceProject || project.json.name === 'kibana'; - project.ensureValidProjectDependency(dep, dependentProjectIsInWorkspace); - projectDeps.push(dep); - } - } +function selectColor(namespace) { + var hash = 0, i; - projectGraph.set(project.name, projectDeps); + for (i in namespace) { + hash = ((hash << 5) - hash) + namespace.charCodeAt(i); + hash |= 0; // Convert to 32bit integer } - return projectGraph; + return exports.colors[Math.abs(hash) % exports.colors.length]; } -function topologicallyBatchProjects(projectsToBatch, projectGraph, { - batchByWorkspace = false -} = {}) { - // We're going to be chopping stuff out of this list, so copy it. - const projectsLeftToBatch = new Set(projectsToBatch.keys()); - const batches = []; - if (batchByWorkspace) { - const workspaceRootProject = Array.from(projectsToBatch.values()).find(p => p.isWorkspaceRoot); +/** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ - if (!workspaceRootProject) { - throw new _errors__WEBPACK_IMPORTED_MODULE_3__["CliError"](`There was no yarn workspace root found.`); - } // Push in the workspace root first. +function createDebug(namespace) { + var prevTime; - batches.push([workspaceRootProject]); - projectsLeftToBatch.delete(workspaceRootProject.name); // In the next batch, push in all workspace projects. + function debug() { + // disabled? + if (!debug.enabled) return; - const workspaceBatch = []; + var self = debug; - for (const projectName of projectsLeftToBatch) { - const project = projectsToBatch.get(projectName); + // set `diff` timestamp + var curr = +new Date(); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; - if (project.isWorkspaceProject) { - workspaceBatch.push(project); - projectsLeftToBatch.delete(projectName); - } + // turn the `arguments` into a proper Array + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; } - batches.push(workspaceBatch); - } + args[0] = exports.coerce(args[0]); - while (projectsLeftToBatch.size > 0) { - // Get all projects that have no remaining dependencies within the repo - // that haven't yet been picked. - const batch = []; + if ('string' !== typeof args[0]) { + // anything else let's inspect with %O + args.unshift('%O'); + } - for (const projectName of projectsLeftToBatch) { - const projectDeps = projectGraph.get(projectName); - const needsDependenciesBatched = projectDeps.some(dep => projectsLeftToBatch.has(dep.name)); + // apply any `formatters` transformations + var index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { + // if we encounter an escaped % then don't increase the array index + if (match === '%%') return match; + index++; + var formatter = exports.formatters[format]; + if ('function' === typeof formatter) { + var val = args[index]; + match = formatter.call(self, val); - if (!needsDependenciesBatched) { - batch.push(projectsToBatch.get(projectName)); + // now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; } - } // If we weren't able to find a project with no remaining dependencies, - // then we've encountered a cycle in the dependency graph. + return match; + }); + // apply env-specific formatting (colors, etc.) + exports.formatArgs.call(self, args); - const hasCycles = batch.length === 0; + var logFn = debug.log || exports.log || console.log.bind(console); + logFn.apply(self, args); + } - if (hasCycles) { - const cycleProjectNames = [...projectsLeftToBatch]; - const message = 'Encountered a cycle in the dependency graph. Projects in cycle are:\n' + cycleProjectNames.join(', '); - throw new _errors__WEBPACK_IMPORTED_MODULE_3__["CliError"](message); - } + debug.namespace = namespace; + debug.enabled = exports.enabled(namespace); + debug.useColors = exports.useColors(); + debug.color = selectColor(namespace); + debug.destroy = destroy; - batches.push(batch); - batch.forEach(project => projectsLeftToBatch.delete(project.name)); + // env-specific initialization logic for debug instances + if ('function' === typeof exports.init) { + exports.init(debug); } - return batches; -} -function includeTransitiveProjects(subsetOfProjects, allProjects, { - onlyProductionDependencies = false -} = {}) { - const projectsWithDependents = new Map(); // the current list of packages we are expanding using breadth-first-search + exports.instances.push(debug); - const toProcess = [...subsetOfProjects]; + return debug; +} - while (toProcess.length > 0) { - const project = toProcess.shift(); - const dependencies = onlyProductionDependencies ? project.productionDependencies : project.allDependencies; - Object.keys(dependencies).forEach(dep => { - if (allProjects.has(dep)) { - toProcess.push(allProjects.get(dep)); - } - }); - projectsWithDependents.set(project.name, project); +function destroy () { + var index = exports.instances.indexOf(this); + if (index !== -1) { + exports.instances.splice(index, 1); + return true; + } else { + return false; } - - return projectsWithDependents; } -/***/ }), -/* 503 */ -/***/ (function(module, exports, __webpack_require__) { - -// Approach: -// -// 1. Get the minimatch set -// 2. For each pattern in the set, PROCESS(pattern, false) -// 3. Store matches per-set, then uniq them -// -// PROCESS(pattern, inGlobStar) -// Get the first [n] items from pattern that are all strings -// Join these together. This is PREFIX. -// If there is no more remaining, then stat(PREFIX) and -// add to matches if it succeeds. END. -// -// If inGlobStar and PREFIX is symlink and points to dir -// set ENTRIES = [] -// else readdir(PREFIX) as ENTRIES -// If fail, END -// -// with ENTRIES -// If pattern[n] is GLOBSTAR -// // handle the case where the globstar match is empty -// // by pruning it out, and testing the resulting pattern -// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) -// // handle other cases. -// for ENTRY in ENTRIES (not dotfiles) -// // attach globstar + tail onto the entry -// // Mark that this entry is a globstar match -// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) -// -// else // not globstar -// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) -// Test ENTRY against pattern[n] -// If fails, continue -// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) -// -// Caveat: -// Cache all stats and readdirs results to minimize syscall. Since all -// we ever care about is existence and directory-ness, we can just keep -// `true` for files, and [children,...] for directories, or `false` for -// things that don't exist. - -module.exports = glob +/** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ -var fs = __webpack_require__(23) -var rp = __webpack_require__(504) -var minimatch = __webpack_require__(506) -var Minimatch = minimatch.Minimatch -var inherits = __webpack_require__(510) -var EE = __webpack_require__(399).EventEmitter -var path = __webpack_require__(16) -var assert = __webpack_require__(30) -var isAbsolute = __webpack_require__(512) -var globSync = __webpack_require__(513) -var common = __webpack_require__(514) -var alphasort = common.alphasort -var alphasorti = common.alphasorti -var setopts = common.setopts -var ownProp = common.ownProp -var inflight = __webpack_require__(515) -var util = __webpack_require__(29) -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored +function enable(namespaces) { + exports.save(namespaces); -var once = __webpack_require__(404) + exports.names = []; + exports.skips = []; -function glob (pattern, options, cb) { - if (typeof options === 'function') cb = options, options = {} - if (!options) options = {} + var i; + var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); + var len = split.length; - if (options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return globSync(pattern, options) + for (i = 0; i < len; i++) { + if (!split[i]) continue; // ignore empty strings + namespaces = split[i].replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + exports.names.push(new RegExp('^' + namespaces + '$')); + } } - return new Glob(pattern, options, cb) + for (i = 0; i < exports.instances.length; i++) { + var instance = exports.instances[i]; + instance.enabled = exports.enabled(instance.namespace); + } } -glob.sync = globSync -var GlobSync = glob.GlobSync = globSync.GlobSync +/** + * Disable debug output. + * + * @api public + */ -// old api surface -glob.glob = glob +function disable() { + exports.enable(''); +} -function extend (origin, add) { - if (add === null || typeof add !== 'object') { - return origin - } +/** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ - var keys = Object.keys(add) - var i = keys.length - while (i--) { - origin[keys[i]] = add[keys[i]] +function enabled(name) { + if (name[name.length - 1] === '*') { + return true; } - return origin + var i, len; + for (i = 0, len = exports.skips.length; i < len; i++) { + if (exports.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports.names.length; i < len; i++) { + if (exports.names[i].test(name)) { + return true; + } + } + return false; } -glob.hasMagic = function (pattern, options_) { - var options = extend({}, options_) - options.noprocess = true +/** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ - var g = new Glob(pattern, options) - var set = g.minimatch.set +function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; +} - if (!pattern) - return false - if (set.length > 1) - return true +/***/ }), +/* 469 */ +/***/ (function(module, exports) { - for (var j = 0; j < set[0].length; j++) { - if (typeof set[0][j] !== 'string') - return true - } +/** + * Helpers. + */ - return false -} +var s = 1000; +var m = s * 60; +var h = m * 60; +var d = h * 24; +var y = d * 365.25; -glob.Glob = Glob -inherits(Glob, EE) -function Glob (pattern, options, cb) { - if (typeof options === 'function') { - cb = options - options = null - } +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} [options] + * @throws {Error} throw an error if val is not a non-empty string or a number + * @return {String|Number} + * @api public + */ - if (options && options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return new GlobSync(pattern, options) +module.exports = function(val, options) { + options = options || {}; + var type = typeof val; + if (type === 'string' && val.length > 0) { + return parse(val); + } else if (type === 'number' && isNaN(val) === false) { + return options.long ? fmtLong(val) : fmtShort(val); } + throw new Error( + 'val is not a non-empty string or a valid number. val=' + + JSON.stringify(val) + ); +}; - if (!(this instanceof Glob)) - return new Glob(pattern, options, cb) - - setopts(this, pattern, options) - this._didRealPath = false +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ - // process each pattern in the minimatch set - var n = this.minimatch.set.length +function parse(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s; + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n; + default: + return undefined; + } +} - // The matches are stored as {: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n) +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ - if (typeof cb === 'function') { - cb = once(cb) - this.on('error', cb) - this.on('end', function (matches) { - cb(null, matches) - }) +function fmtShort(ms) { + if (ms >= d) { + return Math.round(ms / d) + 'd'; } + if (ms >= h) { + return Math.round(ms / h) + 'h'; + } + if (ms >= m) { + return Math.round(ms / m) + 'm'; + } + if (ms >= s) { + return Math.round(ms / s) + 's'; + } + return ms + 'ms'; +} - var self = this - this._processing = 0 - - this._emitQueue = [] - this._processQueue = [] - this.paused = false +/** + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ - if (this.noprocess) - return this +function fmtLong(ms) { + return plural(ms, d, 'day') || + plural(ms, h, 'hour') || + plural(ms, m, 'minute') || + plural(ms, s, 'second') || + ms + ' ms'; +} - if (n === 0) - return done() +/** + * Pluralization helper. + */ - var sync = true - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false, done) +function plural(ms, n, name) { + if (ms < n) { + return; } - sync = false - - function done () { - --self._processing - if (self._processing <= 0) { - if (sync) { - process.nextTick(function () { - self._finish() - }) - } else { - self._finish() - } - } + if (ms < n * 1.5) { + return Math.floor(ms / n) + ' ' + name; } + return Math.ceil(ms / n) + ' ' + name + 's'; } -Glob.prototype._finish = function () { - assert(this instanceof Glob) - if (this.aborted) - return - if (this.realpath && !this._didRealpath) - return this._realpath() +/***/ }), +/* 470 */ +/***/ (function(module, exports, __webpack_require__) { - common.finish(this) - this.emit('end', this.found) -} +/** + * Module dependencies. + */ -Glob.prototype._realpath = function () { - if (this._didRealpath) - return +var tty = __webpack_require__(471); +var util = __webpack_require__(397); - this._didRealpath = true +/** + * This is the Node.js implementation of `debug()`. + * + * Expose `debug()` as the module. + */ - var n = this.matches.length - if (n === 0) - return this._finish() +exports = module.exports = __webpack_require__(468); +exports.init = init; +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; - var self = this - for (var i = 0; i < this.matches.length; i++) - this._realpathSet(i, next) +/** + * Colors. + */ - function next () { - if (--n === 0) - self._finish() +exports.colors = [ 6, 2, 3, 4, 5, 1 ]; + +try { + var supportsColor = __webpack_require__(472); + if (supportsColor && supportsColor.level >= 2) { + exports.colors = [ + 20, 21, 26, 27, 32, 33, 38, 39, 40, 41, 42, 43, 44, 45, 56, 57, 62, 63, 68, + 69, 74, 75, 76, 77, 78, 79, 80, 81, 92, 93, 98, 99, 112, 113, 128, 129, 134, + 135, 148, 149, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 178, 179, 184, 185, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 214, 215, 220, 221 + ]; } +} catch (err) { + // swallow - we only care if `supports-color` is available; it doesn't have to be. } -Glob.prototype._realpathSet = function (index, cb) { - var matchset = this.matches[index] - if (!matchset) - return cb() +/** + * Build up the default `inspectOpts` object from the environment variables. + * + * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js + */ - var found = Object.keys(matchset) - var self = this - var n = found.length +exports.inspectOpts = Object.keys(process.env).filter(function (key) { + return /^debug_/i.test(key); +}).reduce(function (obj, key) { + // camel-case + var prop = key + .substring(6) + .toLowerCase() + .replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() }); - if (n === 0) - return cb() + // coerce string value into JS value + var val = process.env[key]; + if (/^(yes|on|true|enabled)$/i.test(val)) val = true; + else if (/^(no|off|false|disabled)$/i.test(val)) val = false; + else if (val === 'null') val = null; + else val = Number(val); - var set = this.matches[index] = Object.create(null) - found.forEach(function (p, i) { - // If there's a problem with the stat, then it means that - // one or more of the links in the realpath couldn't be - // resolved. just return the abs value in that case. - p = self._makeAbs(p) - rp.realpath(p, self.realpathCache, function (er, real) { - if (!er) - set[real] = true - else if (er.syscall === 'stat') - set[p] = true - else - self.emit('error', er) // srsly wtf right here + obj[prop] = val; + return obj; +}, {}); - if (--n === 0) { - self.matches[index] = set - cb() - } - }) - }) +/** + * Is stdout a TTY? Colored output is enabled when `true`. + */ + +function useColors() { + return 'colors' in exports.inspectOpts + ? Boolean(exports.inspectOpts.colors) + : tty.isatty(process.stderr.fd); } -Glob.prototype._mark = function (p) { - return common.mark(this, p) -} +/** + * Map %o to `util.inspect()`, all on a single line. + */ -Glob.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} +exports.formatters.o = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts) + .split('\n').map(function(str) { + return str.trim() + }).join(' '); +}; -Glob.prototype.abort = function () { - this.aborted = true - this.emit('abort') -} +/** + * Map %o to `util.inspect()`, allowing multiple lines if needed. + */ -Glob.prototype.pause = function () { - if (!this.paused) { - this.paused = true - this.emit('pause') - } -} +exports.formatters.O = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); +}; -Glob.prototype.resume = function () { - if (this.paused) { - this.emit('resume') - this.paused = false - if (this._emitQueue.length) { - var eq = this._emitQueue.slice(0) - this._emitQueue.length = 0 - for (var i = 0; i < eq.length; i ++) { - var e = eq[i] - this._emitMatch(e[0], e[1]) - } - } - if (this._processQueue.length) { - var pq = this._processQueue.slice(0) - this._processQueue.length = 0 - for (var i = 0; i < pq.length; i ++) { - var p = pq[i] - this._processing-- - this._process(p[0], p[1], p[2], p[3]) - } - } - } -} +/** + * Adds ANSI color escape codes if enabled. + * + * @api public + */ -Glob.prototype._process = function (pattern, index, inGlobStar, cb) { - assert(this instanceof Glob) - assert(typeof cb === 'function') +function formatArgs(args) { + var name = this.namespace; + var useColors = this.useColors; - if (this.aborted) - return + if (useColors) { + var c = this.color; + var colorCode = '\u001b[3' + (c < 8 ? c : '8;5;' + c); + var prefix = ' ' + colorCode + ';1m' + name + ' ' + '\u001b[0m'; - this._processing++ - if (this.paused) { - this._processQueue.push([pattern, index, inGlobStar, cb]) - return + args[0] = prefix + args[0].split('\n').join('\n' + prefix); + args.push(colorCode + 'm+' + exports.humanize(this.diff) + '\u001b[0m'); + } else { + args[0] = getDate() + name + ' ' + args[0]; } +} - //console.error('PROCESS %d', this._processing, pattern) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ +function getDate() { + if (exports.inspectOpts.hideDate) { + return ''; + } else { + return new Date().toISOString() + ' '; } - // now n is the index of the first one that is *not* a string. +} - // see if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index, cb) - return +/** + * Invokes `util.format()` with the specified arguments and writes to stderr. + */ - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break +function log() { + return process.stderr.write(util.format.apply(util, arguments) + '\n'); +} - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ + +function save(namespaces) { + if (null == namespaces) { + // If you set a process.env field to null or undefined, it gets cast to the + // string 'null' or 'undefined'. Just delete instead. + delete process.env.DEBUG; + } else { + process.env.DEBUG = namespaces; } +} - var remain = pattern.slice(n) +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix +function load() { + return process.env.DEBUG; +} - var abs = this._makeAbs(read) +/** + * Init logic for `debug` instances. + * + * Create a new `inspectOpts` object in case `useColors` is set + * differently for a particular `debug` instance. + */ - //if ignored, skip _processing - if (childrenIgnored(this, read)) - return cb() +function init (debug) { + debug.inspectOpts = {}; - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) + var keys = Object.keys(exports.inspectOpts); + for (var i = 0; i < keys.length; i++) { + debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; + } } -Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} +/** + * Enable namespaces listed in `process.env.DEBUG` initially. + */ -Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { +exports.enable(load()); - // if the abs isn't a dir, then nothing can match! - if (!entries) - return cb() - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' +/***/ }), +/* 471 */ +/***/ (function(module, exports) { - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } +module.exports = require("tty"); - //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) +/***/ }), +/* 472 */ +/***/ (function(module, exports, __webpack_require__) { - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return cb() +"use strict"; - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. +const os = __webpack_require__(364); +const hasFlag = __webpack_require__(394); - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) +const env = process.env; - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } +let forceColor; +if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false')) { + forceColor = false; +} else if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + forceColor = true; +} +if ('FORCE_COLOR' in env) { + forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; +} - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return cb() - } +function translateLevel(level) { + if (level === 0) { + return false; + } - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - this._process([e].concat(remain), index, inGlobStar, cb) - } - cb() + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; } -Glob.prototype._emitMatch = function (index, e) { - if (this.aborted) - return +function supportsColor(stream) { + if (forceColor === false) { + return 0; + } - if (isIgnored(this, e)) - return + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } - if (this.paused) { - this._emitQueue.push([index, e]) - return - } + if (hasFlag('color=256')) { + return 2; + } - var abs = isAbsolute(e) ? e : this._makeAbs(e) + if (stream && !stream.isTTY && forceColor !== true) { + return 0; + } - if (this.mark) - e = this._mark(e) + const min = forceColor ? 1 : 0; - if (this.absolute) - e = abs + if (process.platform === 'win32') { + // Node.js 7.5.0 is the first version of Node.js to include a patch to + // libuv that enables 256 color output on Windows. Anything earlier and it + // won't work. However, here we target Node.js 8 at minimum as it is an LTS + // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows + // release that supports 256 colors. Windows 10 build 14931 is the first release + // that supports 16m/TrueColor. + const osRelease = os.release().split('.'); + if ( + Number(process.versions.node.split('.')[0]) >= 8 && + Number(osRelease[0]) >= 10 && + Number(osRelease[2]) >= 10586 + ) { + return Number(osRelease[2]) >= 14931 ? 3 : 2; + } - if (this.matches[index][e]) - return + return 1; + } - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } + if ('CI' in env) { + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } - this.matches[index][e] = true + return min; + } - var st = this.statCache[abs] - if (st) - this.emit('stat', e, st) + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } - this.emit('match', e) -} + if (env.COLORTERM === 'truecolor') { + return 3; + } -Glob.prototype._readdirInGlobStar = function (abs, cb) { - if (this.aborted) - return + if ('TERM_PROGRAM' in env) { + const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false, cb) + switch (env.TERM_PROGRAM) { + case 'iTerm.app': + return version >= 3 ? 3 : 2; + case 'Apple_Terminal': + return 2; + // No default + } + } - var lstatkey = 'lstat\0' + abs - var self = this - var lstatcb = inflight(lstatkey, lstatcb_) + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } - if (lstatcb) - fs.lstat(abs, lstatcb) + if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } - function lstatcb_ (er, lstat) { - if (er && er.code === 'ENOENT') - return cb() + if ('COLORTERM' in env) { + return 1; + } - var isSym = lstat && lstat.isSymbolicLink() - self.symlinks[abs] = isSym + if (env.TERM === 'dumb') { + return min; + } - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) { - self.cache[abs] = 'FILE' - cb() - } else - self._readdir(abs, false, cb) - } + return min; } -Glob.prototype._readdir = function (abs, inGlobStar, cb) { - if (this.aborted) - return - - cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) - if (!cb) - return +function getSupportLevel(stream) { + const level = supportsColor(stream); + return translateLevel(level); +} - //console.error('RD %j %j', +inGlobStar, abs) - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs, cb) +module.exports = { + supportsColor: getSupportLevel, + stdout: getSupportLevel(process.stdout), + stderr: getSupportLevel(process.stderr) +}; - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return cb() - if (Array.isArray(c)) - return cb(null, c) - } +/***/ }), +/* 473 */ +/***/ (function(module, exports) { - var self = this - fs.readdir(abs, readdirCb(this, abs, cb)) -} +module.exports = require("zlib"); -function readdirCb (self, abs, cb) { - return function (er, entries) { - if (er) - self._readdirError(abs, er, cb) - else - self._readdirEntries(abs, entries, cb) - } -} +/***/ }), +/* 474 */ +/***/ (function(module) { -Glob.prototype._readdirEntries = function (abs, entries, cb) { - if (this.aborted) - return +module.exports = JSON.parse("{\"name\":\"axios\",\"version\":\"0.19.2\",\"description\":\"Promise based HTTP client for the browser and node.js\",\"main\":\"index.js\",\"scripts\":{\"test\":\"grunt test && bundlesize\",\"start\":\"node ./sandbox/server.js\",\"build\":\"NODE_ENV=production grunt build\",\"preversion\":\"npm test\",\"version\":\"npm run build && grunt version && git add -A dist && git add CHANGELOG.md bower.json package.json\",\"postversion\":\"git push && git push --tags\",\"examples\":\"node ./examples/server.js\",\"coveralls\":\"cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js\",\"fix\":\"eslint --fix lib/**/*.js\"},\"repository\":{\"type\":\"git\",\"url\":\"https://github.com/axios/axios.git\"},\"keywords\":[\"xhr\",\"http\",\"ajax\",\"promise\",\"node\"],\"author\":\"Matt Zabriskie\",\"license\":\"MIT\",\"bugs\":{\"url\":\"https://github.com/axios/axios/issues\"},\"homepage\":\"https://github.com/axios/axios\",\"devDependencies\":{\"bundlesize\":\"^0.17.0\",\"coveralls\":\"^3.0.0\",\"es6-promise\":\"^4.2.4\",\"grunt\":\"^1.0.2\",\"grunt-banner\":\"^0.6.0\",\"grunt-cli\":\"^1.2.0\",\"grunt-contrib-clean\":\"^1.1.0\",\"grunt-contrib-watch\":\"^1.0.0\",\"grunt-eslint\":\"^20.1.0\",\"grunt-karma\":\"^2.0.0\",\"grunt-mocha-test\":\"^0.13.3\",\"grunt-ts\":\"^6.0.0-beta.19\",\"grunt-webpack\":\"^1.0.18\",\"istanbul-instrumenter-loader\":\"^1.0.0\",\"jasmine-core\":\"^2.4.1\",\"karma\":\"^1.3.0\",\"karma-chrome-launcher\":\"^2.2.0\",\"karma-coverage\":\"^1.1.1\",\"karma-firefox-launcher\":\"^1.1.0\",\"karma-jasmine\":\"^1.1.1\",\"karma-jasmine-ajax\":\"^0.1.13\",\"karma-opera-launcher\":\"^1.0.0\",\"karma-safari-launcher\":\"^1.0.0\",\"karma-sauce-launcher\":\"^1.2.0\",\"karma-sinon\":\"^1.0.5\",\"karma-sourcemap-loader\":\"^0.3.7\",\"karma-webpack\":\"^1.7.0\",\"load-grunt-tasks\":\"^3.5.2\",\"minimist\":\"^1.2.0\",\"mocha\":\"^5.2.0\",\"sinon\":\"^4.5.0\",\"typescript\":\"^2.8.1\",\"url-search-params\":\"^0.10.0\",\"webpack\":\"^1.13.1\",\"webpack-dev-server\":\"^1.14.1\"},\"browser\":{\"./lib/adapters/http.js\":\"./lib/adapters/xhr.js\"},\"typings\":\"./index.d.ts\",\"dependencies\":{\"follow-redirects\":\"1.5.10\"},\"bundlesize\":[{\"path\":\"./dist/axios.min.js\",\"threshold\":\"5kB\"}]}"); - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } +/***/ }), +/* 475 */ +/***/ (function(module, exports, __webpack_require__) { - this.cache[abs] = entries - return cb(null, entries) -} +"use strict"; -Glob.prototype._readdirError = function (f, er, cb) { - if (this.aborted) - return - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - this.emit('error', error) - this.abort() - } - break +var utils = __webpack_require__(442); - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break +/** + * Config-specific merge-function which creates a new config-object + * by merging two configuration objects together. + * + * @param {Object} config1 + * @param {Object} config2 + * @returns {Object} New object resulting from merging config2 to config1 + */ +module.exports = function mergeConfig(config1, config2) { + // eslint-disable-next-line no-param-reassign + config2 = config2 || {}; + var config = {}; - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) { - this.emit('error', er) - // If the error is handled, then we abort - // if not, we threw out of here - this.abort() - } - if (!this.silent) - console.error('glob error', er) - break - } - - return cb() -} - -Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} + var valueFromConfig2Keys = ['url', 'method', 'params', 'data']; + var mergeDeepPropertiesKeys = ['headers', 'auth', 'proxy']; + var defaultToConfig2Keys = [ + 'baseURL', 'url', 'transformRequest', 'transformResponse', 'paramsSerializer', + 'timeout', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName', + 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', + 'maxContentLength', 'validateStatus', 'maxRedirects', 'httpAgent', + 'httpsAgent', 'cancelToken', 'socketPath' + ]; + utils.forEach(valueFromConfig2Keys, function valueFromConfig2(prop) { + if (typeof config2[prop] !== 'undefined') { + config[prop] = config2[prop]; + } + }); -Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - //console.error('pgs2', prefix, remain[0], entries) + utils.forEach(mergeDeepPropertiesKeys, function mergeDeepProperties(prop) { + if (utils.isObject(config2[prop])) { + config[prop] = utils.deepMerge(config1[prop], config2[prop]); + } else if (typeof config2[prop] !== 'undefined') { + config[prop] = config2[prop]; + } else if (utils.isObject(config1[prop])) { + config[prop] = utils.deepMerge(config1[prop]); + } else if (typeof config1[prop] !== 'undefined') { + config[prop] = config1[prop]; + } + }); - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return cb() + utils.forEach(defaultToConfig2Keys, function defaultToConfig2(prop) { + if (typeof config2[prop] !== 'undefined') { + config[prop] = config2[prop]; + } else if (typeof config1[prop] !== 'undefined') { + config[prop] = config1[prop]; + } + }); - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) + var axiosKeys = valueFromConfig2Keys + .concat(mergeDeepPropertiesKeys) + .concat(defaultToConfig2Keys); - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false, cb) + var otherKeys = Object + .keys(config2) + .filter(function filterAxiosKeys(key) { + return axiosKeys.indexOf(key) === -1; + }); - var isSym = this.symlinks[abs] - var len = entries.length + utils.forEach(otherKeys, function otherKeysDefaultToConfig2(prop) { + if (typeof config2[prop] !== 'undefined') { + config[prop] = config2[prop]; + } else if (typeof config1[prop] !== 'undefined') { + config[prop] = config1[prop]; + } + }); - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return cb() + return config; +}; - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true, cb) +/***/ }), +/* 476 */ +/***/ (function(module, exports, __webpack_require__) { - var below = gspref.concat(entries[i], remain) - this._process(below, index, true, cb) - } +"use strict"; - cb() -} -Glob.prototype._processSimple = function (prefix, index, cb) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var self = this - this._stat(prefix, function (er, exists) { - self._processSimple2(prefix, index, er, exists, cb) - }) +/** + * A `Cancel` is an object that is thrown when an operation is canceled. + * + * @class + * @param {string=} message The message. + */ +function Cancel(message) { + this.message = message; } -Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { - - //console.error('ps2', prefix, exists) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return cb() - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - // Mark this as a match - this._emitMatch(index, prefix) - cb() -} +Cancel.prototype.toString = function toString() { + return 'Cancel' + (this.message ? ': ' + this.message : ''); +}; -// Returns either 'DIR', 'FILE', or false -Glob.prototype._stat = function (f, cb) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' +Cancel.prototype.__CANCEL__ = true; - if (f.length > this.maxLength) - return cb() +module.exports = Cancel; - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (Array.isArray(c)) - c = 'DIR' +/***/ }), +/* 477 */ +/***/ (function(module, exports, __webpack_require__) { - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return cb(null, c) +"use strict"; - if (needDir && c === 'FILE') - return cb() - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } +var Cancel = __webpack_require__(476); - var exists - var stat = this.statCache[abs] - if (stat !== undefined) { - if (stat === false) - return cb(null, stat) - else { - var type = stat.isDirectory() ? 'DIR' : 'FILE' - if (needDir && type === 'FILE') - return cb() - else - return cb(null, type, stat) - } +/** + * A `CancelToken` is an object that can be used to request cancellation of an operation. + * + * @class + * @param {Function} executor The executor function. + */ +function CancelToken(executor) { + if (typeof executor !== 'function') { + throw new TypeError('executor must be a function.'); } - var self = this - var statcb = inflight('stat\0' + abs, lstatcb_) - if (statcb) - fs.lstat(abs, statcb) + var resolvePromise; + this.promise = new Promise(function promiseExecutor(resolve) { + resolvePromise = resolve; + }); - function lstatcb_ (er, lstat) { - if (lstat && lstat.isSymbolicLink()) { - // If it's a symlink, then treat it as the target, unless - // the target does not exist, then treat it as a file. - return fs.stat(abs, function (er, stat) { - if (er) - self._stat2(f, abs, null, lstat, cb) - else - self._stat2(f, abs, er, stat, cb) - }) - } else { - self._stat2(f, abs, er, lstat, cb) + var token = this; + executor(function cancel(message) { + if (token.reason) { + // Cancellation has already been requested + return; } - } + + token.reason = new Cancel(message); + resolvePromise(token.reason); + }); } -Glob.prototype._stat2 = function (f, abs, er, stat, cb) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return cb() +/** + * Throws a `Cancel` if cancellation has been requested. + */ +CancelToken.prototype.throwIfRequested = function throwIfRequested() { + if (this.reason) { + throw this.reason; } +}; - var needDir = f.slice(-1) === '/' - this.statCache[abs] = stat - - if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) - return cb(null, false, stat) - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - this.cache[abs] = this.cache[abs] || c - - if (needDir && c === 'FILE') - return cb() +/** + * Returns an object that contains a new `CancelToken` and a function that, when called, + * cancels the `CancelToken`. + */ +CancelToken.source = function source() { + var cancel; + var token = new CancelToken(function executor(c) { + cancel = c; + }); + return { + token: token, + cancel: cancel + }; +}; - return cb(null, c, stat) -} +module.exports = CancelToken; /***/ }), -/* 504 */ +/* 478 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = realpath -realpath.realpath = realpath -realpath.sync = realpathSync -realpath.realpathSync = realpathSync -realpath.monkeypatch = monkeypatch -realpath.unmonkeypatch = unmonkeypatch - -var fs = __webpack_require__(23) -var origRealpath = fs.realpath -var origRealpathSync = fs.realpathSync - -var version = process.version -var ok = /^v[0-5]\./.test(version) -var old = __webpack_require__(505) - -function newError (er) { - return er && er.syscall === 'realpath' && ( - er.code === 'ELOOP' || - er.code === 'ENOMEM' || - er.code === 'ENAMETOOLONG' - ) -} +"use strict"; -function realpath (p, cache, cb) { - if (ok) { - return origRealpath(p, cache, cb) - } - if (typeof cache === 'function') { - cb = cache - cache = null - } - origRealpath(p, cache, function (er, result) { - if (newError(er)) { - old.realpath(p, cache, cb) - } else { - cb(er, result) - } - }) -} +/** + * Syntactic sugar for invoking a function and expanding an array for arguments. + * + * Common use case would be to use `Function.prototype.apply`. + * + * ```js + * function f(x, y, z) {} + * var args = [1, 2, 3]; + * f.apply(null, args); + * ``` + * + * With `spread` this example can be re-written. + * + * ```js + * spread(function(x, y, z) {})([1, 2, 3]); + * ``` + * + * @param {Function} callback + * @returns {Function} + */ +module.exports = function spread(callback) { + return function wrap(arr) { + return callback.apply(null, arr); + }; +}; -function realpathSync (p, cache) { - if (ok) { - return origRealpathSync(p, cache) - } - try { - return origRealpathSync(p, cache) - } catch (er) { - if (newError(er)) { - return old.realpathSync(p, cache) - } else { - throw er - } - } -} +/***/ }), +/* 479 */ +/***/ (function(module, exports, __webpack_require__) { -function monkeypatch () { - fs.realpath = realpath - fs.realpathSync = realpathSync -} +"use strict"; -function unmonkeypatch () { - fs.realpath = origRealpath - fs.realpathSync = origRealpathSync -} +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(6); +tslib_1.__exportStar(__webpack_require__(480), exports); /***/ }), -/* 505 */ +/* 480 */ /***/ (function(module, exports, __webpack_require__) { -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var pathModule = __webpack_require__(16); -var isWindows = process.platform === 'win32'; -var fs = __webpack_require__(23); +"use strict"; -// JavaScript implementation of realpath, ported from node pre-v6 +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isAxiosRequestError = (error) => { + return error && error.config && error.response === undefined; +}; +exports.isAxiosResponseError = (error) => { + return error && error.response && error.response.status !== undefined; +}; -var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - var callback; - if (DEBUG) { - var backtrace = new Error; - callback = debugCallback; - } else - callback = missingCallback; +/***/ }), +/* 481 */ +/***/ (function(module, exports, __webpack_require__) { - return callback; +"use strict"; - function debugCallback(err) { - if (err) { - backtrace.message = err.message; - err = backtrace; - missingCallback(err); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +class KbnClientStatus { + constructor(requester) { + this.requester = requester; } - } - - function missingCallback(err) { - if (err) { - if (process.throwDeprecation) - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - else if (!process.noDeprecation) { - var msg = 'fs: missing callback ' + (err.stack || err.message); - if (process.traceDeprecation) - console.trace(msg); - else - console.error(msg); - } + /** + * Get the full server status + */ + async get() { + return await this.requester.request({ + method: 'GET', + path: 'api/status', + }); + } + /** + * Get the overall/merged state + */ + async getOverallState() { + const status = await this.get(); + return status.status.overall.state; } - } } +exports.KbnClientStatus = KbnClientStatus; -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} -var normalize = pathModule.normalize; +/***/ }), +/* 482 */ +/***/ (function(module, exports, __webpack_require__) { -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} +"use strict"; -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const PLUGIN_STATUS_ID = /^plugin:(.+?)@/; +class KbnClientPlugins { + constructor(status) { + this.status = status; + } + /** + * Get a list of plugin ids that are enabled on the server + */ + async getEnabledIds() { + const pluginIds = []; + const apiResp = await this.status.get(); + for (const status of apiResp.status.statuses) { + if (status.id) { + const match = status.id.match(PLUGIN_STATUS_ID); + if (match) { + pluginIds.push(match[1]); + } + } + } + return pluginIds; + } } +exports.KbnClientPlugins = KbnClientPlugins; -exports.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } +/***/ }), +/* 483 */ +/***/ (function(module, exports, __webpack_require__) { - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; +"use strict"; - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +class KbnClientVersion { + constructor(status) { + this.status = status; } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; + async get() { + if (this.versionCache !== undefined) { + return this.versionCache; } - } - if (linkTarget === null) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; + const status = await this.status.get(); + this.versionCache = status.version.number + (status.version.build_snapshot ? '-SNAPSHOT' : ''); + return this.versionCache; } +} +exports.KbnClientVersion = KbnClientVersion; - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -exports.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = maybeCallback(cache); - cache = null; - } - // make p is absolute - p = pathModule.resolve(p); +/***/ }), +/* 484 */ +/***/ (function(module, exports, __webpack_require__) { - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } +"use strict"; - var original = p, - seenLinks = {}, - knownHard = {}; +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const kbn_client_requester_1 = __webpack_require__(438); +class KbnClientSavedObjects { + constructor(log, requester) { + this.log = log; + this.requester = requester; + } + /** + * Run the saved objects migration + */ + async migrate() { + this.log.debug('Migrating saved objects'); + return await this.requester.request({ + description: 'migrate saved objects', + path: kbn_client_requester_1.uriencode `/internal/saved_objects/_migrate`, + method: 'POST', + body: {}, + }); + } + /** + * Get an object + */ + async get(options) { + this.log.debug('Gettings saved object: %j', options); + return await this.requester.request({ + description: 'get saved object', + path: kbn_client_requester_1.uriencode `/api/saved_objects/${options.type}/${options.id}`, + method: 'GET', + }); + } + /** + * Create a saved object + */ + async create(options) { + this.log.debug('Creating saved object: %j', options); + return await this.requester.request({ + description: 'update saved object', + path: options.id + ? kbn_client_requester_1.uriencode `/api/saved_objects/${options.type}/${options.id}` + : kbn_client_requester_1.uriencode `/api/saved_objects/${options.type}`, + query: { + overwrite: options.overwrite, + }, + method: 'POST', + body: { + attributes: options.attributes, + migrationVersion: options.migrationVersion, + references: options.references, + }, + }); + } + /** + * Update a saved object + */ + async update(options) { + this.log.debug('Updating saved object: %j', options); + return await this.requester.request({ + description: 'update saved object', + path: kbn_client_requester_1.uriencode `/api/saved_objects/${options.type}/${options.id}`, + query: { + overwrite: options.overwrite, + }, + method: 'PUT', + body: { + attributes: options.attributes, + migrationVersion: options.migrationVersion, + references: options.references, + }, + }); + } + /** + * Delete an object + */ + async delete(options) { + this.log.debug('Deleting saved object %s/%s', options); + return await this.requester.request({ + description: 'delete saved object', + path: kbn_client_requester_1.uriencode `/api/saved_objects/${options.type}/${options.id}`, + method: 'DELETE', + }); + } +} +exports.KbnClientSavedObjects = KbnClientSavedObjects; - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - start(); +/***/ }), +/* 485 */ +/***/ (function(module, exports, __webpack_require__) { - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; +"use strict"; - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const kbn_client_requester_1 = __webpack_require__(438); +class KbnClientUiSettings { + constructor(log, requester, defaults) { + this.log = log; + this.requester = requester; + this.defaults = defaults; } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); + async get(setting) { + var _a; + const all = await this.getAll(); + const value = (_a = all[setting]) === null || _a === void 0 ? void 0 : _a.userValue; + this.log.verbose('uiSettings.value: %j', value); + return value; } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); + /** + * Gets defaultIndex from the config doc. + */ + async getDefaultIndex() { + return await this.get('defaultIndex'); } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); + /** + * Unset a uiSetting + */ + async unset(setting) { + return await this.requester.request({ + path: kbn_client_requester_1.uriencode `/api/kibana/settings/${setting}`, + method: 'DELETE', + }); } - - return fs.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); + /** + * Replace all uiSettings with the `doc` values, `doc` is merged + * with some defaults + */ + async replace(doc, { retries = 5 } = {}) { + this.log.debug('replacing kibana config doc: %j', doc); + const changes = { + ...this.defaults, + ...doc, + }; + for (const [name, { isOverridden }] of Object.entries(await this.getAll())) { + if (!isOverridden && !changes.hasOwnProperty(name)) { + changes[name] = null; + } + } + await this.requester.request({ + method: 'POST', + path: '/api/kibana/settings', + body: { changes }, + retries, + }); } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } + /** + * Add fields to the config doc (like setting timezone and defaultIndex) + */ + async update(updates) { + this.log.debug('applying update to kibana config: %j', updates); + await this.requester.request({ + path: '/api/kibana/settings', + method: 'POST', + body: { + changes: updates, + }, + }); } - fs.stat(base, function(err) { - if (err) return cb(err); + async getAll() { + const resp = await this.requester.request({ + path: '/api/kibana/settings', + method: 'GET', + }); + return resp.settings; + } +} +exports.KbnClientUiSettings = KbnClientUiSettings; - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - function gotTarget(err, target, base) { - if (err) return cb(err); +/***/ }), +/* 486 */ +/***/ (function(module, exports, __webpack_require__) { - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } +"use strict"; - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(6); +tslib_1.__exportStar(__webpack_require__(487), exports); /***/ }), -/* 506 */ +/* 487 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = minimatch -minimatch.Minimatch = Minimatch - -var path = { sep: '/' } -try { - path = __webpack_require__(16) -} catch (er) {} - -var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} -var expand = __webpack_require__(507) - -var plTypes = { - '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, - '?': { open: '(?:', close: ')?' }, - '+': { open: '(?:', close: ')+' }, - '*': { open: '(?:', close: ')*' }, - '@': { open: '(?:', close: ')' } -} +"use strict"; -// any single thing other than / -// don't need to escape / when using new RegExp() -var qmark = '[^/]' - -// * => any number of characters -var star = qmark + '*?' +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = __webpack_require__(6); +const util_1 = __webpack_require__(397); +const axios_1 = tslib_1.__importDefault(__webpack_require__(440)); +function parseConfig(log) { + const configJson = process.env.KIBANA_CI_STATS_CONFIG; + if (!configJson) { + log.debug('KIBANA_CI_STATS_CONFIG environment variable not found, disabling CiStatsReporter'); + return; + } + let config; + try { + config = JSON.parse(configJson); + } + catch (_) { + // handled below + } + if (typeof config === 'object' && config !== null) { + return validateConfig(log, config); + } + log.warning('KIBANA_CI_STATS_CONFIG is invalid, stats will not be reported'); + return; +} +function validateConfig(log, config) { + const validApiUrl = typeof config.apiUrl === 'string' && config.apiUrl.length !== 0; + if (!validApiUrl) { + log.warning('KIBANA_CI_STATS_CONFIG is missing a valid api url, stats will not be reported'); + return; + } + const validApiToken = typeof config.apiToken === 'string' && config.apiToken.length !== 0; + if (!validApiToken) { + log.warning('KIBANA_CI_STATS_CONFIG is missing a valid api token, stats will not be reported'); + return; + } + const validId = typeof config.buildId === 'string' && config.buildId.length !== 0; + if (!validId) { + log.warning('KIBANA_CI_STATS_CONFIG is missing a valid build id, stats will not be reported'); + return; + } + return config; +} +class CiStatsReporter { + constructor(config, log) { + this.config = config; + this.log = log; + } + static fromEnv(log) { + return new CiStatsReporter(parseConfig(log), log); + } + isEnabled() { + return !!this.config; + } + async metrics(metrics) { + var _a, _b, _c, _d; + if (!this.config) { + return; + } + let attempt = 0; + const maxAttempts = 5; + const bodySummary = metrics + .map(({ group, id, value }) => `[${group}/${id}=${value}]`) + .join(' '); + while (true) { + attempt += 1; + try { + await axios_1.default.request({ + method: 'POST', + url: '/v1/metrics', + baseURL: this.config.apiUrl, + headers: { + Authorization: `token ${this.config.apiToken}`, + }, + data: { + buildId: this.config.buildId, + metrics, + }, + }); + return; + } + catch (error) { + if (!((_a = error) === null || _a === void 0 ? void 0 : _a.request)) { + // not an axios error, must be a usage error that we should notify user about + throw error; + } + if (((_b = error) === null || _b === void 0 ? void 0 : _b.response) && error.response.status !== 502) { + // error response from service was received so warn the user and move on + this.log.warning(`error recording metric [status=${error.response.status}] [resp=${util_1.inspect(error.response.data)}] ${bodySummary}`); + return; + } + if (attempt === maxAttempts) { + this.log.warning(`failed to reach kibana-ci-stats service too many times, unable to record metric ${bodySummary}`); + return; + } + // we failed to reach the backend and we have remaining attempts, lets retry after a short delay + const reason = ((_d = (_c = error) === null || _c === void 0 ? void 0 : _c.response) === null || _d === void 0 ? void 0 : _d.status) ? `${error.response.status} response` + : 'no response'; + this.log.warning(`failed to reach kibana-ci-stats service [reason=${reason}], retrying in ${attempt} seconds`); + await new Promise((resolve) => setTimeout(resolve, attempt * 1000)); + } + } + } +} +exports.CiStatsReporter = CiStatsReporter; -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' +/***/ }), +/* 488 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -// characters that need to be escaped in RegExp. -var reSpecials = charSet('().*{}+?[]^$\\!') +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "commands", function() { return commands; }); +/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(489); +/* harmony import */ var _clean__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(581); +/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(686); +/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(687); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -// "abc" -> { a:true, b:true, c:true } -function charSet (s) { - return s.split('').reduce(function (set, c) { - set[c] = true - return set - }, {}) -} -// normalizes slashes. -var slashSplit = /\/+/ -minimatch.filter = filter -function filter (pattern, options) { - options = options || {} - return function (p, i, list) { - return minimatch(p, pattern, options) - } -} -function ext (a, b) { - a = a || {} - b = b || {} - var t = {} - Object.keys(b).forEach(function (k) { - t[k] = b[k] - }) - Object.keys(a).forEach(function (k) { - t[k] = a[k] - }) - return t -} +const commands = { + bootstrap: _bootstrap__WEBPACK_IMPORTED_MODULE_0__["BootstrapCommand"], + clean: _clean__WEBPACK_IMPORTED_MODULE_1__["CleanCommand"], + run: _run__WEBPACK_IMPORTED_MODULE_2__["RunCommand"], + watch: _watch__WEBPACK_IMPORTED_MODULE_3__["WatchCommand"] +}; -minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return minimatch +/***/ }), +/* 489 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - var orig = minimatch +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BootstrapCommand", function() { return BootstrapCommand; }); +/* harmony import */ var _utils_link_project_executables__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(490); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(500); +/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(501); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(502); +/* harmony import */ var _utils_project_checksums__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(575); +/* harmony import */ var _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(580); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ - var m = function minimatch (p, pattern, options) { - return orig.minimatch(p, pattern, ext(def, options)) - } - m.Minimatch = function Minimatch (pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)) - } - return m -} -Minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return Minimatch - return minimatch.defaults(def).Minimatch -} -function minimatch (p, pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } - if (!options) options = {} +const BootstrapCommand = { + description: 'Install dependencies and crosslink projects', + name: 'bootstrap', - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false - } + async run(projects, projectGraph, { + options, + kbn + }) { + const batchedProjectsByWorkspace = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_3__["topologicallyBatchProjects"])(projects, projectGraph, { + batchByWorkspace: true + }); + const batchedProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_3__["topologicallyBatchProjects"])(projects, projectGraph); + const extraArgs = [...(options['frozen-lockfile'] === true ? ['--frozen-lockfile'] : []), ...(options['prefer-offline'] === true ? ['--prefer-offline'] : [])]; - // "" only matches "" - if (pattern.trim() === '') return p === '' + for (const batch of batchedProjectsByWorkspace) { + for (const project of batch) { + if (project.isWorkspaceProject) { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].verbose(`Skipping workspace project: ${project.name}`); + continue; + } - return new Minimatch(pattern, options).match(p) -} + if (project.hasDependencies()) { + await project.installDependencies({ + extraArgs + }); + } + } + } -function Minimatch (pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options) - } + await Object(_utils_link_project_executables__WEBPACK_IMPORTED_MODULE_0__["linkProjectExecutables"])(projects, projectGraph); + /** + * At the end of the bootstrapping process we call all `kbn:bootstrap` scripts + * in the list of projects. We do this because some projects need to be + * transpiled before they can be used. Ideally we shouldn't do this unless we + * have to, as it will slow down the bootstrapping process. + */ - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } + const checksums = await Object(_utils_project_checksums__WEBPACK_IMPORTED_MODULE_4__["getAllChecksums"])(kbn, _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"]); + const caches = new Map(); + let cachedProjectCount = 0; - if (!options) options = {} - pattern = pattern.trim() + for (const project of projects.values()) { + if (project.hasScript('kbn:bootstrap')) { + const file = new _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_5__["BootstrapCacheFile"](kbn, project, checksums); + const valid = options.cache && file.isValid(); - // windows support: need to use /, not \ - if (path.sep !== '/') { - pattern = pattern.split(path.sep).join('/') - } + if (valid) { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].debug(`[${project.name}] cache up to date`); + } - this.options = options - this.set = [] - this.pattern = pattern - this.regexp = null - this.negate = false - this.comment = false - this.empty = false + caches.set(project, { + file, + valid + }); + cachedProjectCount += 1; + } + } - // make the set of regexps etc. - this.make() -} + if (cachedProjectCount > 0) { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].success(`${cachedProjectCount} bootsrap builds are cached`); + } -Minimatch.prototype.debug = function () {} + await Object(_utils_parallelize__WEBPACK_IMPORTED_MODULE_2__["parallelizeBatches"])(batchedProjects, async project => { + const cache = caches.get(project); -Minimatch.prototype.make = make -function make () { - // don't do it more than once. - if (this._made) return + if (cache && !cache.valid) { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].info(`[${project.name}] running [kbn:bootstrap] script`); + cache.file.delete(); + await project.runScriptStreaming('kbn:bootstrap'); + cache.file.write(); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].success(`[${project.name}] bootstrap complete`); + } + }); + } - var pattern = this.pattern - var options = this.options +}; - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true - return - } - if (!pattern) { - this.empty = true - return - } +/***/ }), +/* 490 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - // step 1: figure out negation, etc. - this.parseNegate() +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "linkProjectExecutables", function() { return linkProjectExecutables; }); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(491); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(500); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ - // step 2: expand braces - var set = this.globSet = this.braceExpand() - if (options.debug) this.debug = console.error - this.debug(this.pattern, set) - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(function (s) { - return s.split(slashSplit) - }) +/** + * Yarn does not link the executables from dependencies that are installed + * using `link:` https://github.com/yarnpkg/yarn/pull/5046 + * + * We simulate this functionality by walking through each project's project + * dependencies, and manually linking their executables if defined. The logic + * for linking was mostly adapted from lerna: https://github.com/lerna/lerna/blob/1d7eb9eeff65d5a7de64dea73613b1bf6bfa8d57/src/PackageUtilities.js#L348 + */ +async function linkProjectExecutables(projectsByName, projectGraph) { + _log__WEBPACK_IMPORTED_MODULE_2__["log"].debug(`Linking package executables`); - this.debug(this.pattern, set) + for (const [projectName, projectDeps] of projectGraph) { + const project = projectsByName.get(projectName); + const binsDir = Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(project.nodeModulesLocation, '.bin'); - // glob --> regexps - set = set.map(function (s, si, set) { - return s.map(this.parse, this) - }, this) + for (const projectDep of projectDeps) { + const executables = projectDep.getExecutables(); - this.debug(this.pattern, set) + for (const name of Object.keys(executables)) { + const srcPath = executables[name]; // existing logic from lerna -- ensure that the bin we are going to + // point to exists or ignore it - // filter out everything that didn't compile properly. - set = set.filter(function (s) { - return s.indexOf(false) === -1 - }) + if (!(await Object(_fs__WEBPACK_IMPORTED_MODULE_1__["isFile"])(srcPath))) { + continue; + } - this.debug(this.pattern, set) + const dest = Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(binsDir, name); // Get relative project path with normalized path separators. - this.set = set + const projectRelativePath = Object(path__WEBPACK_IMPORTED_MODULE_0__["relative"])(project.path, srcPath).split(path__WEBPACK_IMPORTED_MODULE_0__["sep"]).join('/'); + _log__WEBPACK_IMPORTED_MODULE_2__["log"].debug(`[${project.name}] ${name} -> ${projectRelativePath}`); + await Object(_fs__WEBPACK_IMPORTED_MODULE_1__["mkdirp"])(Object(path__WEBPACK_IMPORTED_MODULE_0__["dirname"])(dest)); + await Object(_fs__WEBPACK_IMPORTED_MODULE_1__["createSymlink"])(srcPath, dest, 'exec'); + await Object(_fs__WEBPACK_IMPORTED_MODULE_1__["chmod"])(dest, '755'); + } + } + } } -Minimatch.prototype.parseNegate = parseNegate -function parseNegate () { - var pattern = this.pattern - var negate = false - var options = this.options - var negateOffset = 0 +/***/ }), +/* 491 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - if (options.nonegate) return +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readFile", function() { return readFile; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "chmod", function() { return chmod; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mkdirp", function() { return mkdirp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unlink", function() { return unlink; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "copyDirectory", function() { return copyDirectory; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isSymlink", function() { return isSymlink; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isDirectory", function() { return isDirectory; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isFile", function() { return isFile; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createSymlink", function() { return createSymlink; }); +/* harmony import */ var cmd_shim__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(492); +/* harmony import */ var cmd_shim__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(cmd_shim__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(349); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var ncp__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(499); +/* harmony import */ var ncp__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(ncp__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(397); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_4__); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ - for (var i = 0, l = pattern.length - ; i < l && pattern.charAt(i) === '!' - ; i++) { - negate = !negate - negateOffset++ - } - if (negateOffset) this.pattern = pattern.substr(negateOffset) - this.negate = negate -} -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch.braceExpand = function (pattern, options) { - return braceExpand(pattern, options) -} -Minimatch.prototype.braceExpand = braceExpand -function braceExpand (pattern, options) { - if (!options) { - if (this instanceof Minimatch) { - options = this.options - } else { - options = {} - } - } +const lstat = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.lstat); +const readFile = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.readFile); +const symlink = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.symlink); +const chmod = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.chmod); +const cmdShim = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(cmd_shim__WEBPACK_IMPORTED_MODULE_0___default.a); +const mkdir = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.mkdir); +const mkdirp = async path => await mkdir(path, { + recursive: true +}); +const unlink = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.unlink); +const copyDirectory = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(ncp__WEBPACK_IMPORTED_MODULE_2__["ncp"]); - pattern = typeof pattern === 'undefined' - ? this.pattern : pattern +async function statTest(path, block) { + try { + return block((await lstat(path))); + } catch (e) { + if (e.code === 'ENOENT') { + return false; + } - if (typeof pattern === 'undefined') { - throw new TypeError('undefined pattern') + throw e; } +} +/** + * Test if a path points to a symlink. + * @param path + */ - if (options.nobrace || - !pattern.match(/\{.*\}/)) { - // shortcut. no need to expand. - return [pattern] - } - return expand(pattern) +async function isSymlink(path) { + return await statTest(path, stats => stats.isSymbolicLink()); } +/** + * Test if a path points to a directory. + * @param path + */ -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -Minimatch.prototype.parse = parse -var SUBPARSE = {} -function parse (pattern, isSub) { - if (pattern.length > 1024 * 64) { - throw new TypeError('pattern is too long') - } - - var options = this.options - - // shortcuts - if (!options.noglobstar && pattern === '**') return GLOBSTAR - if (pattern === '') return '' +async function isDirectory(path) { + return await statTest(path, stats => stats.isDirectory()); +} +/** + * Test if a path points to a regular file. + * @param path + */ - var re = '' - var hasMagic = !!options.nocase - var escaping = false - // ? => one single character - var patternListStack = [] - var negativeLists = [] - var stateChar - var inClass = false - var reClassStart = -1 - var classStart = -1 - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - var patternStart = pattern.charAt(0) === '.' ? '' // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' - : '(?!\\.)' - var self = this +async function isFile(path) { + return await statTest(path, stats => stats.isFile()); +} +/** + * Create a symlink at dest that points to src. Adapted from + * https://github.com/lerna/lerna/blob/2f1b87d9e2295f587e4ac74269f714271d8ed428/src/FileSystemUtilities.js#L103. + * + * @param src + * @param dest + * @param type 'dir', 'file', 'junction', or 'exec'. 'exec' on + * windows will use the `cmd-shim` module since symlinks can't be used + * for executable files on windows. + */ - function clearStateChar () { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star - hasMagic = true - break - case '?': - re += qmark - hasMagic = true - break - default: - re += '\\' + stateChar - break - } - self.debug('clearStateChar %j %j', stateChar, re) - stateChar = false +async function createSymlink(src, dest, type) { + if (process.platform === 'win32') { + if (type === 'exec') { + await cmdShim(src, dest); + } else { + await forceCreate(src, dest, type); } + } else { + const posixType = type === 'exec' ? 'file' : type; + const relativeSource = Object(path__WEBPACK_IMPORTED_MODULE_3__["relative"])(Object(path__WEBPACK_IMPORTED_MODULE_3__["dirname"])(dest), src); + await forceCreate(relativeSource, dest, posixType); } +} - for (var i = 0, len = pattern.length, c - ; (i < len) && (c = pattern.charAt(i)) - ; i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c) - - // skip over any that are escaped. - if (escaping && reSpecials[c]) { - re += '\\' + c - escaping = false - continue +async function forceCreate(src, dest, type) { + try { + // If something exists at `dest` we need to remove it first. + await unlink(dest); + } catch (error) { + if (error.code !== 'ENOENT') { + throw error; } + } - switch (c) { - case '/': - // completely not allowed, even escaped. - // Should already be path-split by now. - return false - - case '\\': - clearStateChar() - escaping = true - continue - - // the various stateChar values - // for the "extglob" stuff. - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) - - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class') - if (c === '!' && i === classStart + 1) c = '^' - re += c - continue - } - - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - self.debug('call clearStateChar %j', stateChar) - clearStateChar() - stateChar = c - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar() - continue - - case '(': - if (inClass) { - re += '(' - continue - } - - if (!stateChar) { - re += '\\(' - continue - } - - patternListStack.push({ - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close - }) - // negation is (?:(?!js)[^/]*) - re += stateChar === '!' ? '(?:(?!(?:' : '(?:' - this.debug('plType %j %j', stateChar, re) - stateChar = false - continue - - case ')': - if (inClass || !patternListStack.length) { - re += '\\)' - continue - } - - clearStateChar() - hasMagic = true - var pl = patternListStack.pop() - // negation is (?:(?!js)[^/]*) - // The others are (?:) - re += pl.close - if (pl.type === '!') { - negativeLists.push(pl) - } - pl.reEnd = re.length - continue - - case '|': - if (inClass || !patternListStack.length || escaping) { - re += '\\|' - escaping = false - continue - } - - clearStateChar() - re += '|' - continue + await symlink(src, dest, type); +} - // these are mostly the same in regexp and glob - case '[': - // swallow any state-tracking char before the [ - clearStateChar() +/***/ }), +/* 492 */ +/***/ (function(module, exports, __webpack_require__) { - if (inClass) { - re += '\\' + c - continue - } +// On windows, create a .cmd file. +// Read the #! in the file to see what it uses. The vast majority +// of the time, this will be either: +// "#!/usr/bin/env " +// or: +// "#! " +// +// Write a binroot/pkg.bin + ".cmd" file that has this line in it: +// @ %~dp0 %* - inClass = true - classStart = i - reClassStart = re.length - re += c - continue +module.exports = cmdShim +cmdShim.ifExists = cmdShimIfExists - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c - escaping = false - continue - } +var fs = __webpack_require__(493) - // handle the case where we left a class open. - // "[z-a]" is valid, equivalent to "\[z-a\]" - if (inClass) { - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - var cs = pattern.substring(classStart + 1, i) - try { - RegExp('[' + cs + ']') - } catch (er) { - // not a valid class! - var sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' - hasMagic = hasMagic || sp[1] - inClass = false - continue - } - } +var mkdir = __webpack_require__(497) + , path = __webpack_require__(4) + , toBatchSyntax = __webpack_require__(498) + , shebangExpr = /^#\!\s*(?:\/usr\/bin\/env)?\s*([^ \t]+=[^ \t]+\s+)*\s*([^ \t]+)(.*)$/ - // finish up the class. - hasMagic = true - inClass = false - re += c - continue +function cmdShimIfExists (from, to, cb) { + fs.stat(from, function (er) { + if (er) return cb() + cmdShim(from, to, cb) + }) +} - default: - // swallow any state char that wasn't consumed - clearStateChar() +// Try to unlink, but ignore errors. +// Any problems will surface later. +function rm (path, cb) { + fs.unlink(path, function(er) { + cb() + }) +} - if (escaping) { - // no need - escaping = false - } else if (reSpecials[c] - && !(c === '^' && inClass)) { - re += '\\' - } +function cmdShim (from, to, cb) { + fs.stat(from, function (er, stat) { + if (er) + return cb(er) - re += c + cmdShim_(from, to, cb) + }) +} - } // switch - } // for +function cmdShim_ (from, to, cb) { + var then = times(2, next, cb) + rm(to, then) + rm(to + ".cmd", then) - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.substr(classStart + 1) - sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] - hasMagic = hasMagic || sp[1] + function next(er) { + writeShim(from, to, cb) } +} - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + pl.open.length) - this.debug('setting tail', re, pl) - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\' - } - - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + '|' +function writeShim (from, to, cb) { + // make a cmd file and a sh script + // First, check if the bin is a #! of some sort. + // If not, then assume it's something that'll be compiled, or some other + // sort of script, and just call it directly. + mkdir(path.dirname(to), function (er) { + if (er) + return cb(er) + fs.readFile(from, "utf8", function (er, data) { + if (er) return writeShim_(from, to, null, null, cb) + var firstLine = data.trim().split(/\r*\n/)[0] + , shebang = firstLine.match(shebangExpr) + if (!shebang) return writeShim_(from, to, null, null, null, cb) + var vars = shebang[1] || "" + , prog = shebang[2] + , args = shebang[3] || "" + return writeShim_(from, to, prog, args, vars, cb) }) + }) +} - this.debug('tail=%j\n %s', tail, tail, pl, re) - var t = pl.type === '*' ? star - : pl.type === '?' ? qmark - : '\\' + pl.type - - hasMagic = true - re = re.slice(0, pl.reStart) + t + '\\(' + tail - } - // handle trailing things that only matter at the very end. - clearStateChar() - if (escaping) { - // trailing \\ - re += '\\\\' +function writeShim_ (from, to, prog, args, variables, cb) { + var shTarget = path.relative(path.dirname(to), from) + , target = shTarget.split("/").join("\\") + , longProg + , shProg = prog && prog.split("\\").join("/") + , shLongProg + , pwshProg = shProg && "\"" + shProg + "$exe\"" + , pwshLongProg + shTarget = shTarget.split("\\").join("/") + args = args || "" + variables = variables || "" + if (!prog) { + prog = "\"%~dp0\\" + target + "\"" + shProg = "\"$basedir/" + shTarget + "\"" + pwshProg = shProg + args = "" + target = "" + shTarget = "" + } else { + longProg = "\"%~dp0\\" + prog + ".exe\"" + shLongProg = "\"$basedir/" + prog + "\"" + pwshLongProg = "\"$basedir/" + prog + "$exe\"" + target = "\"%~dp0\\" + target + "\"" + shTarget = "\"$basedir/" + shTarget + "\"" } - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - var addPatternStart = false - switch (re.charAt(0)) { - case '.': - case '[': - case '(': addPatternStart = true + // @SETLOCAL + // + // @IF EXIST "%~dp0\node.exe" ( + // @SET "_prog=%~dp0\node.exe" + // ) ELSE ( + // @SET "_prog=node" + // @SET PATHEXT=%PATHEXT:;.JS;=;% + // ) + // + // "%_prog%" "%~dp0\.\node_modules\npm\bin\npm-cli.js" %* + // @ENDLOCAL + var cmd + if (longProg) { + shLongProg = shLongProg.trim(); + args = args.trim(); + var variableDeclarationsAsBatch = toBatchSyntax.convertToSetCommands(variables) + cmd = "@SETLOCAL\r\n" + + variableDeclarationsAsBatch + + "\r\n" + + "@IF EXIST " + longProg + " (\r\n" + + " @SET \"_prog=" + longProg.replace(/(^")|("$)/g, '') + "\"\r\n" + + ") ELSE (\r\n" + + " @SET \"_prog=" + prog.replace(/(^")|("$)/g, '') + "\"\r\n" + + " @SET PATHEXT=%PATHEXT:;.JS;=;%\r\n" + + ")\r\n" + + "\r\n" + + "\"%_prog%\" " + args + " " + target + " %*\r\n" + + '@ENDLOCAL\r\n' + } else { + cmd = "@" + prog + " " + args + " " + target + " %*\r\n" } - // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. - for (var n = negativeLists.length - 1; n > -1; n--) { - var nl = negativeLists[n] - - var nlBefore = re.slice(0, nl.reStart) - var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) - var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) - var nlAfter = re.slice(nl.reEnd) - - nlLast += nlAfter - - // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. - var openParensBefore = nlBefore.split('(').length - 1 - var cleanAfter = nlAfter - for (i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') - } - nlAfter = cleanAfter + // #!/bin/sh + // basedir=`dirname "$0"` + // + // case `uname` in + // *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;; + // esac + // + // if [ -x "$basedir/node.exe" ]; then + // "$basedir/node.exe" "$basedir/node_modules/npm/bin/npm-cli.js" "$@" + // ret=$? + // else + // node "$basedir/node_modules/npm/bin/npm-cli.js" "$@" + // ret=$? + // fi + // exit $ret - var dollar = '' - if (nlAfter === '' && isSub !== SUBPARSE) { - dollar = '$' - } - var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast - re = newRe - } + var sh = "#!/bin/sh\n" - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== '' && hasMagic) { - re = '(?=.)' + re - } + sh = sh + + "basedir=$(dirname \"$(echo \"$0\" | sed -e 's,\\\\,/,g')\")\n" + + "\n" + + "case `uname` in\n" + + " *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w \"$basedir\"`;;\n" + + "esac\n" + + "\n" - if (addPatternStart) { - re = patternStart + re + if (shLongProg) { + sh = sh + + "if [ -x "+shLongProg+" ]; then\n" + + " " + variables + shLongProg + " " + args + " " + shTarget + " \"$@\"\n" + + " ret=$?\n" + + "else \n" + + " " + variables + shProg + " " + args + " " + shTarget + " \"$@\"\n" + + " ret=$?\n" + + "fi\n" + + "exit $ret\n" + } else { + sh = sh + + shProg + " " + args + " " + shTarget + " \"$@\"\n" + + "exit $?\n" } - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [re, hasMagic] - } - - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) + // #!/usr/bin/env pwsh + // $basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + // + // $ret=0 + // $exe = "" + // if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + // # Fix case when both the Windows and Linux builds of Node + // # are installed in the same directory + // $exe = ".exe" + // } + // if (Test-Path "$basedir/node") { + // & "$basedir/node$exe" "$basedir/node_modules/npm/bin/npm-cli.js" $args + // $ret=$LASTEXITCODE + // } else { + // & "node$exe" "$basedir/node_modules/npm/bin/npm-cli.js" $args + // $ret=$LASTEXITCODE + // } + // exit $ret + var pwsh = "#!/usr/bin/env pwsh\n" + + "$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent\n" + + "\n" + + "$exe=\"\"\n" + + "if ($PSVersionTable.PSVersion -lt \"6.0\" -or $IsWindows) {\n" + + " # Fix case when both the Windows and Linux builds of Node\n" + + " # are installed in the same directory\n" + + " $exe=\".exe\"\n" + + "}\n" + if (shLongProg) { + pwsh = pwsh + + "$ret=0\n" + + "if (Test-Path " + pwshLongProg + ") {\n" + + " & " + pwshLongProg + " " + args + " " + shTarget + " $args\n" + + " $ret=$LASTEXITCODE\n" + + "} else {\n" + + " & " + pwshProg + " " + args + " " + shTarget + " $args\n" + + " $ret=$LASTEXITCODE\n" + + "}\n" + + "exit $ret\n" + } else { + pwsh = pwsh + + "& " + pwshProg + " " + args + " " + shTarget + " $args\n" + + "exit $LASTEXITCODE\n" } - var flags = options.nocase ? 'i' : '' - try { - var regExp = new RegExp('^' + re + '$', flags) - } catch (er) { - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - return new RegExp('$.') + var then = times(3, next, cb) + fs.writeFile(to + ".ps1", pwsh, "utf8", then) + fs.writeFile(to + ".cmd", cmd, "utf8", then) + fs.writeFile(to, sh, "utf8", then) + function next () { + chmodShim(to, cb) } - - regExp._glob = pattern - regExp._src = re - - return regExp } -minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe() +function chmodShim (to, cb) { + var then = times(2, cb, cb) + fs.chmod(to, "0755", then) + fs.chmod(to + ".cmd", "0755", then) + fs.chmod(to + ".ps1", "0755", then) } -Minimatch.prototype.makeRe = makeRe -function makeRe () { - if (this.regexp || this.regexp === false) return this.regexp - - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - var set = this.set - - if (!set.length) { - this.regexp = false - return this.regexp +function times(n, ok, cb) { + var errState = null + return function(er) { + if (!errState) { + if (er) + cb(errState = er) + else if (--n === 0) + ok() + } } - var options = this.options +} - var twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot - var flags = options.nocase ? 'i' : '' - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return (p === GLOBSTAR) ? twoStar - : (typeof p === 'string') ? regExpEscape(p) - : p._src - }).join('\\\/') - }).join('|') +/***/ }), +/* 493 */ +/***/ (function(module, exports, __webpack_require__) { - // must match entire pattern - // ending in a * or ** will make it less strict. - re = '^(?:' + re + ')$' +var fs = __webpack_require__(349) +var polyfills = __webpack_require__(494) +var legacy = __webpack_require__(495) +var clone = __webpack_require__(496) - // can match anything, as long as it's not this. - if (this.negate) re = '^(?!' + re + ').*$' +var util = __webpack_require__(397) - try { - this.regexp = new RegExp(re, flags) - } catch (ex) { - this.regexp = false - } - return this.regexp -} +/* istanbul ignore next - node 0.x polyfill */ +var gracefulQueue +var previousSymbol -minimatch.match = function (list, pattern, options) { - options = options || {} - var mm = new Minimatch(pattern, options) - list = list.filter(function (f) { - return mm.match(f) - }) - if (mm.options.nonull && !list.length) { - list.push(pattern) - } - return list +/* istanbul ignore else - node 0.x polyfill */ +if (typeof Symbol === 'function' && typeof Symbol.for === 'function') { + gracefulQueue = Symbol.for('graceful-fs.queue') + // This is used in testing by future versions + previousSymbol = Symbol.for('graceful-fs.previous') +} else { + gracefulQueue = '___graceful-fs.queue' + previousSymbol = '___graceful-fs.previous' } -Minimatch.prototype.match = match -function match (f, partial) { - this.debug('match', f, this.pattern) - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === '' - - if (f === '/' && partial) return true - - var options = this.options +function noop () {} - // windows: need to use /, not \ - if (path.sep !== '/') { - f = f.split(path.sep).join('/') +var debug = noop +if (util.debuglog) + debug = util.debuglog('gfs4') +else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) + debug = function() { + var m = util.format.apply(util, arguments) + m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') + console.error(m) } - // treat the test path as a set of pathparts. - f = f.split(slashSplit) - this.debug(this.pattern, 'split', f) +// Once time initialization +if (!global[gracefulQueue]) { + // This queue can be shared by multiple loaded instances + var queue = [] + Object.defineProperty(global, gracefulQueue, { + get: function() { + return queue + } + }) - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. + // Patch fs.close/closeSync to shared queue version, because we need + // to retry() whenever a close happens *anywhere* in the program. + // This is essential when multiple graceful-fs instances are + // in play at the same time. + fs.close = (function (fs$close) { + function close (fd, cb) { + return fs$close.call(fs, fd, function (err) { + // This function uses the graceful-fs shared queue + if (!err) { + retry() + } - var set = this.set - this.debug(this.pattern, 'set', set) + if (typeof cb === 'function') + cb.apply(this, arguments) + }) + } - // Find the basename of the path by looking for the last non-empty segment - var filename - var i - for (i = f.length - 1; i >= 0; i--) { - filename = f[i] - if (filename) break - } + Object.defineProperty(close, previousSymbol, { + value: fs$close + }) + return close + })(fs.close) - for (i = 0; i < set.length; i++) { - var pattern = set[i] - var file = f - if (options.matchBase && pattern.length === 1) { - file = [filename] - } - var hit = this.matchOne(file, pattern, partial) - if (hit) { - if (options.flipNegate) return true - return !this.negate + fs.closeSync = (function (fs$closeSync) { + function closeSync (fd) { + // This function uses the graceful-fs shared queue + fs$closeSync.apply(fs, arguments) + retry() } - } - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate + Object.defineProperty(closeSync, previousSymbol, { + value: fs$closeSync + }) + return closeSync + })(fs.closeSync) + + if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { + process.on('exit', function() { + debug(global[gracefulQueue]) + __webpack_require__(371).equal(global[gracefulQueue].length, 0) + }) + } } -// set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. -Minimatch.prototype.matchOne = function (file, pattern, partial) { - var options = this.options +module.exports = patch(clone(fs)) +if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) { + module.exports = patch(fs) + fs.__patched = true; +} - this.debug('matchOne', - { 'this': this, file: file, pattern: pattern }) +function patch (fs) { + // Everything that references the open() function needs to be in here + polyfills(fs) + fs.gracefulify = patch - this.debug('matchOne', file.length, pattern.length) + fs.createReadStream = createReadStream + fs.createWriteStream = createWriteStream + var fs$readFile = fs.readFile + fs.readFile = readFile + function readFile (path, options, cb) { + if (typeof options === 'function') + cb = options, options = null - for (var fi = 0, - pi = 0, - fl = file.length, - pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi++, pi++) { - this.debug('matchOne loop') - var p = pattern[pi] - var f = file[fi] + return go$readFile(path, options, cb) - this.debug(pattern, p, f) + function go$readFile (path, options, cb) { + return fs$readFile(path, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readFile, [path, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } - // should be impossible. - // some invalid regexp stuff in the set. - if (p === false) return false + var fs$writeFile = fs.writeFile + fs.writeFile = writeFile + function writeFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]) + return go$writeFile(path, data, options, cb) - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi - var pr = pi + 1 - if (pr === pl) { - this.debug('** at the end') - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for (; fi < fl; fi++) { - if (file[fi] === '.' || file[fi] === '..' || - (!options.dot && file[fi].charAt(0) === '.')) return false + function go$writeFile (path, data, options, cb) { + return fs$writeFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$writeFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() } - return true - } - - // ok, let's see if we can swallow whatever we can. - while (fr < fl) { - var swallowee = file[fr] + }) + } + } - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) + var fs$appendFile = fs.appendFile + if (fs$appendFile) + fs.appendFile = appendFile + function appendFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee) - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || swallowee === '..' || - (!options.dot && swallowee.charAt(0) === '.')) { - this.debug('dot detected!', file, fr, pattern, pr) - break - } + return go$appendFile(path, data, options, cb) - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue') - fr++ + function go$appendFile (path, data, options, cb) { + return fs$appendFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$appendFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() } - } - - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr) - if (fr === fl) return true - } - return false + }) } + } - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit - if (typeof p === 'string') { - if (options.nocase) { - hit = f.toLowerCase() === p.toLowerCase() - } else { - hit = f === p - } - this.debug('string match', p, f, hit) + var fs$readdir = fs.readdir + fs.readdir = readdir + function readdir (path, options, cb) { + var args = [path] + if (typeof options !== 'function') { + args.push(options) } else { - hit = f.match(p) - this.debug('pattern match', p, f, hit) + cb = options } + args.push(go$readdir$cb) - if (!hit) return false - } - - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') - return emptyFileEnd - } + return go$readdir(args) - // should be unreachable. - throw new Error('wtf?') -} + function go$readdir$cb (err, files) { + if (files && files.sort) + files.sort() -// replace stuff like \* with * -function globUnescape (s) { - return s.replace(/\\(.)/g, '$1') -} + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readdir, [args]]) -function regExpEscape (s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') -} + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + } + } + function go$readdir (args) { + return fs$readdir.apply(fs, args) + } -/***/ }), -/* 507 */ -/***/ (function(module, exports, __webpack_require__) { + if (process.version.substr(0, 4) === 'v0.8') { + var legStreams = legacy(fs) + ReadStream = legStreams.ReadStream + WriteStream = legStreams.WriteStream + } -var concatMap = __webpack_require__(508); -var balanced = __webpack_require__(509); + var fs$ReadStream = fs.ReadStream + if (fs$ReadStream) { + ReadStream.prototype = Object.create(fs$ReadStream.prototype) + ReadStream.prototype.open = ReadStream$open + } -module.exports = expandTop; + var fs$WriteStream = fs.WriteStream + if (fs$WriteStream) { + WriteStream.prototype = Object.create(fs$WriteStream.prototype) + WriteStream.prototype.open = WriteStream$open + } -var escSlash = '\0SLASH'+Math.random()+'\0'; -var escOpen = '\0OPEN'+Math.random()+'\0'; -var escClose = '\0CLOSE'+Math.random()+'\0'; -var escComma = '\0COMMA'+Math.random()+'\0'; -var escPeriod = '\0PERIOD'+Math.random()+'\0'; - -function numeric(str) { - return parseInt(str, 10) == str - ? parseInt(str, 10) - : str.charCodeAt(0); -} - -function escapeBraces(str) { - return str.split('\\\\').join(escSlash) - .split('\\{').join(escOpen) - .split('\\}').join(escClose) - .split('\\,').join(escComma) - .split('\\.').join(escPeriod); -} - -function unescapeBraces(str) { - return str.split(escSlash).join('\\') - .split(escOpen).join('{') - .split(escClose).join('}') - .split(escComma).join(',') - .split(escPeriod).join('.'); -} - - -// Basically just str.split(","), but handling cases -// where we have nested braced sections, which should be -// treated as individual members, like {a,{b,c},d} -function parseCommaParts(str) { - if (!str) - return ['']; - - var parts = []; - var m = balanced('{', '}', str); - - if (!m) - return str.split(','); + Object.defineProperty(fs, 'ReadStream', { + get: function () { + return ReadStream + }, + set: function (val) { + ReadStream = val + }, + enumerable: true, + configurable: true + }) + Object.defineProperty(fs, 'WriteStream', { + get: function () { + return WriteStream + }, + set: function (val) { + WriteStream = val + }, + enumerable: true, + configurable: true + }) - var pre = m.pre; - var body = m.body; - var post = m.post; - var p = pre.split(','); + // legacy names + var FileReadStream = ReadStream + Object.defineProperty(fs, 'FileReadStream', { + get: function () { + return FileReadStream + }, + set: function (val) { + FileReadStream = val + }, + enumerable: true, + configurable: true + }) + var FileWriteStream = WriteStream + Object.defineProperty(fs, 'FileWriteStream', { + get: function () { + return FileWriteStream + }, + set: function (val) { + FileWriteStream = val + }, + enumerable: true, + configurable: true + }) - p[p.length-1] += '{' + body + '}'; - var postParts = parseCommaParts(post); - if (post.length) { - p[p.length-1] += postParts.shift(); - p.push.apply(p, postParts); + function ReadStream (path, options) { + if (this instanceof ReadStream) + return fs$ReadStream.apply(this, arguments), this + else + return ReadStream.apply(Object.create(ReadStream.prototype), arguments) } - parts.push.apply(parts, p); - - return parts; -} - -function expandTop(str) { - if (!str) - return []; + function ReadStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + if (that.autoClose) + that.destroy() - // I don't know why Bash 4.3 does this, but it does. - // Anything starting with {} will have the first two bytes preserved - // but *only* at the top level, so {},a}b will not expand to anything, - // but a{},b}c will be expanded to [a}c,abc]. - // One could argue that this is a bug in Bash, but since the goal of - // this module is to match Bash's rules, we escape a leading {} - if (str.substr(0, 2) === '{}') { - str = '\\{\\}' + str.substr(2); + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) + that.read() + } + }) } - return expand(escapeBraces(str), true).map(unescapeBraces); -} - -function identity(e) { - return e; -} - -function embrace(str) { - return '{' + str + '}'; -} -function isPadded(el) { - return /^-?0\d/.test(el); -} - -function lte(i, y) { - return i <= y; -} -function gte(i, y) { - return i >= y; -} - -function expand(str, isTop) { - var expansions = []; - - var m = balanced('{', '}', str); - if (!m || /\$$/.test(m.pre)) return [str]; - - var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); - var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); - var isSequence = isNumericSequence || isAlphaSequence; - var isOptions = m.body.indexOf(',') >= 0; - if (!isSequence && !isOptions) { - // {a},b} - if (m.post.match(/,.*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; - return expand(str); - } - return [str]; + function WriteStream (path, options) { + if (this instanceof WriteStream) + return fs$WriteStream.apply(this, arguments), this + else + return WriteStream.apply(Object.create(WriteStream.prototype), arguments) } - var n; - if (isSequence) { - n = m.body.split(/\.\./); - } else { - n = parseCommaParts(m.body); - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y - n = expand(n[0], false).map(embrace); - if (n.length === 1) { - var post = m.post.length - ? expand(m.post, false) - : ['']; - return post.map(function(p) { - return m.pre + n[0] + p; - }); + function WriteStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + that.destroy() + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) } - } + }) } - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. - - // no need to expand pre, since it is guaranteed to be free of brace-sets - var pre = m.pre; - var post = m.post.length - ? expand(m.post, false) - : ['']; + function createReadStream (path, options) { + return new fs.ReadStream(path, options) + } - var N; + function createWriteStream (path, options) { + return new fs.WriteStream(path, options) + } - if (isSequence) { - var x = numeric(n[0]); - var y = numeric(n[1]); - var width = Math.max(n[0].length, n[1].length) - var incr = n.length == 3 - ? Math.abs(numeric(n[2])) - : 1; - var test = lte; - var reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - var pad = n.some(isPadded); + var fs$open = fs.open + fs.open = open + function open (path, flags, mode, cb) { + if (typeof mode === 'function') + cb = mode, mode = null - N = []; + return go$open(path, flags, mode, cb) - for (var i = x; test(i, y); i += incr) { - var c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') - c = ''; - } else { - c = String(i); - if (pad) { - var need = width - c.length; - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) - c = '-' + z + c.slice(1); - else - c = z + c; - } + function go$open (path, flags, mode, cb) { + return fs$open(path, flags, mode, function (err, fd) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$open, [path, flags, mode, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() } - } - N.push(c); - } - } else { - N = concatMap(n, function(el) { return expand(el, false) }); - } - - for (var j = 0; j < N.length; j++) { - for (var k = 0; k < post.length; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) - expansions.push(expansion); + }) } } - return expansions; + return fs } +function enqueue (elem) { + debug('ENQUEUE', elem[0].name, elem[1]) + global[gracefulQueue].push(elem) +} - -/***/ }), -/* 508 */ -/***/ (function(module, exports) { - -module.exports = function (xs, fn) { - var res = []; - for (var i = 0; i < xs.length; i++) { - var x = fn(xs[i], i); - if (isArray(x)) res.push.apply(res, x); - else res.push(x); - } - return res; -}; - -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; +function retry () { + var elem = global[gracefulQueue].shift() + if (elem) { + debug('RETRY', elem[0].name, elem[1]) + elem[0].apply(null, elem[1]) + } +} /***/ }), -/* 509 */ +/* 494 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var constants = __webpack_require__(411) -module.exports = balanced; -function balanced(a, b, str) { - if (a instanceof RegExp) a = maybeMatch(a, str); - if (b instanceof RegExp) b = maybeMatch(b, str); +var origCwd = process.cwd +var cwd = null - var r = range(a, b, str); +var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform - return r && { - start: r[0], - end: r[1], - pre: str.slice(0, r[0]), - body: str.slice(r[0] + a.length, r[1]), - post: str.slice(r[1] + b.length) - }; +process.cwd = function() { + if (!cwd) + cwd = origCwd.call(process) + return cwd } +try { + process.cwd() +} catch (er) {} -function maybeMatch(reg, str) { - var m = str.match(reg); - return m ? m[0] : null; +var chdir = process.chdir +process.chdir = function(d) { + cwd = null + chdir.call(process, d) } -balanced.range = range; -function range(a, b, str) { - var begs, beg, left, right, result; - var ai = str.indexOf(a); - var bi = str.indexOf(b, ai + 1); - var i = ai; - - if (ai >= 0 && bi > 0) { - begs = []; - left = str.length; - - while (i >= 0 && !result) { - if (i == ai) { - begs.push(i); - ai = str.indexOf(a, i + 1); - } else if (begs.length == 1) { - result = [ begs.pop(), bi ]; - } else { - beg = begs.pop(); - if (beg < left) { - left = beg; - right = bi; - } +module.exports = patch - bi = str.indexOf(b, i + 1); - } +function patch (fs) { + // (re-)implement some things that are known busted or missing. - i = ai < bi && ai >= 0 ? ai : bi; - } + // lchmod, broken prior to 0.6.2 + // back-port the fix here. + if (constants.hasOwnProperty('O_SYMLINK') && + process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { + patchLchmod(fs) + } - if (begs.length) { - result = [ left, right ]; - } + // lutimes implementation, or no-op + if (!fs.lutimes) { + patchLutimes(fs) } - return result; -} + // https://github.com/isaacs/node-graceful-fs/issues/4 + // Chown should not fail on einval or eperm if non-root. + // It should not fail on enosys ever, as this just indicates + // that a fs doesn't support the intended operation. + fs.chown = chownFix(fs.chown) + fs.fchown = chownFix(fs.fchown) + fs.lchown = chownFix(fs.lchown) -/***/ }), -/* 510 */ -/***/ (function(module, exports, __webpack_require__) { + fs.chmod = chmodFix(fs.chmod) + fs.fchmod = chmodFix(fs.fchmod) + fs.lchmod = chmodFix(fs.lchmod) -try { - var util = __webpack_require__(29); - /* istanbul ignore next */ - if (typeof util.inherits !== 'function') throw ''; - module.exports = util.inherits; -} catch (e) { - /* istanbul ignore next */ - module.exports = __webpack_require__(511); -} + fs.chownSync = chownFixSync(fs.chownSync) + fs.fchownSync = chownFixSync(fs.fchownSync) + fs.lchownSync = chownFixSync(fs.lchownSync) + fs.chmodSync = chmodFixSync(fs.chmodSync) + fs.fchmodSync = chmodFixSync(fs.fchmodSync) + fs.lchmodSync = chmodFixSync(fs.lchmodSync) -/***/ }), -/* 511 */ -/***/ (function(module, exports) { + fs.stat = statFix(fs.stat) + fs.fstat = statFix(fs.fstat) + fs.lstat = statFix(fs.lstat) -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }) + fs.statSync = statFixSync(fs.statSync) + fs.fstatSync = statFixSync(fs.fstatSync) + fs.lstatSync = statFixSync(fs.lstatSync) + + // if lchmod/lchown do not exist, then make them no-ops + if (!fs.lchmod) { + fs.lchmod = function (path, mode, cb) { + if (cb) process.nextTick(cb) } - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor + fs.lchmodSync = function () {} + } + if (!fs.lchown) { + fs.lchown = function (path, uid, gid, cb) { + if (cb) process.nextTick(cb) } + fs.lchownSync = function () {} } -} - - -/***/ }), -/* 512 */ -/***/ (function(module, exports, __webpack_require__) { -"use strict"; + // on Windows, A/V software can lock the directory, causing this + // to fail with an EACCES or EPERM if the directory contains newly + // created files. Try again on failure, for up to 60 seconds. + // Set the timeout this long because some Windows Anti-Virus, such as Parity + // bit9, may lock files for up to a minute, causing npm package install + // failures. Also, take care to yield the scheduler. Windows scheduling gives + // CPU to a busy looping process, which can cause the program causing the lock + // contention to be starved of CPU by node, so the contention doesn't resolve. + if (platform === "win32") { + fs.rename = (function (fs$rename) { return function (from, to, cb) { + var start = Date.now() + var backoff = 0; + fs$rename(from, to, function CB (er) { + if (er + && (er.code === "EACCES" || er.code === "EPERM") + && Date.now() - start < 60000) { + setTimeout(function() { + fs.stat(to, function (stater, st) { + if (stater && stater.code === "ENOENT") + fs$rename(from, to, CB); + else + cb(er) + }) + }, backoff) + if (backoff < 100) + backoff += 10; + return; + } + if (cb) cb(er) + }) + }})(fs.rename) + } -function posix(path) { - return path.charAt(0) === '/'; -} + // if read() returns EAGAIN, then just try it again. + fs.read = (function (fs$read) { + function read (fd, buffer, offset, length, position, callback_) { + var callback + if (callback_ && typeof callback_ === 'function') { + var eagCounter = 0 + callback = function (er, _, __) { + if (er && er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + } + callback_.apply(this, arguments) + } + } + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + } -function win32(path) { - // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 - var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; - var result = splitDeviceRe.exec(path); - var device = result[1] || ''; - var isUnc = Boolean(device && device.charAt(1) !== ':'); - - // UNC paths are always absolute - return Boolean(result[2] || isUnc); -} - -module.exports = process.platform === 'win32' ? win32 : posix; -module.exports.posix = posix; -module.exports.win32 = win32; + // This ensures `util.promisify` works as it does for native `fs.read`. + read.__proto__ = fs$read + return read + })(fs.read) + fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { + var eagCounter = 0 + while (true) { + try { + return fs$readSync.call(fs, fd, buffer, offset, length, position) + } catch (er) { + if (er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + continue + } + throw er + } + } + }})(fs.readSync) -/***/ }), -/* 513 */ -/***/ (function(module, exports, __webpack_require__) { + function patchLchmod (fs) { + fs.lchmod = function (path, mode, callback) { + fs.open( path + , constants.O_WRONLY | constants.O_SYMLINK + , mode + , function (err, fd) { + if (err) { + if (callback) callback(err) + return + } + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + fs.fchmod(fd, mode, function (err) { + fs.close(fd, function(err2) { + if (callback) callback(err || err2) + }) + }) + }) + } -module.exports = globSync -globSync.GlobSync = GlobSync + fs.lchmodSync = function (path, mode) { + var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) -var fs = __webpack_require__(23) -var rp = __webpack_require__(504) -var minimatch = __webpack_require__(506) -var Minimatch = minimatch.Minimatch -var Glob = __webpack_require__(503).Glob -var util = __webpack_require__(29) -var path = __webpack_require__(16) -var assert = __webpack_require__(30) -var isAbsolute = __webpack_require__(512) -var common = __webpack_require__(514) -var alphasort = common.alphasort -var alphasorti = common.alphasorti -var setopts = common.setopts -var ownProp = common.ownProp -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + var threw = true + var ret + try { + ret = fs.fchmodSync(fd, mode) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } + } + return ret + } + } -function globSync (pattern, options) { - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') + function patchLutimes (fs) { + if (constants.hasOwnProperty("O_SYMLINK")) { + fs.lutimes = function (path, at, mt, cb) { + fs.open(path, constants.O_SYMLINK, function (er, fd) { + if (er) { + if (cb) cb(er) + return + } + fs.futimes(fd, at, mt, function (er) { + fs.close(fd, function (er2) { + if (cb) cb(er || er2) + }) + }) + }) + } - return new GlobSync(pattern, options).found -} + fs.lutimesSync = function (path, at, mt) { + var fd = fs.openSync(path, constants.O_SYMLINK) + var ret + var threw = true + try { + ret = fs.futimesSync(fd, at, mt) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } + } + return ret + } -function GlobSync (pattern, options) { - if (!pattern) - throw new Error('must provide pattern') + } else { + fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } + fs.lutimesSync = function () {} + } + } - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') + function chmodFix (orig) { + if (!orig) return orig + return function (target, mode, cb) { + return orig.call(fs, target, mode, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } + } - if (!(this instanceof GlobSync)) - return new GlobSync(pattern, options) + function chmodFixSync (orig) { + if (!orig) return orig + return function (target, mode) { + try { + return orig.call(fs, target, mode) + } catch (er) { + if (!chownErOk(er)) throw er + } + } + } - setopts(this, pattern, options) - if (this.noprocess) - return this + function chownFix (orig) { + if (!orig) return orig + return function (target, uid, gid, cb) { + return orig.call(fs, target, uid, gid, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } + } - var n = this.minimatch.set.length - this.matches = new Array(n) - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false) + function chownFixSync (orig) { + if (!orig) return orig + return function (target, uid, gid) { + try { + return orig.call(fs, target, uid, gid) + } catch (er) { + if (!chownErOk(er)) throw er + } + } } - this._finish() -} -GlobSync.prototype._finish = function () { - assert(this instanceof GlobSync) - if (this.realpath) { - var self = this - this.matches.forEach(function (matchset, index) { - var set = self.matches[index] = Object.create(null) - for (var p in matchset) { - try { - p = self._makeAbs(p) - var real = rp.realpathSync(p, self.realpathCache) - set[real] = true - } catch (er) { - if (er.syscall === 'stat') - set[self._makeAbs(p)] = true - else - throw er + function statFix (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + function callback (er, stats) { + if (stats) { + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 } + if (cb) cb.apply(this, arguments) } - }) + return options ? orig.call(fs, target, options, callback) + : orig.call(fs, target, callback) + } } - common.finish(this) -} - - -GlobSync.prototype._process = function (pattern, index, inGlobStar) { - assert(this instanceof GlobSync) - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ + function statFixSync (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target, options) { + var stats = options ? orig.call(fs, target, options) + : orig.call(fs, target) + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + return stats; + } } - // now n is the index of the first one that is *not* a string. - // See if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index) - return + // ENOSYS means that the fs doesn't support the op. Just ignore + // that, because it doesn't matter. + // + // if there's no getuid, or if getuid() is something other + // than 0, and the error is EINVAL or EPERM, then just ignore + // it. + // + // This specific case is a silent failure in cp, install, tar, + // and most other unix tools that manage permissions. + // + // When running as root, or if other types of errors are + // encountered, then it's strict. + function chownErOk (er) { + if (!er) + return true - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break + if (er.code === "ENOSYS") + return true - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break + var nonroot = !process.getuid || process.getuid() !== 0 + if (nonroot) { + if (er.code === "EINVAL" || er.code === "EPERM") + return true + } + + return false } +} - var remain = pattern.slice(n) - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix +/***/ }), +/* 495 */ +/***/ (function(module, exports, __webpack_require__) { - var abs = this._makeAbs(read) +var Stream = __webpack_require__(382).Stream - //if ignored, skip processing - if (childrenIgnored(this, read)) - return +module.exports = legacy - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar) -} +function legacy (fs) { + return { + ReadStream: ReadStream, + WriteStream: WriteStream + } + function ReadStream (path, options) { + if (!(this instanceof ReadStream)) return new ReadStream(path, options); -GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { - var entries = this._readdir(abs, inGlobStar) + Stream.call(this); - // if the abs isn't a dir, then nothing can match! - if (!entries) - return + var self = this; - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' + this.path = path; + this.fd = null; + this.readable = true; + this.paused = false; - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } + this.flags = 'r'; + this.mode = 438; /*=0666*/ + this.bufferSize = 64 * 1024; - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return + options = options || {}; - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) + if (this.encoding) this.setEncoding(this.encoding); - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix.slice(-1) !== '/') - e = prefix + '/' + e - else - e = prefix + e + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.end === undefined) { + this.end = Infinity; + } else if ('number' !== typeof this.end) { + throw TypeError('end must be a Number'); } - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) + if (this.start > this.end) { + throw new Error('start must be <= end'); } - this._emitMatch(index, e) + + this.pos = this.start; } - // This was the last one, and no stats were needed - return - } - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) - newPattern = [prefix, e] - else - newPattern = [e] - this._process(newPattern.concat(remain), index, inGlobStar) - } -} + if (this.fd !== null) { + process.nextTick(function() { + self._read(); + }); + return; + } + fs.open(this.path, this.flags, this.mode, function (err, fd) { + if (err) { + self.emit('error', err); + self.readable = false; + return; + } -GlobSync.prototype._emitMatch = function (index, e) { - if (isIgnored(this, e)) - return + self.fd = fd; + self.emit('open', fd); + self._read(); + }) + } - var abs = this._makeAbs(e) + function WriteStream (path, options) { + if (!(this instanceof WriteStream)) return new WriteStream(path, options); - if (this.mark) - e = this._mark(e) + Stream.call(this); - if (this.absolute) { - e = abs - } + this.path = path; + this.fd = null; + this.writable = true; - if (this.matches[index][e]) - return + this.flags = 'w'; + this.encoding = 'binary'; + this.mode = 438; /*=0666*/ + this.bytesWritten = 0; - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } + options = options || {}; - this.matches[index][e] = true + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } - if (this.stat) - this._stat(e) -} + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.start < 0) { + throw new Error('start must be >= zero'); + } + this.pos = this.start; + } -GlobSync.prototype._readdirInGlobStar = function (abs) { - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false) + this.busy = false; + this._queue = []; - var entries - var lstat - var stat - try { - lstat = fs.lstatSync(abs) - } catch (er) { - if (er.code === 'ENOENT') { - // lstat failed, doesn't exist - return null + if (this.fd === null) { + this._open = fs.open; + this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); + this.flush(); } } +} - var isSym = lstat && lstat.isSymbolicLink() - this.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) - this.cache[abs] = 'FILE' - else - entries = this._readdir(abs, false) - return entries -} +/***/ }), +/* 496 */ +/***/ (function(module, exports, __webpack_require__) { -GlobSync.prototype._readdir = function (abs, inGlobStar) { - var entries +"use strict"; - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs) - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return null +module.exports = clone - if (Array.isArray(c)) - return c - } +function clone (obj) { + if (obj === null || typeof obj !== 'object') + return obj - try { - return this._readdirEntries(abs, fs.readdirSync(abs)) - } catch (er) { - this._readdirError(abs, er) - return null - } -} - -GlobSync.prototype._readdirEntries = function (abs, entries) { - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } + if (obj instanceof Object) + var copy = { __proto__: obj.__proto__ } + else + var copy = Object.create(null) - this.cache[abs] = entries + Object.getOwnPropertyNames(obj).forEach(function (key) { + Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) + }) - // mark and cache dir-ness - return entries + return copy } -GlobSync.prototype._readdirError = function (f, er) { - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - throw error - } - break - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break +/***/ }), +/* 497 */ +/***/ (function(module, exports, __webpack_require__) { - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) - throw er - if (!this.silent) - console.error('glob error', er) - break - } -} +var path = __webpack_require__(4); +var fs = __webpack_require__(349); +var _0777 = parseInt('0777', 8); -GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { +module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; - var entries = this._readdir(abs, inGlobStar) +function mkdirP (p, opts, f, made) { + if (typeof opts === 'function') { + f = opts; + opts = {}; + } + else if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; + } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = _0777 & (~process.umask()); + } + if (!made) made = null; + + var cb = f || function () {}; + p = path.resolve(p); + + xfs.mkdir(p, mode, function (er) { + if (!er) { + made = made || p; + return cb(null, made); + } + switch (er.code) { + case 'ENOENT': + if (path.dirname(p) === p) return cb(er); + mkdirP(path.dirname(p), opts, function (er, made) { + if (er) cb(er, made); + else mkdirP(p, opts, cb, made); + }); + break; - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + xfs.stat(p, function (er2, stat) { + // if the stat fails, then that's super weird. + // let the original error be the failure reason. + if (er2 || !stat.isDirectory()) cb(er, made) + else cb(null, made); + }); + break; + } + }); +} - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) +mkdirP.sync = function sync (p, opts, made) { + if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; + } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = _0777 & (~process.umask()); + } + if (!made) made = null; - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false) + p = path.resolve(p); - var len = entries.length - var isSym = this.symlinks[abs] + try { + xfs.mkdirSync(p, mode); + made = made || p; + } + catch (err0) { + switch (err0.code) { + case 'ENOENT' : + made = sync(path.dirname(p), opts, made); + sync(p, opts, made); + break; - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + var stat; + try { + stat = xfs.statSync(p); + } + catch (err1) { + throw err0; + } + if (!stat.isDirectory()) throw err0; + break; + } + } - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue + return made; +}; - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true) - var below = gspref.concat(entries[i], remain) - this._process(below, index, true) - } -} +/***/ }), +/* 498 */ +/***/ (function(module, exports) { -GlobSync.prototype._processSimple = function (prefix, index) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var exists = this._stat(prefix) +exports.replaceDollarWithPercentPair = replaceDollarWithPercentPair +exports.convertToSetCommand = convertToSetCommand +exports.convertToSetCommands = convertToSetCommands + +function convertToSetCommand(key, value) { + var line = "" + key = key || "" + key = key.trim() + value = value || "" + value = value.trim() + if(key && value && value.length > 0) { + line = "@SET " + key + "=" + replaceDollarWithPercentPair(value) + "\r\n" + } + return line +} + +function extractVariableValuePairs(declarations) { + var pairs = {} + declarations.map(function(declaration) { + var split = declaration.split("=") + pairs[split[0]]=split[1] + }) + return pairs +} + +function convertToSetCommands(variableString) { + var variableValuePairs = extractVariableValuePairs(variableString.split(" ")) + var variableDeclarationsAsBatch = "" + Object.keys(variableValuePairs).forEach(function (key) { + variableDeclarationsAsBatch += convertToSetCommand(key, variableValuePairs[key]) + }) + return variableDeclarationsAsBatch +} + +function replaceDollarWithPercentPair(value) { + var dollarExpressions = /\$\{?([^\$@#\?\- \t{}:]+)\}?/g + var result = "" + var startIndex = 0 + value = value || "" + do { + var match = dollarExpressions.exec(value) + if(match) { + var betweenMatches = value.substring(startIndex, match.index) || "" + result += betweenMatches + "%" + match[1] + "%" + startIndex = dollarExpressions.lastIndex + } + } while (dollarExpressions.lastIndex > 0) + result += value.substr(startIndex) + return result +} + + - if (!this.matches[index]) - this.matches[index] = Object.create(null) - // If it doesn't exist, then just mark the lack of results - if (!exists) - return +/***/ }), +/* 499 */ +/***/ (function(module, exports, __webpack_require__) { - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } +var fs = __webpack_require__(349), + path = __webpack_require__(4); - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') +module.exports = ncp; +ncp.ncp = ncp; - // Mark this as a match - this._emitMatch(index, prefix) -} +function ncp (source, dest, options, callback) { + var cback = callback; -// Returns either 'DIR', 'FILE', or false -GlobSync.prototype._stat = function (f) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' + if (!callback) { + cback = options; + options = {}; + } - if (f.length > this.maxLength) - return false + var basePath = process.cwd(), + currentPath = path.resolve(basePath, source), + targetPath = path.resolve(basePath, dest), + filter = options.filter, + rename = options.rename, + transform = options.transform, + clobber = options.clobber !== false, + modified = options.modified, + dereference = options.dereference, + errs = null, + started = 0, + finished = 0, + running = 0, + limit = options.limit || ncp.limit || 16; - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] + limit = (limit < 1) ? 1 : (limit > 512) ? 512 : limit; - if (Array.isArray(c)) - c = 'DIR' + startCopy(currentPath); + + function startCopy(source) { + started++; + if (filter) { + if (filter instanceof RegExp) { + if (!filter.test(source)) { + return cb(true); + } + } + else if (typeof filter === 'function') { + if (!filter(source)) { + return cb(true); + } + } + } + return getStats(source); + } - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return c + function getStats(source) { + var stat = dereference ? fs.stat : fs.lstat; + if (running >= limit) { + return setImmediate(function () { + getStats(source); + }); + } + running++; + stat(source, function (err, stats) { + var item = {}; + if (err) { + return onError(err); + } - if (needDir && c === 'FILE') - return false + // We need to get the mode from the stats object and preserve it. + item.name = source; + item.mode = stats.mode; + item.mtime = stats.mtime; //modified time + item.atime = stats.atime; //access time - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. + if (stats.isDirectory()) { + return onDir(item); + } + else if (stats.isFile()) { + return onFile(item); + } + else if (stats.isSymbolicLink()) { + // Symlinks don't really need to know about the mode. + return onLink(source); + } + }); } - var exists - var stat = this.statCache[abs] - if (!stat) { - var lstat - try { - lstat = fs.lstatSync(abs) - } catch (er) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return false - } + function onFile(file) { + var target = file.name.replace(currentPath, targetPath); + if(rename) { + target = rename(target); } - - if (lstat && lstat.isSymbolicLink()) { - try { - stat = fs.statSync(abs) - } catch (er) { - stat = lstat + isWritable(target, function (writable) { + if (writable) { + return copyFile(file, target); + } + if(clobber) { + rmFile(target, function () { + copyFile(file, target); + }); + } + if (modified) { + var stat = dereference ? fs.stat : fs.lstat; + stat(target, function(err, stats) { + //if souce modified time greater to target modified time copy file + if (file.mtime.getTime()>stats.mtime.getTime()) + copyFile(file, target); + else return cb(); + }); + } + else { + return cb(); } + }); + } + + function copyFile(file, target) { + var readStream = fs.createReadStream(file.name), + writeStream = fs.createWriteStream(target, { mode: file.mode }); + + readStream.on('error', onError); + writeStream.on('error', onError); + + if(transform) { + transform(readStream, writeStream, file); } else { - stat = lstat + writeStream.on('open', function() { + readStream.pipe(writeStream); + }); } + writeStream.once('finish', function() { + if (modified) { + //target file modified date sync. + fs.utimesSync(target, file.atime, file.mtime); + cb(); + } + else cb(); + }); } - this.statCache[abs] = stat - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' + function rmFile(file, done) { + fs.unlink(file, function (err) { + if (err) { + return onError(err); + } + return done(); + }); + } - this.cache[abs] = this.cache[abs] || c + function onDir(dir) { + var target = dir.name.replace(currentPath, targetPath); + isWritable(target, function (writable) { + if (writable) { + return mkDir(dir, target); + } + copyDir(dir.name); + }); + } - if (needDir && c === 'FILE') - return false + function mkDir(dir, target) { + fs.mkdir(target, dir.mode, function (err) { + if (err) { + return onError(err); + } + copyDir(dir.name); + }); + } - return c -} + function copyDir(dir) { + fs.readdir(dir, function (err, items) { + if (err) { + return onError(err); + } + items.forEach(function (item) { + startCopy(path.join(dir, item)); + }); + return cb(); + }); + } -GlobSync.prototype._mark = function (p) { - return common.mark(this, p) -} + function onLink(link) { + var target = link.replace(currentPath, targetPath); + fs.readlink(link, function (err, resolvedPath) { + if (err) { + return onError(err); + } + checkLink(resolvedPath, target); + }); + } -GlobSync.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} + function checkLink(resolvedPath, target) { + if (dereference) { + resolvedPath = path.resolve(basePath, resolvedPath); + } + isWritable(target, function (writable) { + if (writable) { + return makeLink(resolvedPath, target); + } + fs.readlink(target, function (err, targetDest) { + if (err) { + return onError(err); + } + if (dereference) { + targetDest = path.resolve(basePath, targetDest); + } + if (targetDest === resolvedPath) { + return cb(); + } + return rmFile(target, function () { + makeLink(resolvedPath, target); + }); + }); + }); + } + function makeLink(linkPath, target) { + fs.symlink(linkPath, target, function (err) { + if (err) { + return onError(err); + } + return cb(); + }); + } -/***/ }), -/* 514 */ -/***/ (function(module, exports, __webpack_require__) { - -exports.alphasort = alphasort -exports.alphasorti = alphasorti -exports.setopts = setopts -exports.ownProp = ownProp -exports.makeAbs = makeAbs -exports.finish = finish -exports.mark = mark -exports.isIgnored = isIgnored -exports.childrenIgnored = childrenIgnored - -function ownProp (obj, field) { - return Object.prototype.hasOwnProperty.call(obj, field) -} - -var path = __webpack_require__(16) -var minimatch = __webpack_require__(506) -var isAbsolute = __webpack_require__(512) -var Minimatch = minimatch.Minimatch - -function alphasorti (a, b) { - return a.toLowerCase().localeCompare(b.toLowerCase()) -} - -function alphasort (a, b) { - return a.localeCompare(b) -} - -function setupIgnores (self, options) { - self.ignore = options.ignore || [] - - if (!Array.isArray(self.ignore)) - self.ignore = [self.ignore] - - if (self.ignore.length) { - self.ignore = self.ignore.map(ignoreMap) - } -} - -// ignore patterns are always in dot:true mode. -function ignoreMap (pattern) { - var gmatcher = null - if (pattern.slice(-3) === '/**') { - var gpattern = pattern.replace(/(\/\*\*)+$/, '') - gmatcher = new Minimatch(gpattern, { dot: true }) - } - - return { - matcher: new Minimatch(pattern, { dot: true }), - gmatcher: gmatcher + function isWritable(path, done) { + fs.lstat(path, function (err) { + if (err) { + if (err.code === 'ENOENT') return done(true); + return done(false); + } + return done(false); + }); } -} - -function setopts (self, pattern, options) { - if (!options) - options = {} - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") + function onError(err) { + if (options.stopOnError) { + return cback(err); } - pattern = "**/" + pattern - } - - self.silent = !!options.silent - self.pattern = pattern - self.strict = options.strict !== false - self.realpath = !!options.realpath - self.realpathCache = options.realpathCache || Object.create(null) - self.follow = !!options.follow - self.dot = !!options.dot - self.mark = !!options.mark - self.nodir = !!options.nodir - if (self.nodir) - self.mark = true - self.sync = !!options.sync - self.nounique = !!options.nounique - self.nonull = !!options.nonull - self.nosort = !!options.nosort - self.nocase = !!options.nocase - self.stat = !!options.stat - self.noprocess = !!options.noprocess - self.absolute = !!options.absolute - - self.maxLength = options.maxLength || Infinity - self.cache = options.cache || Object.create(null) - self.statCache = options.statCache || Object.create(null) - self.symlinks = options.symlinks || Object.create(null) - - setupIgnores(self, options) - - self.changedCwd = false - var cwd = process.cwd() - if (!ownProp(options, "cwd")) - self.cwd = cwd - else { - self.cwd = path.resolve(options.cwd) - self.changedCwd = self.cwd !== cwd - } - - self.root = options.root || path.resolve(self.cwd, "/") - self.root = path.resolve(self.root) - if (process.platform === "win32") - self.root = self.root.replace(/\\/g, "/") - - // TODO: is an absolute `cwd` supposed to be resolved against `root`? - // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') - self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) - if (process.platform === "win32") - self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") - self.nomount = !!options.nomount - - // disable comments and negation in Minimatch. - // Note that they are not supported in Glob itself anyway. - options.nonegate = true - options.nocomment = true - - self.minimatch = new Minimatch(pattern, options) - self.options = self.minimatch.options -} - -function finish (self) { - var nou = self.nounique - var all = nou ? [] : Object.create(null) - - for (var i = 0, l = self.matches.length; i < l; i ++) { - var matches = self.matches[i] - if (!matches || Object.keys(matches).length === 0) { - if (self.nonull) { - // do like the shell, and spit out the literal glob - var literal = self.minimatch.globSet[i] - if (nou) - all.push(literal) - else - all[literal] = true - } - } else { - // had matches - var m = Object.keys(matches) - if (nou) - all.push.apply(all, m) - else - m.forEach(function (m) { - all[m] = true - }) + else if (!errs && options.errs) { + errs = fs.createWriteStream(options.errs); } - } - - if (!nou) - all = Object.keys(all) - - if (!self.nosort) - all = all.sort(self.nocase ? alphasorti : alphasort) - - // at *some* point we statted all of these - if (self.mark) { - for (var i = 0; i < all.length; i++) { - all[i] = self._mark(all[i]) + else if (!errs) { + errs = []; } - if (self.nodir) { - all = all.filter(function (e) { - var notDir = !(/\/$/.test(e)) - var c = self.cache[e] || self.cache[makeAbs(self, e)] - if (notDir && c) - notDir = c !== 'DIR' && !Array.isArray(c) - return notDir - }) + if (typeof errs.write === 'undefined') { + errs.push(err); } + else { + errs.write(err.stack + '\n\n'); + } + return cb(); } - if (self.ignore.length) - all = all.filter(function(m) { - return !isIgnored(self, m) - }) - - self.found = all -} - -function mark (self, p) { - var abs = makeAbs(self, p) - var c = self.cache[abs] - var m = p - if (c) { - var isDir = c === 'DIR' || Array.isArray(c) - var slash = p.slice(-1) === '/' - - if (isDir && !slash) - m += '/' - else if (!isDir && slash) - m = m.slice(0, -1) - - if (m !== p) { - var mabs = makeAbs(self, m) - self.statCache[mabs] = self.statCache[abs] - self.cache[mabs] = self.cache[abs] + function cb(skipped) { + if (!skipped) running--; + finished++; + if ((started === finished) && (running === 0)) { + if (cback !== undefined ) { + return errs ? cback(errs) : cback(null); + } } } - - return m } -// lotta situps... -function makeAbs (self, f) { - var abs = f - if (f.charAt(0) === '/') { - abs = path.join(self.root, f) - } else if (isAbsolute(f) || f === '') { - abs = f - } else if (self.changedCwd) { - abs = path.resolve(self.cwd, f) - } else { - abs = path.resolve(f) - } - - if (process.platform === 'win32') - abs = abs.replace(/\\/g, '/') - return abs -} -// Return true, if pattern ends with globstar '**', for the accompanying parent directory. -// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents -function isIgnored (self, path) { - if (!self.ignore.length) - return false +/***/ }), +/* 500 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - return self.ignore.some(function(item) { - return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) - }) -} +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "log", function() { return log; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Log", function() { return Log; }); +/* harmony import */ var _kbn_dev_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5); +/* harmony import */ var _kbn_dev_utils__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_kbn_dev_utils__WEBPACK_IMPORTED_MODULE_0__); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LogLevel", function() { return _kbn_dev_utils__WEBPACK_IMPORTED_MODULE_0__["LogLevel"]; }); -function childrenIgnored (self, path) { - if (!self.ignore.length) - return false +function _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; } - return self.ignore.some(function(item) { - return !!(item.gmatcher && item.gmatcher.match(path)) - }) -} +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -/***/ }), -/* 515 */ -/***/ (function(module, exports, __webpack_require__) { +class Log extends _kbn_dev_utils__WEBPACK_IMPORTED_MODULE_0__["ToolingLog"] { + constructor() { + super(); -var wrappy = __webpack_require__(405) -var reqs = Object.create(null) -var once = __webpack_require__(404) + _defineProperty(this, "logLevel", void 0); -module.exports = wrappy(inflight) + this.setLogLevel('info'); + } -function inflight (key, cb) { - if (reqs[key]) { - reqs[key].push(cb) - return null - } else { - reqs[key] = [cb] - return makeres(key) + setLogLevel(level) { + this.logLevel = Object(_kbn_dev_utils__WEBPACK_IMPORTED_MODULE_0__["parseLogLevel"])(level); + this.setWriters([new _kbn_dev_utils__WEBPACK_IMPORTED_MODULE_0__["ToolingLogTextWriter"]({ + level: this.logLevel.name, + writeTo: process.stdout + })]); } -} -function makeres (key) { - return once(function RES () { - var cbs = reqs[key] - var len = cbs.length - var args = slice(arguments) + wouldLogLevel(level) { + return this.logLevel.flags[level]; + } - // XXX It's somewhat ambiguous whether a new callback added in this - // pass should be queued for later execution if something in the - // list of callbacks throws, or if it should just be discarded. - // However, it's such an edge case that it hardly matters, and either - // choice is likely as surprising as the other. - // As it happens, we do go ahead and schedule it for later execution. - try { - for (var i = 0; i < len; i++) { - cbs[i].apply(null, args) - } - } finally { - if (cbs.length > len) { - // added more in the interim. - // de-zalgo, just in case, but don't call again. - cbs.splice(0, len) - process.nextTick(function () { - RES.apply(null, args) - }) - } else { - delete reqs[key] - } - } - }) } -function slice (args) { - var length = args.length - var array = [] - - for (var i = 0; i < length; i++) array[i] = args[i] - return array -} +const log = new Log(); /***/ }), -/* 516 */ +/* 501 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CliError", function() { return CliError; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parallelizeBatches", function() { return parallelizeBatches; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parallelize", function() { return parallelize; }); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -47570,39 +44042,65 @@ __webpack_require__.r(__webpack_exports__); * specific language governing permissions and limitations * under the License. */ -class CliError extends Error { - constructor(message, meta = {}) { - super(message); - this.meta = meta; +async function parallelizeBatches(batches, fn) { + for (const batch of batches) { + // We need to make sure the entire batch has completed before we can move on + // to the next batch + await parallelize(batch, fn); + } +} +async function parallelize(items, fn, concurrency = 4) { + if (items.length === 0) { + return; } + return new Promise((resolve, reject) => { + let activePromises = 0; + const values = items.slice(0); + + async function scheduleItem(item) { + activePromises++; + + try { + await fn(item); + activePromises--; + + if (values.length > 0) { + // We have more work to do, so we schedule the next promise + scheduleItem(values.shift()); + } else if (activePromises === 0) { + // We have no more values left, and all items have completed, so we've + // completed all the work. + resolve(); + } + } catch (error) { + reject(error); + } + } + + values.splice(0, concurrency).map(scheduleItem); + }); } /***/ }), -/* 517 */ +/* 502 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Project", function() { return Project; }); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(23); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(16); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(29); -/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(516); -/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(34); -/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(518); -/* harmony import */ var _scripts__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(563); -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; } - -function _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; } - -function _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; } - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getProjects", function() { return getProjects; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buildProjectGraph", function() { return buildProjectGraph; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "topologicallyBatchProjects", function() { return topologicallyBatchProjects; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "includeTransitiveProjects", function() { return includeTransitiveProjects; }); +/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(503); +/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(glob__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(397); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(516); +/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(517); +/* harmony import */ var _workspaces__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(573); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -47627,6243 +44125,8760 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope +const glob = Object(util__WEBPACK_IMPORTED_MODULE_2__["promisify"])(glob__WEBPACK_IMPORTED_MODULE_0___default.a); +/** a Map of project names to Project instances */ +async function getProjects(rootPath, projectsPathsPatterns, { + include = [], + exclude = [] +} = {}) { + const projects = new Map(); + const workspaceProjectsPaths = await Object(_workspaces__WEBPACK_IMPORTED_MODULE_5__["workspacePackagePaths"])(rootPath); -class Project { - static async fromPath(path) { - const pkgJson = await Object(_package_json__WEBPACK_IMPORTED_MODULE_6__["readPackageJson"])(path); - return new Project(pkgJson, path); - } - /** parsed package.json */ + for (const pattern of projectsPathsPatterns) { + const pathsToProcess = await packagesFromGlobPattern({ + pattern, + rootPath + }); + for (const filePath of pathsToProcess) { + const projectConfigPath = normalize(filePath); + const projectDir = path__WEBPACK_IMPORTED_MODULE_1___default.a.dirname(projectConfigPath); + const project = await _project__WEBPACK_IMPORTED_MODULE_4__["Project"].fromPath(projectDir); - constructor(packageJson, projectPath) { - _defineProperty(this, "json", void 0); + if (workspaceProjectsPaths.indexOf(filePath) >= 0) { + project.isWorkspaceProject = true; + } - _defineProperty(this, "packageJsonLocation", void 0); + const excludeProject = exclude.includes(project.name) || include.length > 0 && !include.includes(project.name); - _defineProperty(this, "nodeModulesLocation", void 0); + if (excludeProject) { + continue; + } - _defineProperty(this, "targetLocation", void 0); + if (projects.has(project.name)) { + throw new _errors__WEBPACK_IMPORTED_MODULE_3__["CliError"](`There are multiple projects with the same name [${project.name}]`, { + name: project.name, + paths: [project.path, projects.get(project.name).path] + }); + } - _defineProperty(this, "path", void 0); + projects.set(project.name, project); + } + } - _defineProperty(this, "version", void 0); + return projects; +} - _defineProperty(this, "allDependencies", void 0); +function packagesFromGlobPattern({ + pattern, + rootPath +}) { + const globOptions = { + cwd: rootPath, + // Should throw in case of unusual errors when reading the file system + strict: true, + // Always returns absolute paths for matched files + absolute: true, + // Do not match ** against multiple filenames + // (This is only specified because we currently don't have a need for it.) + noglobstar: true + }; + return glob(path__WEBPACK_IMPORTED_MODULE_1___default.a.join(pattern, 'package.json'), globOptions); +} // https://github.com/isaacs/node-glob/blob/master/common.js#L104 +// glob always returns "\\" as "/" in windows, so everyone +// gets normalized because we can't have nice things. - _defineProperty(this, "productionDependencies", void 0); - _defineProperty(this, "devDependencies", void 0); +function normalize(dir) { + return path__WEBPACK_IMPORTED_MODULE_1___default.a.normalize(dir); +} - _defineProperty(this, "scripts", void 0); +function buildProjectGraph(projects) { + const projectGraph = new Map(); - _defineProperty(this, "isWorkspaceRoot", false); + for (const project of projects.values()) { + const projectDeps = []; + const dependencies = project.allDependencies; - _defineProperty(this, "isWorkspaceProject", false); + for (const depName of Object.keys(dependencies)) { + if (projects.has(depName)) { + const dep = projects.get(depName); + const dependentProjectIsInWorkspace = project.isWorkspaceProject || project.json.name === 'kibana'; + project.ensureValidProjectDependency(dep, dependentProjectIsInWorkspace); + projectDeps.push(dep); + } + } - this.json = Object.freeze(packageJson); - this.path = projectPath; - this.packageJsonLocation = path__WEBPACK_IMPORTED_MODULE_2___default.a.resolve(this.path, 'package.json'); - this.nodeModulesLocation = path__WEBPACK_IMPORTED_MODULE_2___default.a.resolve(this.path, 'node_modules'); - this.targetLocation = path__WEBPACK_IMPORTED_MODULE_2___default.a.resolve(this.path, 'target'); - this.version = this.json.version; - this.productionDependencies = this.json.dependencies || {}; - this.devDependencies = this.json.devDependencies || {}; - this.allDependencies = _objectSpread({}, this.devDependencies, {}, this.productionDependencies); - this.isWorkspaceRoot = this.json.hasOwnProperty('workspaces'); - this.scripts = this.json.scripts || {}; + projectGraph.set(project.name, projectDeps); } - get name() { - return this.json.name; - } + return projectGraph; +} +function topologicallyBatchProjects(projectsToBatch, projectGraph, { + batchByWorkspace = false +} = {}) { + // We're going to be chopping stuff out of this list, so copy it. + const projectsLeftToBatch = new Set(projectsToBatch.keys()); + const batches = []; - ensureValidProjectDependency(project, dependentProjectIsInWorkspace) { - const versionInPackageJson = this.allDependencies[project.name]; - let expectedVersionInPackageJson; + if (batchByWorkspace) { + const workspaceRootProject = Array.from(projectsToBatch.values()).find(p => p.isWorkspaceRoot); - if (dependentProjectIsInWorkspace) { - expectedVersionInPackageJson = project.json.version; - } else { - const relativePathToProject = normalizePath(path__WEBPACK_IMPORTED_MODULE_2___default.a.relative(this.path, project.path)); - expectedVersionInPackageJson = `link:${relativePathToProject}`; - } // No issues! + if (!workspaceRootProject) { + throw new _errors__WEBPACK_IMPORTED_MODULE_3__["CliError"](`There was no yarn workspace root found.`); + } // Push in the workspace root first. - if (versionInPackageJson === expectedVersionInPackageJson) { - return; - } + batches.push([workspaceRootProject]); + projectsLeftToBatch.delete(workspaceRootProject.name); // In the next batch, push in all workspace projects. - let problemMsg; + const workspaceBatch = []; - if (Object(_package_json__WEBPACK_IMPORTED_MODULE_6__["isLinkDependency"])(versionInPackageJson) && dependentProjectIsInWorkspace) { - problemMsg = `but should be using a workspace`; - } else if (Object(_package_json__WEBPACK_IMPORTED_MODULE_6__["isLinkDependency"])(versionInPackageJson)) { - problemMsg = `using 'link:', but the path is wrong`; - } else { - problemMsg = `but it's not using the local package`; - } + for (const projectName of projectsLeftToBatch) { + const project = projectsToBatch.get(projectName); - throw new _errors__WEBPACK_IMPORTED_MODULE_4__["CliError"](`[${this.name}] depends on [${project.name}] ${problemMsg}. Update its package.json to the expected value below.`, { - actual: `"${project.name}": "${versionInPackageJson}"`, - expected: `"${project.name}": "${expectedVersionInPackageJson}"`, - package: `${this.name} (${this.packageJsonLocation})` - }); - } + if (project.isWorkspaceProject) { + workspaceBatch.push(project); + projectsLeftToBatch.delete(projectName); + } + } - getBuildConfig() { - return this.json.kibana && this.json.kibana.build || {}; + batches.push(workspaceBatch); } - /** - * Returns the directory that should be copied into the Kibana build artifact. - * This config can be specified to only include the project's build artifacts - * instead of everything located in the project directory. - */ + while (projectsLeftToBatch.size > 0) { + // Get all projects that have no remaining dependencies within the repo + // that haven't yet been picked. + const batch = []; - getIntermediateBuildDirectory() { - return path__WEBPACK_IMPORTED_MODULE_2___default.a.resolve(this.path, this.getBuildConfig().intermediateBuildDirectory || '.'); - } - - getCleanConfig() { - return this.json.kibana && this.json.kibana.clean || {}; - } + for (const projectName of projectsLeftToBatch) { + const projectDeps = projectGraph.get(projectName); + const needsDependenciesBatched = projectDeps.some(dep => projectsLeftToBatch.has(dep.name)); - hasScript(name) { - return name in this.scripts; - } + if (!needsDependenciesBatched) { + batch.push(projectsToBatch.get(projectName)); + } + } // If we weren't able to find a project with no remaining dependencies, + // then we've encountered a cycle in the dependency graph. - getExecutables() { - const raw = this.json.bin; - if (!raw) { - return {}; - } + const hasCycles = batch.length === 0; - if (typeof raw === 'string') { - return { - [this.name]: path__WEBPACK_IMPORTED_MODULE_2___default.a.resolve(this.path, raw) - }; + if (hasCycles) { + const cycleProjectNames = [...projectsLeftToBatch]; + const message = 'Encountered a cycle in the dependency graph. Projects in cycle are:\n' + cycleProjectNames.join(', '); + throw new _errors__WEBPACK_IMPORTED_MODULE_3__["CliError"](message); } - if (typeof raw === 'object') { - const binsConfig = {}; + batches.push(batch); + batch.forEach(project => projectsLeftToBatch.delete(project.name)); + } - for (const binName of Object.keys(raw)) { - binsConfig[binName] = path__WEBPACK_IMPORTED_MODULE_2___default.a.resolve(this.path, raw[binName]); - } + return batches; +} +function includeTransitiveProjects(subsetOfProjects, allProjects, { + onlyProductionDependencies = false +} = {}) { + const projectsWithDependents = new Map(); // the current list of packages we are expanding using breadth-first-search - return binsConfig; - } + const toProcess = [...subsetOfProjects]; - throw new _errors__WEBPACK_IMPORTED_MODULE_4__["CliError"](`[${this.name}] has an invalid "bin" field in its package.json, ` + `expected an object or a string`, { - binConfig: Object(util__WEBPACK_IMPORTED_MODULE_3__["inspect"])(raw), - package: `${this.name} (${this.packageJsonLocation})` + while (toProcess.length > 0) { + const project = toProcess.shift(); + const dependencies = onlyProductionDependencies ? project.productionDependencies : project.allDependencies; + Object.keys(dependencies).forEach(dep => { + if (allProjects.has(dep)) { + toProcess.push(allProjects.get(dep)); + } }); + projectsWithDependents.set(project.name, project); } - async runScript(scriptName, args = []) { - _log__WEBPACK_IMPORTED_MODULE_5__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold(`\n\nRunning script [${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(scriptName)}] in [${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(this.name)}]:\n`)); - return Object(_scripts__WEBPACK_IMPORTED_MODULE_7__["runScriptInPackage"])(scriptName, args, this); - } - - runScriptStreaming(scriptName, args = []) { - return Object(_scripts__WEBPACK_IMPORTED_MODULE_7__["runScriptInPackageStreaming"])(scriptName, args, this); - } - - hasDependencies() { - return Object.keys(this.allDependencies).length > 0; - } + return projectsWithDependents; +} - async installDependencies({ - extraArgs - }) { - _log__WEBPACK_IMPORTED_MODULE_5__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold(`\n\nInstalling dependencies in [${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(this.name)}]:\n`)); - await Object(_scripts__WEBPACK_IMPORTED_MODULE_7__["installInDir"])(this.path, extraArgs); - await this.removeExtraneousNodeModules(); - } - /** - * Yarn workspaces symlinks workspace projects to the root node_modules, even - * when there is no depenency on the project. This results in unnecicary, and - * often duplicated code in the build archives. - */ +/***/ }), +/* 503 */ +/***/ (function(module, exports, __webpack_require__) { +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. - async removeExtraneousNodeModules() { - // this is only relevant for the root workspace - if (!this.isWorkspaceRoot) { - return; - } +module.exports = glob - const workspacesInfo = await Object(_scripts__WEBPACK_IMPORTED_MODULE_7__["yarnWorkspacesInfo"])(this.path); - const unusedWorkspaces = new Set(Object.keys(workspacesInfo)); // check for any cross-project dependency +var fs = __webpack_require__(349) +var rp = __webpack_require__(504) +var minimatch = __webpack_require__(506) +var Minimatch = minimatch.Minimatch +var inherits = __webpack_require__(510) +var EE = __webpack_require__(373).EventEmitter +var path = __webpack_require__(4) +var assert = __webpack_require__(371) +var isAbsolute = __webpack_require__(512) +var globSync = __webpack_require__(513) +var common = __webpack_require__(514) +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = __webpack_require__(515) +var util = __webpack_require__(397) +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored - for (const name of Object.keys(workspacesInfo)) { - const workspace = workspacesInfo[name]; - workspace.workspaceDependencies.forEach(w => unusedWorkspaces.delete(w)); - } +var once = __webpack_require__(378) - unusedWorkspaces.forEach(name => { - const { - dependencies, - devDependencies - } = this.json; - const nodeModulesPath = path__WEBPACK_IMPORTED_MODULE_2___default.a.resolve(this.nodeModulesLocation, name); - const isDependency = dependencies && dependencies.hasOwnProperty(name); - const isDevDependency = devDependencies && devDependencies.hasOwnProperty(name); +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} - if (!isDependency && !isDevDependency && fs__WEBPACK_IMPORTED_MODULE_1___default.a.existsSync(nodeModulesPath)) { - _log__WEBPACK_IMPORTED_MODULE_5__["log"].write(`No dependency on ${name}, removing link in node_modules`); - fs__WEBPACK_IMPORTED_MODULE_1___default.a.unlinkSync(nodeModulesPath); - } - }); + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) } -} // We normalize all path separators to `/` in generated files - -function normalizePath(path) { - return path.replace(/[\\\/]+/g, '/'); + return new Glob(pattern, options, cb) } -/***/ }), -/* 518 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readPackageJson", function() { return readPackageJson; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "writePackageJson", function() { return writePackageJson; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isLinkDependency", function() { return isLinkDependency; }); -/* harmony import */ var read_pkg__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(519); -/* harmony import */ var read_pkg__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(read_pkg__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var write_pkg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(545); -/* harmony import */ var write_pkg__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(write_pkg__WEBPACK_IMPORTED_MODULE_1__); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +// old api surface +glob.glob = glob +function extend (origin, add) { + if (add === null || typeof add !== 'object') { + return origin + } -function readPackageJson(cwd) { - return read_pkg__WEBPACK_IMPORTED_MODULE_0___default()({ - cwd, - normalize: false - }); -} -function writePackageJson(path, json) { - return write_pkg__WEBPACK_IMPORTED_MODULE_1___default()(path, json); + var keys = Object.keys(add) + var i = keys.length + while (i--) { + origin[keys[i]] = add[keys[i]] + } + return origin } -const isLinkDependency = depVersion => depVersion.startsWith('link:'); - -/***/ }), -/* 519 */ -/***/ (function(module, exports, __webpack_require__) { -"use strict"; +glob.hasMagic = function (pattern, options_) { + var options = extend({}, options_) + options.noprocess = true -const {promisify} = __webpack_require__(29); -const fs = __webpack_require__(23); -const path = __webpack_require__(16); -const parseJson = __webpack_require__(520); + var g = new Glob(pattern, options) + var set = g.minimatch.set -const readFileAsync = promisify(fs.readFile); + if (!pattern) + return false -module.exports = async options => { - options = { - cwd: process.cwd(), - normalize: true, - ...options - }; + if (set.length > 1) + return true - const filePath = path.resolve(options.cwd, 'package.json'); - const json = parseJson(await readFileAsync(filePath, 'utf8')); + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } - if (options.normalize) { - __webpack_require__(521)(json); - } + return false +} - return json; -}; +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } -module.exports.sync = options => { - options = { - cwd: process.cwd(), - normalize: true, - ...options - }; + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } - const filePath = path.resolve(options.cwd, 'package.json'); - const json = parseJson(fs.readFileSync(filePath, 'utf8')); + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) - if (options.normalize) { - __webpack_require__(521)(json); - } + setopts(this, pattern, options) + this._didRealPath = false - return json; -}; + // process each pattern in the minimatch set + var n = this.minimatch.set.length + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) -/***/ }), -/* 520 */ -/***/ (function(module, exports, __webpack_require__) { + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } -"use strict"; + var self = this + this._processing = 0 -const errorEx = __webpack_require__(429); -const fallback = __webpack_require__(431); -const {default: LinesAndColumns} = __webpack_require__(432); -const {codeFrameColumns} = __webpack_require__(433); + this._emitQueue = [] + this._processQueue = [] + this.paused = false -const JSONError = errorEx('JSONError', { - fileName: errorEx.append('in %s'), - codeFrame: errorEx.append('\n\n%s\n') -}); + if (this.noprocess) + return this -module.exports = (string, reviver, filename) => { - if (typeof reviver === 'string') { - filename = reviver; - reviver = null; - } + if (n === 0) + return done() - try { - try { - return JSON.parse(string, reviver); - } catch (error) { - fallback(string, reviver); - throw error; - } - } catch (error) { - error.message = error.message.replace(/\n/g, ''); - const indexMatch = error.message.match(/in JSON at position (\d+) while parsing near/); + var sync = true + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + sync = false - const jsonError = new JSONError(error); - if (filename) { - jsonError.fileName = filename; - } + function done () { + --self._processing + if (self._processing <= 0) { + if (sync) { + process.nextTick(function () { + self._finish() + }) + } else { + self._finish() + } + } + } +} - if (indexMatch && indexMatch.length > 0) { - const lines = new LinesAndColumns(string); - const index = Number(indexMatch[1]); - const location = lines.locationForIndex(index); +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return - const codeFrame = codeFrameColumns( - string, - {start: {line: location.line + 1, column: location.column + 1}}, - {highlightCode: true} - ); + if (this.realpath && !this._didRealpath) + return this._realpath() - jsonError.codeFrame = codeFrame; - } + common.finish(this) + this.emit('end', this.found) +} - throw jsonError; - } -}; +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + this._didRealpath = true -/***/ }), -/* 521 */ -/***/ (function(module, exports, __webpack_require__) { + var n = this.matches.length + if (n === 0) + return this._finish() -module.exports = normalize + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) -var fixer = __webpack_require__(522) -normalize.fixer = fixer + function next () { + if (--n === 0) + self._finish() + } +} -var makeWarning = __webpack_require__(543) +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() -var fieldsToFix = ['name','version','description','repository','modules','scripts' - ,'files','bin','man','bugs','keywords','readme','homepage','license'] -var otherThingsToFix = ['dependencies','people', 'typos'] + var found = Object.keys(matchset) + var self = this + var n = found.length -var thingsToFix = fieldsToFix.map(function(fieldName) { - return ucFirst(fieldName) + "Field" -}) -// two ways to do this in CoffeeScript on only one line, sub-70 chars: -// thingsToFix = fieldsToFix.map (name) -> ucFirst(name) + "Field" -// thingsToFix = (ucFirst(name) + "Field" for name in fieldsToFix) -thingsToFix = thingsToFix.concat(otherThingsToFix) + if (n === 0) + return cb() -function normalize (data, warn, strict) { - if(warn === true) warn = null, strict = true - if(!strict) strict = false - if(!warn || data.private) warn = function(msg) { /* noop */ } + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + rp.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here - if (data.scripts && - data.scripts.install === "node-gyp rebuild" && - !data.scripts.preinstall) { - data.gypfile = true - } - fixer.warn = function() { warn(makeWarning.apply(null, arguments)) } - thingsToFix.forEach(function(thingName) { - fixer["fix" + ucFirst(thingName)](data, strict) + if (--n === 0) { + self.matches[index] = set + cb() + } + }) }) - data._id = data.name + "@" + data.version } -function ucFirst (string) { - return string.charAt(0).toUpperCase() + string.slice(1); +Glob.prototype._mark = function (p) { + return common.mark(this, p) } +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} -/***/ }), -/* 522 */ -/***/ (function(module, exports, __webpack_require__) { +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} -var semver = __webpack_require__(523) -var validateLicense = __webpack_require__(524); -var hostedGitInfo = __webpack_require__(529) -var isBuiltinModule = __webpack_require__(532).isCore -var depTypes = ["dependencies","devDependencies","optionalDependencies"] -var extractDescription = __webpack_require__(541) -var url = __webpack_require__(452) -var typos = __webpack_require__(542) +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} -var fixer = module.exports = { - // default warning function - warn: function() {}, - - fixRepositoryField: function(data) { - if (data.repositories) { - this.warn("repositories"); - data.repository = data.repositories[0] - } - if (!data.repository) return this.warn("missingRepository") - if (typeof data.repository === "string") { - data.repository = { - type: "git", - url: data.repository +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) } } - var r = data.repository.url || "" - if (r) { - var hosted = hostedGitInfo.fromUrl(r) - if (hosted) { - r = data.repository.url - = hosted.getDefaultRepresentation() == "shortcut" ? hosted.https() : hosted.toString() + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) } } + } +} - if (r.match(/github.com\/[^\/]+\/[^\/]+\.git\.git$/)) { - this.warn("brokenGitUrl", r) - } +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return } -, fixTypos: function(data) { - Object.keys(typos.topLevel).forEach(function (d) { - if (data.hasOwnProperty(d)) { - this.warn("typo", d, typos.topLevel[d]) - } - }, this) + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ } + // now n is the index of the first one that is *not* a string. -, fixScriptsField: function(data) { - if (!data.scripts) return - if (typeof data.scripts !== "object") { - this.warn("nonObjectScripts") - delete data.scripts + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) return - } - Object.keys(data.scripts).forEach(function (k) { - if (typeof data.scripts[k] !== "string") { - this.warn("nonStringScript") - delete data.scripts[k] - } else if (typos.script[k] && !data.scripts[typos.script[k]]) { - this.warn("typo", k, typos.script[k], "scripts") - } - }, this) - } -, fixFilesField: function(data) { - var files = data.files - if (files && !Array.isArray(files)) { - this.warn("nonArrayFiles") - delete data.files - } else if (data.files) { - data.files = data.files.filter(function(file) { - if (!file || typeof file !== "string") { - this.warn("invalidFilename", file) - return false - } else { - return true - } - }, this) - } + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break } -, fixBinField: function(data) { - if (!data.bin) return; - if (typeof data.bin === "string") { - var b = {} - var match - if (match = data.name.match(/^@[^/]+[/](.*)$/)) { - b[match[1]] = data.bin + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) } else { - b[data.name] = data.bin + m = e.match(pn) } - data.bin = b + if (m) + matchedEntries.push(e) } } -, fixManField: function(data) { - if (!data.man) return; - if (typeof data.man === "string") { - data.man = [ data.man ] - } - } -, fixBundleDependenciesField: function(data) { - var bdd = "bundledDependencies" - var bd = "bundleDependencies" - if (data[bdd] && !data[bd]) { - data[bd] = data[bdd] - delete data[bdd] - } - if (data[bd] && !Array.isArray(data[bd])) { - this.warn("nonArrayBundleDependencies") - delete data[bd] - } else if (data[bd]) { - data[bd] = data[bd].filter(function(bd) { - if (!bd || typeof bd !== 'string') { - this.warn("nonStringBundleDependency", bd) - return false - } else { - if (!data.dependencies) { - data.dependencies = {} - } - if (!data.dependencies.hasOwnProperty(bd)) { - this.warn("nonDependencyBundleDependency", bd) - data.dependencies[bd] = "*" - } - return true - } - }, this) - } - } + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) -, fixDependencies: function(data, strict) { - var loose = !strict - objectifyDeps(data, this.warn) - addOptionalDepsToDeps(data, this.warn) - this.fixBundleDependenciesField(data) + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() - ;['dependencies','devDependencies'].forEach(function(deps) { - if (!(deps in data)) return - if (!data[deps] || typeof data[deps] !== "object") { - this.warn("nonObjectDependencies", deps) - delete data[deps] - return + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e } - Object.keys(data[deps]).forEach(function (d) { - var r = data[deps][d] - if (typeof r !== 'string') { - this.warn("nonStringDependency", d, JSON.stringify(r)) - delete data[deps][d] - } - var hosted = hostedGitInfo.fromUrl(data[deps][d]) - if (hosted) data[deps][d] = hosted.toString() - }, this) - }, this) - } -, fixModulesField: function (data) { - if (data.modules) { - this.warn("deprecatedModules") - delete data.modules + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) } + // This was the last one, and no stats were needed + return cb() } -, fixKeywordsField: function (data) { - if (typeof data.keywords === "string") { - data.keywords = data.keywords.split(/,\s+/) - } - if (data.keywords && !Array.isArray(data.keywords)) { - delete data.keywords - this.warn("nonArrayKeywords") - } else if (data.keywords) { - data.keywords = data.keywords.filter(function(kw) { - if (typeof kw !== "string" || !kw) { - this.warn("nonStringKeyword"); - return false - } else { - return true - } - }, this) + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e } + this._process([e].concat(remain), index, inGlobStar, cb) } + cb() +} -, fixVersionField: function(data, strict) { - // allow "loose" semver 1.0 versions in non-strict mode - // enforce strict semver 2.0 compliance in strict mode - var loose = !strict - if (!data.version) { - data.version = "" - return true - } - if (!semver.valid(data.version, loose)) { - throw new Error('Invalid version: "'+ data.version + '"') - } - data.version = semver.clean(data.version, loose) - return true - } +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return -, fixPeople: function(data) { - modifyPeople(data, unParsePerson) - modifyPeople(data, parsePerson) - } + if (isIgnored(this, e)) + return -, fixNameField: function(data, options) { - if (typeof options === "boolean") options = {strict: options} - else if (typeof options === "undefined") options = {} - var strict = options.strict - if (!data.name && !strict) { - data.name = "" - return - } - if (typeof data.name !== "string") { - throw new Error("name field must be a string.") - } - if (!strict) - data.name = data.name.trim() - ensureValidName(data.name, strict, options.allowLegacyCase) - if (isBuiltinModule(data.name)) - this.warn("conflictingName", data.name) + if (this.paused) { + this._emitQueue.push([index, e]) + return } + var abs = isAbsolute(e) ? e : this._makeAbs(e) -, fixDescriptionField: function (data) { - if (data.description && typeof data.description !== 'string') { - this.warn("nonStringDescription") - delete data.description - } - if (data.readme && !data.description) - data.description = extractDescription(data.readme) - if(data.description === undefined) delete data.description; - if (!data.description) this.warn("missingDescription") - } + if (this.mark) + e = this._mark(e) -, fixReadmeField: function (data) { - if (!data.readme) { - this.warn("missingReadme") - data.readme = "ERROR: No README data found!" - } - } + if (this.absolute) + e = abs -, fixBugsField: function(data) { - if (!data.bugs && data.repository && data.repository.url) { - var hosted = hostedGitInfo.fromUrl(data.repository.url) - if(hosted && hosted.bugs()) { - data.bugs = {url: hosted.bugs()} - } - } - else if(data.bugs) { - var emailRe = /^.+@.*\..+$/ - if(typeof data.bugs == "string") { - if(emailRe.test(data.bugs)) - data.bugs = {email:data.bugs} - else if(url.parse(data.bugs).protocol) - data.bugs = {url: data.bugs} - else - this.warn("nonEmailUrlBugsString") - } - else { - bugsTypos(data.bugs, this.warn) - var oldBugs = data.bugs - data.bugs = {} - if(oldBugs.url) { - if(typeof(oldBugs.url) == "string" && url.parse(oldBugs.url).protocol) - data.bugs.url = oldBugs.url - else - this.warn("nonUrlBugsUrlField") - } - if(oldBugs.email) { - if(typeof(oldBugs.email) == "string" && emailRe.test(oldBugs.email)) - data.bugs.email = oldBugs.email - else - this.warn("nonEmailBugsEmailField") - } - } - if(!data.bugs.email && !data.bugs.url) { - delete data.bugs - this.warn("emptyNormalizedBugs") - } - } + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return } -, fixHomepageField: function(data) { - if (!data.homepage && data.repository && data.repository.url) { - var hosted = hostedGitInfo.fromUrl(data.repository.url) - if (hosted && hosted.docs()) data.homepage = hosted.docs() - } - if (!data.homepage) return + this.matches[index][e] = true - if(typeof data.homepage !== "string") { - this.warn("nonUrlHomepage") - return delete data.homepage - } - if(!url.parse(data.homepage).protocol) { - data.homepage = "http://" + data.homepage - } - } + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) -, fixLicenseField: function(data) { - if (!data.license) { - return this.warn("missingLicense") - } else{ - if ( - typeof(data.license) !== 'string' || - data.license.length < 1 || - data.license.trim() === '' - ) { - this.warn("invalidLicense") - } else { - if (!validateLicense(data.license).validForNewPackages) - this.warn("invalidLicense") - } - } - } + this.emit('match', e) } -function isValidScopedPackageName(spec) { - if (spec.charAt(0) !== '@') return false +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return - var rest = spec.slice(1).split('/') - if (rest.length !== 2) return false + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) - return rest[0] && rest[1] && - rest[0] === encodeURIComponent(rest[0]) && - rest[1] === encodeURIComponent(rest[1]) -} + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) -function isCorrectlyEncodedName(spec) { - return !spec.match(/[\/@\s\+%:]/) && - spec === encodeURIComponent(spec) -} + if (lstatcb) + fs.lstat(abs, lstatcb) -function ensureValidName (name, strict, allowLegacyCase) { - if (name.charAt(0) === "." || - !(isValidScopedPackageName(name) || isCorrectlyEncodedName(name)) || - (strict && (!allowLegacyCase) && name !== name.toLowerCase()) || - name.toLowerCase() === "node_modules" || - name.toLowerCase() === "favicon.ico") { - throw new Error("Invalid name: " + JSON.stringify(name)) + function lstatcb_ (er, lstat) { + if (er && er.code === 'ENOENT') + return cb() + + var isSym = lstat && lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) } } -function modifyPeople (data, fn) { - if (data.author) data.author = fn(data.author) - ;["maintainers", "contributors"].forEach(function (set) { - if (!Array.isArray(data[set])) return; - data[set] = data[set].map(fn) - }) - return data -} +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return -function unParsePerson (person) { - if (typeof person === "string") return person - var name = person.name || "" - var u = person.url || person.web - var url = u ? (" ("+u+")") : "" - var e = person.email || person.mail - var email = e ? (" <"+e+">") : "" - return name+email+url -} + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return -function parsePerson (person) { - if (typeof person !== "string") return person - var name = person.match(/^([^\(<]+)/) - var url = person.match(/\(([^\)]+)\)/) - var email = person.match(/<([^>]+)>/) - var obj = {} - if (name && name[0].trim()) obj.name = name[0].trim() - if (email) obj.email = email[1]; - if (url) obj.url = url[1]; - return obj -} + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) -function addOptionalDepsToDeps (data, warn) { - var o = data.optionalDependencies - if (!o) return; - var d = data.dependencies || {} - Object.keys(o).forEach(function (k) { - d[k] = o[k] - }) - data.dependencies = d -} + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() -function depObjectify (deps, type, warn) { - if (!deps) return {} - if (typeof deps === "string") { - deps = deps.trim().split(/[\n\r\s\t ,]+/) + if (Array.isArray(c)) + return cb(null, c) } - if (!Array.isArray(deps)) return deps - warn("deprecatedArrayDependencies", type) - var o = {} - deps.filter(function (d) { - return typeof d === "string" - }).forEach(function(d) { - d = d.trim().split(/(:?[@\s><=])/) - var dn = d.shift() - var dv = d.join("") - dv = dv.trim() - dv = dv.replace(/^@/, "") - o[dn] = dv - }) - return o -} -function objectifyDeps (data, warn) { - depTypes.forEach(function (type) { - if (!data[type]) return; - data[type] = depObjectify(data[type], type, warn) - }) + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) } -function bugsTypos(bugs, warn) { - if (!bugs) return - Object.keys(bugs).forEach(function (k) { - if (typos.bugs[k]) { - warn("typo", k, typos.bugs[k], "bugs") - bugs[typos.bugs[k]] = bugs[k] - delete bugs[k] - } - }) +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } } +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return -/***/ }), -/* 523 */ -/***/ (function(module, exports) { - -exports = module.exports = SemVer - -var debug -/* istanbul ignore next */ -if (typeof process === 'object' && - process.env && - process.env.NODE_DEBUG && - /\bsemver\b/i.test(process.env.NODE_DEBUG)) { - debug = function () { - var args = Array.prototype.slice.call(arguments, 0) - args.unshift('SEMVER') - console.log.apply(console, args) + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } } -} else { - debug = function () {} -} -// Note: this is the semver.org version of the spec that it implements -// Not necessarily the package version of this code. -exports.SEMVER_SPEC_VERSION = '2.0.0' + this.cache[abs] = entries + return cb(null, entries) +} -var MAX_LENGTH = 256 -var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || - /* istanbul ignore next */ 9007199254740991 +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return -// Max safe segment length for coercion. -var MAX_SAFE_COMPONENT_LENGTH = 16 + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + this.emit('error', error) + this.abort() + } + break -// The actual regexps go on exports.re -var re = exports.re = [] -var src = exports.src = [] -var R = 0 + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break -// The following Regular Expressions can be used for tokenizing, -// validating, and parsing SemVer version strings. + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } -// ## Numeric Identifier -// A single `0`, or a non-zero digit followed by zero or more digits. + return cb() +} -var NUMERICIDENTIFIER = R++ -src[NUMERICIDENTIFIER] = '0|[1-9]\\d*' -var NUMERICIDENTIFIERLOOSE = R++ -src[NUMERICIDENTIFIERLOOSE] = '[0-9]+' +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} -// ## Non-numeric Identifier -// Zero or more digits, followed by a letter or hyphen, and then zero or -// more letters, digits, or hyphens. -var NONNUMERICIDENTIFIER = R++ -src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*' +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) -// ## Main Version -// Three dot-separated numeric identifiers. + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() -var MAINVERSION = R++ -src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + - '(' + src[NUMERICIDENTIFIER] + ')\\.' + - '(' + src[NUMERICIDENTIFIER] + ')' + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) -var MAINVERSIONLOOSE = R++ -src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + - '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + - '(' + src[NUMERICIDENTIFIERLOOSE] + ')' + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) -// ## Pre-release Version Identifier -// A numeric identifier, or a non-numeric identifier. + var isSym = this.symlinks[abs] + var len = entries.length -var PRERELEASEIDENTIFIER = R++ -src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + - '|' + src[NONNUMERICIDENTIFIER] + ')' + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() -var PRERELEASEIDENTIFIERLOOSE = R++ -src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + - '|' + src[NONNUMERICIDENTIFIER] + ')' + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue -// ## Pre-release Version -// Hyphen, followed by one or more dot-separated pre-release version -// identifiers. + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) -var PRERELEASE = R++ -src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + - '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))' + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } -var PRERELEASELOOSE = R++ -src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + - '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))' + cb() +} -// ## Build Metadata Identifier -// Any combination of digits, letters, or hyphens. +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { -var BUILDIDENTIFIER = R++ -src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+' + //console.error('ps2', prefix, exists) -// ## Build Metadata -// Plus sign, followed by one or more period-separated build metadata -// identifiers. + if (!this.matches[index]) + this.matches[index] = Object.create(null) -var BUILD = R++ -src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + - '(?:\\.' + src[BUILDIDENTIFIER] + ')*))' + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() -// ## Full Version String -// A main version, followed optionally by a pre-release version and -// build metadata. + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } -// Note that the only major, minor, patch, and pre-release sections of -// the version string are capturing groups. The build metadata is not a -// capturing group, because it should not ever be used in version -// comparison. + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') -var FULL = R++ -var FULLPLAIN = 'v?' + src[MAINVERSION] + - src[PRERELEASE] + '?' + - src[BUILD] + '?' + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} -src[FULL] = '^' + FULLPLAIN + '$' +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' -// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. -// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty -// common in the npm registry. -var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + - src[PRERELEASELOOSE] + '?' + - src[BUILD] + '?' + if (f.length > this.maxLength) + return cb() -var LOOSE = R++ -src[LOOSE] = '^' + LOOSEPLAIN + '$' + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] -var GTLT = R++ -src[GTLT] = '((?:<|>)?=?)' + if (Array.isArray(c)) + c = 'DIR' -// Something like "2.*" or "1.2.x". -// Note that "x.x" is a valid xRange identifer, meaning "any version" -// Only the first item is strictly required. -var XRANGEIDENTIFIERLOOSE = R++ -src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*' -var XRANGEIDENTIFIER = R++ -src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*' + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) -var XRANGEPLAIN = R++ -src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + - '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + - '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + - '(?:' + src[PRERELEASE] + ')?' + - src[BUILD] + '?' + - ')?)?' + if (needDir && c === 'FILE') + return cb() -var XRANGEPLAINLOOSE = R++ -src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + - '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + - '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + - '(?:' + src[PRERELEASELOOSE] + ')?' + - src[BUILD] + '?' + - ')?)?' + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } -var XRANGE = R++ -src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$' -var XRANGELOOSE = R++ -src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$' + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } -// Coercion. -// Extract anything that could conceivably be a part of a valid semver -var COERCE = R++ -src[COERCE] = '(?:^|[^\\d])' + - '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + - '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + - '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + - '(?:$|[^\\d])' + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) -// Tilde ranges. -// Meaning is "reasonably at or greater than" -var LONETILDE = R++ -src[LONETILDE] = '(?:~>?)' + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} -var TILDETRIM = R++ -src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+' -re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g') -var tildeTrimReplace = '$1~' +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return cb() + } -var TILDE = R++ -src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$' -var TILDELOOSE = R++ -src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$' + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat -// Caret ranges. -// Meaning is "at least and backwards compatible with" -var LONECARET = R++ -src[LONECARET] = '(?:\\^)' + if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) + return cb(null, false, stat) -var CARETTRIM = R++ -src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+' -re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g') -var caretTrimReplace = '$1^' + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c -var CARET = R++ -src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$' -var CARETLOOSE = R++ -src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$' + if (needDir && c === 'FILE') + return cb() -// A simple gt/lt/eq thing, or just "" to indicate "any version" -var COMPARATORLOOSE = R++ -src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$' -var COMPARATOR = R++ -src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$' + return cb(null, c, stat) +} -// An expression to strip any whitespace between the gtlt and the thing -// it modifies, so that `> 1.2.3` ==> `>1.2.3` -var COMPARATORTRIM = R++ -src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + - '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')' -// this one has to use the /g flag -re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g') -var comparatorTrimReplace = '$1$2$3' +/***/ }), +/* 504 */ +/***/ (function(module, exports, __webpack_require__) { -// Something like `1.2.3 - 1.2.4` -// Note that these all use the loose form, because they'll be -// checked against either the strict or loose comparator form -// later. -var HYPHENRANGE = R++ -src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + - '\\s+-\\s+' + - '(' + src[XRANGEPLAIN] + ')' + - '\\s*$' +module.exports = realpath +realpath.realpath = realpath +realpath.sync = realpathSync +realpath.realpathSync = realpathSync +realpath.monkeypatch = monkeypatch +realpath.unmonkeypatch = unmonkeypatch -var HYPHENRANGELOOSE = R++ -src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + - '\\s+-\\s+' + - '(' + src[XRANGEPLAINLOOSE] + ')' + - '\\s*$' +var fs = __webpack_require__(349) +var origRealpath = fs.realpath +var origRealpathSync = fs.realpathSync -// Star ranges basically just allow anything at all. -var STAR = R++ -src[STAR] = '(<|>)?=?\\s*\\*' +var version = process.version +var ok = /^v[0-5]\./.test(version) +var old = __webpack_require__(505) -// Compile to actual regexp objects. -// All are flag-free, unless they were created above with a flag. -for (var i = 0; i < R; i++) { - debug(i, src[i]) - if (!re[i]) { - re[i] = new RegExp(src[i]) - } +function newError (er) { + return er && er.syscall === 'realpath' && ( + er.code === 'ELOOP' || + er.code === 'ENOMEM' || + er.code === 'ENAMETOOLONG' + ) } -exports.parse = parse -function parse (version, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } - - if (version instanceof SemVer) { - return version - } - - if (typeof version !== 'string') { - return null +function realpath (p, cache, cb) { + if (ok) { + return origRealpath(p, cache, cb) } - if (version.length > MAX_LENGTH) { - return null + if (typeof cache === 'function') { + cb = cache + cache = null } + origRealpath(p, cache, function (er, result) { + if (newError(er)) { + old.realpath(p, cache, cb) + } else { + cb(er, result) + } + }) +} - var r = options.loose ? re[LOOSE] : re[FULL] - if (!r.test(version)) { - return null +function realpathSync (p, cache) { + if (ok) { + return origRealpathSync(p, cache) } try { - return new SemVer(version, options) + return origRealpathSync(p, cache) } catch (er) { - return null + if (newError(er)) { + return old.realpathSync(p, cache) + } else { + throw er + } } } -exports.valid = valid -function valid (version, options) { - var v = parse(version, options) - return v ? v.version : null +function monkeypatch () { + fs.realpath = realpath + fs.realpathSync = realpathSync } -exports.clean = clean -function clean (version, options) { - var s = parse(version.trim().replace(/^[=v]+/, ''), options) - return s ? s.version : null +function unmonkeypatch () { + fs.realpath = origRealpath + fs.realpathSync = origRealpathSync } -exports.SemVer = SemVer - -function SemVer (version, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } - if (version instanceof SemVer) { - if (version.loose === options.loose) { - return version - } else { - version = version.version - } - } else if (typeof version !== 'string') { - throw new TypeError('Invalid Version: ' + version) - } - - if (version.length > MAX_LENGTH) { - throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') - } - - if (!(this instanceof SemVer)) { - return new SemVer(version, options) - } - debug('SemVer', version, options) - this.options = options - this.loose = !!options.loose +/***/ }), +/* 505 */ +/***/ (function(module, exports, __webpack_require__) { - var m = version.trim().match(options.loose ? re[LOOSE] : re[FULL]) +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - if (!m) { - throw new TypeError('Invalid Version: ' + version) - } +var pathModule = __webpack_require__(4); +var isWindows = process.platform === 'win32'; +var fs = __webpack_require__(349); - this.raw = version +// JavaScript implementation of realpath, ported from node pre-v6 - // these are actually numbers - this.major = +m[1] - this.minor = +m[2] - this.patch = +m[3] +var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); - if (this.major > MAX_SAFE_INTEGER || this.major < 0) { - throw new TypeError('Invalid major version') - } +function rethrow() { + // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and + // is fairly slow to generate. + var callback; + if (DEBUG) { + var backtrace = new Error; + callback = debugCallback; + } else + callback = missingCallback; - if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { - throw new TypeError('Invalid minor version') - } + return callback; - if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { - throw new TypeError('Invalid patch version') + function debugCallback(err) { + if (err) { + backtrace.message = err.message; + err = backtrace; + missingCallback(err); + } } - // numberify any prerelease numeric ids - if (!m[4]) { - this.prerelease = [] - } else { - this.prerelease = m[4].split('.').map(function (id) { - if (/^[0-9]+$/.test(id)) { - var num = +id - if (num >= 0 && num < MAX_SAFE_INTEGER) { - return num - } + function missingCallback(err) { + if (err) { + if (process.throwDeprecation) + throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs + else if (!process.noDeprecation) { + var msg = 'fs: missing callback ' + (err.stack || err.message); + if (process.traceDeprecation) + console.trace(msg); + else + console.error(msg); } - return id - }) + } } +} - this.build = m[5] ? m[5].split('.') : [] - this.format() +function maybeCallback(cb) { + return typeof cb === 'function' ? cb : rethrow(); } -SemVer.prototype.format = function () { - this.version = this.major + '.' + this.minor + '.' + this.patch - if (this.prerelease.length) { - this.version += '-' + this.prerelease.join('.') - } - return this.version +var normalize = pathModule.normalize; + +// Regexp that finds the next partion of a (partial) path +// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] +if (isWindows) { + var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; +} else { + var nextPartRe = /(.*?)(?:[\/]+|$)/g; } -SemVer.prototype.toString = function () { - return this.version +// Regex to find the device root, including trailing slash. E.g. 'c:\\'. +if (isWindows) { + var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; +} else { + var splitRootRe = /^[\/]*/; } -SemVer.prototype.compare = function (other) { - debug('SemVer.compare', this.version, this.options, other) - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options) +exports.realpathSync = function realpathSync(p, cache) { + // make p is absolute + p = pathModule.resolve(p); + + if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { + return cache[p]; } - return this.compareMain(other) || this.comparePre(other) -} + var original = p, + seenLinks = {}, + knownHard = {}; -SemVer.prototype.compareMain = function (other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options) - } + // current character position in p + var pos; + // the partial path so far, including a trailing slash if any + var current; + // the partial path without a trailing slash (except when pointing at a root) + var base; + // the partial path scanned in the previous round, with slash + var previous; - return compareIdentifiers(this.major, other.major) || - compareIdentifiers(this.minor, other.minor) || - compareIdentifiers(this.patch, other.patch) -} + start(); -SemVer.prototype.comparePre = function (other) { - if (!(other instanceof SemVer)) { - other = new SemVer(other, this.options) - } + function start() { + // Skip over roots + var m = splitRootRe.exec(p); + pos = m[0].length; + current = m[0]; + base = m[0]; + previous = ''; - // NOT having a prerelease is > having one - if (this.prerelease.length && !other.prerelease.length) { - return -1 - } else if (!this.prerelease.length && other.prerelease.length) { - return 1 - } else if (!this.prerelease.length && !other.prerelease.length) { - return 0 + // On windows, check that the root exists. On unix there is no need. + if (isWindows && !knownHard[base]) { + fs.lstatSync(base); + knownHard[base] = true; + } } - var i = 0 - do { - var a = this.prerelease[i] - var b = other.prerelease[i] - debug('prerelease compare', i, a, b) - if (a === undefined && b === undefined) { - return 0 - } else if (b === undefined) { - return 1 - } else if (a === undefined) { - return -1 - } else if (a === b) { - continue - } else { - return compareIdentifiers(a, b) + // walk down the path, swapping out linked pathparts for their real + // values + // NB: p.length changes. + while (pos < p.length) { + // find the next part + nextPartRe.lastIndex = pos; + var result = nextPartRe.exec(p); + previous = current; + current += result[0]; + base = previous + result[1]; + pos = nextPartRe.lastIndex; + + // continue if not a symlink + if (knownHard[base] || (cache && cache[base] === base)) { + continue; } - } while (++i) -} -// preminor will bump the version up to the next minor release, and immediately -// down to pre-release. premajor and prepatch work the same way. -SemVer.prototype.inc = function (release, identifier) { - switch (release) { - case 'premajor': - this.prerelease.length = 0 - this.patch = 0 - this.minor = 0 - this.major++ - this.inc('pre', identifier) - break - case 'preminor': - this.prerelease.length = 0 - this.patch = 0 - this.minor++ - this.inc('pre', identifier) - break - case 'prepatch': - // If this is already a prerelease, it will bump to the next version - // drop any prereleases that might already exist, since they are not - // relevant at this point. - this.prerelease.length = 0 - this.inc('patch', identifier) - this.inc('pre', identifier) - break - // If the input is a non-prerelease version, this acts the same as - // prepatch. - case 'prerelease': - if (this.prerelease.length === 0) { - this.inc('patch', identifier) + var resolvedLink; + if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { + // some known symbolic link. no need to stat again. + resolvedLink = cache[base]; + } else { + var stat = fs.lstatSync(base); + if (!stat.isSymbolicLink()) { + knownHard[base] = true; + if (cache) cache[base] = base; + continue; } - this.inc('pre', identifier) - break - case 'major': - // If this is a pre-major version, bump up to the same major version. - // Otherwise increment major. - // 1.0.0-5 bumps to 1.0.0 - // 1.1.0 bumps to 2.0.0 - if (this.minor !== 0 || - this.patch !== 0 || - this.prerelease.length === 0) { - this.major++ - } - this.minor = 0 - this.patch = 0 - this.prerelease = [] - break - case 'minor': - // If this is a pre-minor version, bump up to the same minor version. - // Otherwise increment minor. - // 1.2.0-5 bumps to 1.2.0 - // 1.2.1 bumps to 1.3.0 - if (this.patch !== 0 || this.prerelease.length === 0) { - this.minor++ - } - this.patch = 0 - this.prerelease = [] - break - case 'patch': - // If this is not a pre-release version, it will increment the patch. - // If it is a pre-release it will bump up to the same patch version. - // 1.2.0-5 patches to 1.2.0 - // 1.2.0 patches to 1.2.1 - if (this.prerelease.length === 0) { - this.patch++ - } - this.prerelease = [] - break - // This probably shouldn't be used publicly. - // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. - case 'pre': - if (this.prerelease.length === 0) { - this.prerelease = [0] - } else { - var i = this.prerelease.length - while (--i >= 0) { - if (typeof this.prerelease[i] === 'number') { - this.prerelease[i]++ - i = -2 - } - } - if (i === -1) { - // didn't increment anything - this.prerelease.push(0) + // read the link if it wasn't read before + // dev/ino always return 0 on windows, so skip the check. + var linkTarget = null; + if (!isWindows) { + var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); + if (seenLinks.hasOwnProperty(id)) { + linkTarget = seenLinks[id]; } } - if (identifier) { - // 1.2.0-beta.1 bumps to 1.2.0-beta.2, - // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 - if (this.prerelease[0] === identifier) { - if (isNaN(this.prerelease[1])) { - this.prerelease = [identifier, 0] - } - } else { - this.prerelease = [identifier, 0] - } + if (linkTarget === null) { + fs.statSync(base); + linkTarget = fs.readlinkSync(base); } - break + resolvedLink = pathModule.resolve(previous, linkTarget); + // track this, if given a cache. + if (cache) cache[base] = resolvedLink; + if (!isWindows) seenLinks[id] = linkTarget; + } - default: - throw new Error('invalid increment argument: ' + release) + // resolve the link, then start over + p = pathModule.resolve(resolvedLink, p.slice(pos)); + start(); } - this.format() - this.raw = this.version - return this -} -exports.inc = inc -function inc (version, release, loose, identifier) { - if (typeof (loose) === 'string') { - identifier = loose - loose = undefined - } + if (cache) cache[original] = p; - try { - return new SemVer(version, loose).inc(release, identifier).version - } catch (er) { - return null - } -} + return p; +}; -exports.diff = diff -function diff (version1, version2) { - if (eq(version1, version2)) { - return null - } else { - var v1 = parse(version1) - var v2 = parse(version2) - var prefix = '' - if (v1.prerelease.length || v2.prerelease.length) { - prefix = 'pre' - var defaultResult = 'prerelease' - } - for (var key in v1) { - if (key === 'major' || key === 'minor' || key === 'patch') { - if (v1[key] !== v2[key]) { - return prefix + key - } - } - } - return defaultResult // may be undefined - } -} -exports.compareIdentifiers = compareIdentifiers +exports.realpath = function realpath(p, cache, cb) { + if (typeof cb !== 'function') { + cb = maybeCallback(cache); + cache = null; + } -var numeric = /^[0-9]+$/ -function compareIdentifiers (a, b) { - var anum = numeric.test(a) - var bnum = numeric.test(b) + // make p is absolute + p = pathModule.resolve(p); - if (anum && bnum) { - a = +a - b = +b + if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { + return process.nextTick(cb.bind(null, null, cache[p])); } - return a === b ? 0 - : (anum && !bnum) ? -1 - : (bnum && !anum) ? 1 - : a < b ? -1 - : 1 -} + var original = p, + seenLinks = {}, + knownHard = {}; -exports.rcompareIdentifiers = rcompareIdentifiers -function rcompareIdentifiers (a, b) { - return compareIdentifiers(b, a) -} + // current character position in p + var pos; + // the partial path so far, including a trailing slash if any + var current; + // the partial path without a trailing slash (except when pointing at a root) + var base; + // the partial path scanned in the previous round, with slash + var previous; -exports.major = major -function major (a, loose) { - return new SemVer(a, loose).major -} + start(); -exports.minor = minor -function minor (a, loose) { - return new SemVer(a, loose).minor -} + function start() { + // Skip over roots + var m = splitRootRe.exec(p); + pos = m[0].length; + current = m[0]; + base = m[0]; + previous = ''; -exports.patch = patch -function patch (a, loose) { - return new SemVer(a, loose).patch -} + // On windows, check that the root exists. On unix there is no need. + if (isWindows && !knownHard[base]) { + fs.lstat(base, function(err) { + if (err) return cb(err); + knownHard[base] = true; + LOOP(); + }); + } else { + process.nextTick(LOOP); + } + } -exports.compare = compare -function compare (a, b, loose) { - return new SemVer(a, loose).compare(new SemVer(b, loose)) -} + // walk down the path, swapping out linked pathparts for their real + // values + function LOOP() { + // stop if scanned past end of path + if (pos >= p.length) { + if (cache) cache[original] = p; + return cb(null, p); + } -exports.compareLoose = compareLoose -function compareLoose (a, b) { - return compare(a, b, true) -} + // find the next part + nextPartRe.lastIndex = pos; + var result = nextPartRe.exec(p); + previous = current; + current += result[0]; + base = previous + result[1]; + pos = nextPartRe.lastIndex; -exports.rcompare = rcompare -function rcompare (a, b, loose) { - return compare(b, a, loose) -} + // continue if not a symlink + if (knownHard[base] || (cache && cache[base] === base)) { + return process.nextTick(LOOP); + } -exports.sort = sort -function sort (list, loose) { - return list.sort(function (a, b) { - return exports.compare(a, b, loose) - }) -} - -exports.rsort = rsort -function rsort (list, loose) { - return list.sort(function (a, b) { - return exports.rcompare(a, b, loose) - }) -} - -exports.gt = gt -function gt (a, b, loose) { - return compare(a, b, loose) > 0 -} + if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { + // known symbolic link. no need to stat again. + return gotResolvedLink(cache[base]); + } -exports.lt = lt -function lt (a, b, loose) { - return compare(a, b, loose) < 0 -} + return fs.lstat(base, gotStat); + } -exports.eq = eq -function eq (a, b, loose) { - return compare(a, b, loose) === 0 -} + function gotStat(err, stat) { + if (err) return cb(err); -exports.neq = neq -function neq (a, b, loose) { - return compare(a, b, loose) !== 0 -} + // if not a symlink, skip to the next path part + if (!stat.isSymbolicLink()) { + knownHard[base] = true; + if (cache) cache[base] = base; + return process.nextTick(LOOP); + } -exports.gte = gte -function gte (a, b, loose) { - return compare(a, b, loose) >= 0 -} + // stat & read the link if not read before + // call gotTarget as soon as the link target is known + // dev/ino always return 0 on windows, so skip the check. + if (!isWindows) { + var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); + if (seenLinks.hasOwnProperty(id)) { + return gotTarget(null, seenLinks[id], base); + } + } + fs.stat(base, function(err) { + if (err) return cb(err); -exports.lte = lte -function lte (a, b, loose) { - return compare(a, b, loose) <= 0 -} + fs.readlink(base, function(err, target) { + if (!isWindows) seenLinks[id] = target; + gotTarget(err, target); + }); + }); + } -exports.cmp = cmp -function cmp (a, op, b, loose) { - switch (op) { - case '===': - if (typeof a === 'object') - a = a.version - if (typeof b === 'object') - b = b.version - return a === b + function gotTarget(err, target, base) { + if (err) return cb(err); - case '!==': - if (typeof a === 'object') - a = a.version - if (typeof b === 'object') - b = b.version - return a !== b + var resolvedLink = pathModule.resolve(previous, target); + if (cache) cache[base] = resolvedLink; + gotResolvedLink(resolvedLink); + } - case '': - case '=': - case '==': - return eq(a, b, loose) + function gotResolvedLink(resolvedLink) { + // resolve the link, then start over + p = pathModule.resolve(resolvedLink, p.slice(pos)); + start(); + } +}; - case '!=': - return neq(a, b, loose) - case '>': - return gt(a, b, loose) +/***/ }), +/* 506 */ +/***/ (function(module, exports, __webpack_require__) { - case '>=': - return gte(a, b, loose) +module.exports = minimatch +minimatch.Minimatch = Minimatch - case '<': - return lt(a, b, loose) +var path = { sep: '/' } +try { + path = __webpack_require__(4) +} catch (er) {} - case '<=': - return lte(a, b, loose) +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} +var expand = __webpack_require__(507) - default: - throw new TypeError('Invalid operator: ' + op) - } +var plTypes = { + '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, + '?': { open: '(?:', close: ')?' }, + '+': { open: '(?:', close: ')+' }, + '*': { open: '(?:', close: ')*' }, + '@': { open: '(?:', close: ')' } } -exports.Comparator = Comparator -function Comparator (comp, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } - } +// any single thing other than / +// don't need to escape / when using new RegExp() +var qmark = '[^/]' - if (comp instanceof Comparator) { - if (comp.loose === !!options.loose) { - return comp - } else { - comp = comp.value - } - } +// * => any number of characters +var star = qmark + '*?' - if (!(this instanceof Comparator)) { - return new Comparator(comp, options) - } +// ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' - debug('comparator', comp, options) - this.options = options - this.loose = !!options.loose - this.parse(comp) +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' - if (this.semver === ANY) { - this.value = '' - } else { - this.value = this.operator + this.semver.version - } +// characters that need to be escaped in RegExp. +var reSpecials = charSet('().*{}+?[]^$\\!') - debug('comp', this) +// "abc" -> { a:true, b:true, c:true } +function charSet (s) { + return s.split('').reduce(function (set, c) { + set[c] = true + return set + }, {}) } -var ANY = {} -Comparator.prototype.parse = function (comp) { - var r = this.options.loose ? re[COMPARATORLOOSE] : re[COMPARATOR] - var m = comp.match(r) - - if (!m) { - throw new TypeError('Invalid comparator: ' + comp) - } - - this.operator = m[1] - if (this.operator === '=') { - this.operator = '' - } +// normalizes slashes. +var slashSplit = /\/+/ - // if it literally is just '>' or '' then allow anything. - if (!m[2]) { - this.semver = ANY - } else { - this.semver = new SemVer(m[2], this.options.loose) +minimatch.filter = filter +function filter (pattern, options) { + options = options || {} + return function (p, i, list) { + return minimatch(p, pattern, options) } } -Comparator.prototype.toString = function () { - return this.value +function ext (a, b) { + a = a || {} + b = b || {} + var t = {} + Object.keys(b).forEach(function (k) { + t[k] = b[k] + }) + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) + return t } -Comparator.prototype.test = function (version) { - debug('Comparator.test', version, this.options.loose) +minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch - if (this.semver === ANY) { - return true + var orig = minimatch + + var m = function minimatch (p, pattern, options) { + return orig.minimatch(p, pattern, ext(def, options)) } - if (typeof version === 'string') { - version = new SemVer(version, this.options) + m.Minimatch = function Minimatch (pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)) } - return cmp(version, this.operator, this.semver, this.options) + return m } -Comparator.prototype.intersects = function (comp, options) { - if (!(comp instanceof Comparator)) { - throw new TypeError('a Comparator is required') - } +Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch + return minimatch.defaults(def).Minimatch +} - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } +function minimatch (p, pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') } - var rangeTmp + if (!options) options = {} - if (this.operator === '') { - rangeTmp = new Range(comp.value, options) - return satisfies(this.value, rangeTmp, options) - } else if (comp.operator === '') { - rangeTmp = new Range(this.value, options) - return satisfies(comp.semver, rangeTmp, options) + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false } - var sameDirectionIncreasing = - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '>=' || comp.operator === '>') - var sameDirectionDecreasing = - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '<=' || comp.operator === '<') - var sameSemVer = this.semver.version === comp.semver.version - var differentDirectionsInclusive = - (this.operator === '>=' || this.operator === '<=') && - (comp.operator === '>=' || comp.operator === '<=') - var oppositeDirectionsLessThan = - cmp(this.semver, '<', comp.semver, options) && - ((this.operator === '>=' || this.operator === '>') && - (comp.operator === '<=' || comp.operator === '<')) - var oppositeDirectionsGreaterThan = - cmp(this.semver, '>', comp.semver, options) && - ((this.operator === '<=' || this.operator === '<') && - (comp.operator === '>=' || comp.operator === '>')) + // "" only matches "" + if (pattern.trim() === '') return p === '' - return sameDirectionIncreasing || sameDirectionDecreasing || - (sameSemVer && differentDirectionsInclusive) || - oppositeDirectionsLessThan || oppositeDirectionsGreaterThan + return new Minimatch(pattern, options).match(p) } -exports.Range = Range -function Range (range, options) { - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - } +function Minimatch (pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options) } - if (range instanceof Range) { - if (range.loose === !!options.loose && - range.includePrerelease === !!options.includePrerelease) { - return range - } else { - return new Range(range.raw, options) - } + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') } - if (range instanceof Comparator) { - return new Range(range.value, options) - } + if (!options) options = {} + pattern = pattern.trim() - if (!(this instanceof Range)) { - return new Range(range, options) + // windows support: need to use /, not \ + if (path.sep !== '/') { + pattern = pattern.split(path.sep).join('/') } this.options = options - this.loose = !!options.loose - this.includePrerelease = !!options.includePrerelease - - // First, split based on boolean or || - this.raw = range - this.set = range.split(/\s*\|\|\s*/).map(function (range) { - return this.parseRange(range.trim()) - }, this).filter(function (c) { - // throw out any that are not relevant for whatever reason - return c.length - }) - - if (!this.set.length) { - throw new TypeError('Invalid SemVer Range: ' + range) - } + this.set = [] + this.pattern = pattern + this.regexp = null + this.negate = false + this.comment = false + this.empty = false - this.format() + // make the set of regexps etc. + this.make() } -Range.prototype.format = function () { - this.range = this.set.map(function (comps) { - return comps.join(' ').trim() - }).join('||').trim() - return this.range -} +Minimatch.prototype.debug = function () {} -Range.prototype.toString = function () { - return this.range -} +Minimatch.prototype.make = make +function make () { + // don't do it more than once. + if (this._made) return -Range.prototype.parseRange = function (range) { - var loose = this.options.loose - range = range.trim() - // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` - var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE] - range = range.replace(hr, hyphenReplace) - debug('hyphen replace', range) - // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` - range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace) - debug('comparator trim', range, re[COMPARATORTRIM]) + var pattern = this.pattern + var options = this.options - // `~ 1.2.3` => `~1.2.3` - range = range.replace(re[TILDETRIM], tildeTrimReplace) + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true + return + } + if (!pattern) { + this.empty = true + return + } - // `^ 1.2.3` => `^1.2.3` - range = range.replace(re[CARETTRIM], caretTrimReplace) + // step 1: figure out negation, etc. + this.parseNegate() - // normalize spaces - range = range.split(/\s+/).join(' ') + // step 2: expand braces + var set = this.globSet = this.braceExpand() - // At this point, the range is completely trimmed and - // ready to be split into comparators. + if (options.debug) this.debug = console.error - var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR] - var set = range.split(' ').map(function (comp) { - return parseComparator(comp, this.options) - }, this).join(' ').split(/\s+/) - if (this.options.loose) { - // in loose mode, throw out any that are not valid comparators - set = set.filter(function (comp) { - return !!comp.match(compRe) - }) - } - set = set.map(function (comp) { - return new Comparator(comp, this.options) - }, this) + this.debug(this.pattern, set) - return set -} + // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit) + }) -Range.prototype.intersects = function (range, options) { - if (!(range instanceof Range)) { - throw new TypeError('a Range is required') - } + this.debug(this.pattern, set) - return this.set.some(function (thisComparators) { - return thisComparators.every(function (thisComparator) { - return range.set.some(function (rangeComparators) { - return rangeComparators.every(function (rangeComparator) { - return thisComparator.intersects(rangeComparator, options) - }) - }) - }) - }) -} + // glob --> regexps + set = set.map(function (s, si, set) { + return s.map(this.parse, this) + }, this) -// Mostly just for testing and legacy API reasons -exports.toComparators = toComparators -function toComparators (range, options) { - return new Range(range, options).set.map(function (comp) { - return comp.map(function (c) { - return c.value - }).join(' ').trim().split(' ') + this.debug(this.pattern, set) + + // filter out everything that didn't compile properly. + set = set.filter(function (s) { + return s.indexOf(false) === -1 }) -} -// comprised of xranges, tildes, stars, and gtlt's at this point. -// already replaced the hyphen ranges -// turn into a set of JUST comparators. -function parseComparator (comp, options) { - debug('comp', comp, options) - comp = replaceCarets(comp, options) - debug('caret', comp) - comp = replaceTildes(comp, options) - debug('tildes', comp) - comp = replaceXRanges(comp, options) - debug('xrange', comp) - comp = replaceStars(comp, options) - debug('stars', comp) - return comp -} + this.debug(this.pattern, set) -function isX (id) { - return !id || id.toLowerCase() === 'x' || id === '*' + this.set = set } -// ~, ~> --> * (any, kinda silly) -// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 -// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 -// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 -// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 -// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 -function replaceTildes (comp, options) { - return comp.trim().split(/\s+/).map(function (comp) { - return replaceTilde(comp, options) - }).join(' ') -} +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + var negate = false + var options = this.options + var negateOffset = 0 -function replaceTilde (comp, options) { - var r = options.loose ? re[TILDELOOSE] : re[TILDE] - return comp.replace(r, function (_, M, m, p, pr) { - debug('tilde', comp, _, M, m, p, pr) - var ret + if (options.nonegate) return - if (isX(M)) { - ret = '' - } else if (isX(m)) { - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' - } else if (isX(p)) { - // ~1.2 == >=1.2.0 <1.3.0 - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' - } else if (pr) { - debug('replaceTilde pr', pr) - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + M + '.' + (+m + 1) + '.0' - } else { - // ~1.2.3 == >=1.2.3 <1.3.0 - ret = '>=' + M + '.' + m + '.' + p + - ' <' + M + '.' + (+m + 1) + '.0' - } + for (var i = 0, l = pattern.length + ; i < l && pattern.charAt(i) === '!' + ; i++) { + negate = !negate + negateOffset++ + } - debug('tilde return', ret) - return ret - }) + if (negateOffset) this.pattern = pattern.substr(negateOffset) + this.negate = negate } -// ^ --> * (any, kinda silly) -// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 -// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 -// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 -// ^1.2.3 --> >=1.2.3 <2.0.0 -// ^1.2.0 --> >=1.2.0 <2.0.0 -function replaceCarets (comp, options) { - return comp.trim().split(/\s+/).map(function (comp) { - return replaceCaret(comp, options) - }).join(' ') +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +minimatch.braceExpand = function (pattern, options) { + return braceExpand(pattern, options) } -function replaceCaret (comp, options) { - debug('caret', comp, options) - var r = options.loose ? re[CARETLOOSE] : re[CARET] - return comp.replace(r, function (_, M, m, p, pr) { - debug('caret', comp, _, M, m, p, pr) - var ret +Minimatch.prototype.braceExpand = braceExpand - if (isX(M)) { - ret = '' - } else if (isX(m)) { - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' - } else if (isX(p)) { - if (M === '0') { - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' - } else { - ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0' - } - } else if (pr) { - debug('replaceCaret pr', pr) - if (M === '0') { - if (m === '0') { - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + M + '.' + m + '.' + (+p + 1) - } else { - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + M + '.' + (+m + 1) + '.0' - } - } else { - ret = '>=' + M + '.' + m + '.' + p + '-' + pr + - ' <' + (+M + 1) + '.0.0' - } +function braceExpand (pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options } else { - debug('no pr') - if (M === '0') { - if (m === '0') { - ret = '>=' + M + '.' + m + '.' + p + - ' <' + M + '.' + m + '.' + (+p + 1) - } else { - ret = '>=' + M + '.' + m + '.' + p + - ' <' + M + '.' + (+m + 1) + '.0' - } - } else { - ret = '>=' + M + '.' + m + '.' + p + - ' <' + (+M + 1) + '.0.0' - } - } - - debug('caret return', ret) - return ret - }) -} - -function replaceXRanges (comp, options) { - debug('replaceXRanges', comp, options) - return comp.split(/\s+/).map(function (comp) { - return replaceXRange(comp, options) - }).join(' ') -} - -function replaceXRange (comp, options) { - comp = comp.trim() - var r = options.loose ? re[XRANGELOOSE] : re[XRANGE] - return comp.replace(r, function (ret, gtlt, M, m, p, pr) { - debug('xRange', comp, ret, gtlt, M, m, p, pr) - var xM = isX(M) - var xm = xM || isX(m) - var xp = xm || isX(p) - var anyX = xp - - if (gtlt === '=' && anyX) { - gtlt = '' - } - - if (xM) { - if (gtlt === '>' || gtlt === '<') { - // nothing is allowed - ret = '<0.0.0' - } else { - // nothing is forbidden - ret = '*' - } - } else if (gtlt && anyX) { - // we know patch is an x, because we have any x at all. - // replace X with 0 - if (xm) { - m = 0 - } - p = 0 - - if (gtlt === '>') { - // >1 => >=2.0.0 - // >1.2 => >=1.3.0 - // >1.2.3 => >= 1.2.4 - gtlt = '>=' - if (xm) { - M = +M + 1 - m = 0 - p = 0 - } else { - m = +m + 1 - p = 0 - } - } else if (gtlt === '<=') { - // <=0.7.x is actually <0.8.0, since any 0.7.x should - // pass. Similarly, <=7.x is actually <8.0.0, etc. - gtlt = '<' - if (xm) { - M = +M + 1 - } else { - m = +m + 1 - } - } - - ret = gtlt + M + '.' + m + '.' + p - } else if (xm) { - ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' - } else if (xp) { - ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + options = {} } + } - debug('xRange return', ret) - - return ret - }) -} - -// Because * is AND-ed with everything else in the comparator, -// and '' means "any version", just remove the *s entirely. -function replaceStars (comp, options) { - debug('replaceStars', comp, options) - // Looseness is ignored here. star is always as loose as it gets! - return comp.trim().replace(re[STAR], '') -} + pattern = typeof pattern === 'undefined' + ? this.pattern : pattern -// This function is passed to string.replace(re[HYPHENRANGE]) -// M, m, patch, prerelease, build -// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 -// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do -// 1.2 - 3.4 => >=1.2.0 <3.5.0 -function hyphenReplace ($0, - from, fM, fm, fp, fpr, fb, - to, tM, tm, tp, tpr, tb) { - if (isX(fM)) { - from = '' - } else if (isX(fm)) { - from = '>=' + fM + '.0.0' - } else if (isX(fp)) { - from = '>=' + fM + '.' + fm + '.0' - } else { - from = '>=' + from + if (typeof pattern === 'undefined') { + throw new TypeError('undefined pattern') } - if (isX(tM)) { - to = '' - } else if (isX(tm)) { - to = '<' + (+tM + 1) + '.0.0' - } else if (isX(tp)) { - to = '<' + tM + '.' + (+tm + 1) + '.0' - } else if (tpr) { - to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr - } else { - to = '<=' + to + if (options.nobrace || + !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern] } - return (from + ' ' + to).trim() + return expand(pattern) } -// if ANY of the sets match ALL of its comparators, then pass -Range.prototype.test = function (version) { - if (!version) { - return false +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +Minimatch.prototype.parse = parse +var SUBPARSE = {} +function parse (pattern, isSub) { + if (pattern.length > 1024 * 64) { + throw new TypeError('pattern is too long') } - if (typeof version === 'string') { - version = new SemVer(version, this.options) - } + var options = this.options - for (var i = 0; i < this.set.length; i++) { - if (testSet(this.set[i], version, this.options)) { - return true - } - } - return false -} + // shortcuts + if (!options.noglobstar && pattern === '**') return GLOBSTAR + if (pattern === '') return '' -function testSet (set, version, options) { - for (var i = 0; i < set.length; i++) { - if (!set[i].test(version)) { - return false + var re = '' + var hasMagic = !!options.nocase + var escaping = false + // ? => one single character + var patternListStack = [] + var negativeLists = [] + var stateChar + var inClass = false + var reClassStart = -1 + var classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' + : '(?!\\.)' + var self = this + + function clearStateChar () { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star + hasMagic = true + break + case '?': + re += qmark + hasMagic = true + break + default: + re += '\\' + stateChar + break + } + self.debug('clearStateChar %j %j', stateChar, re) + stateChar = false } } - if (version.prerelease.length && !options.includePrerelease) { - // Find the set of versions that are allowed to have prereleases - // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 - // That should allow `1.2.3-pr.2` to pass. - // However, `1.2.4-alpha.notready` should NOT be allowed, - // even though it's within the range set by the comparators. - for (i = 0; i < set.length; i++) { - debug(set[i].semver) - if (set[i].semver === ANY) { - continue - } + for (var i = 0, len = pattern.length, c + ; (i < len) && (c = pattern.charAt(i)) + ; i++) { + this.debug('%s\t%s %s %j', pattern, i, re, c) - if (set[i].semver.prerelease.length > 0) { - var allowed = set[i].semver - if (allowed.major === version.major && - allowed.minor === version.minor && - allowed.patch === version.patch) { - return true - } - } + // skip over any that are escaped. + if (escaping && reSpecials[c]) { + re += '\\' + c + escaping = false + continue } - // Version has a -pre, but it's not one of the ones we like. - return false - } + switch (c) { + case '/': + // completely not allowed, even escaped. + // Should already be path-split by now. + return false - return true -} + case '\\': + clearStateChar() + escaping = true + continue -exports.satisfies = satisfies -function satisfies (version, range, options) { - try { - range = new Range(range, options) - } catch (er) { - return false - } - return range.test(version) -} + // the various stateChar values + // for the "extglob" stuff. + case '?': + case '*': + case '+': + case '@': + case '!': + this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) -exports.maxSatisfying = maxSatisfying -function maxSatisfying (versions, range, options) { - var max = null - var maxSV = null - try { - var rangeObj = new Range(range, options) - } catch (er) { - return null - } - versions.forEach(function (v) { - if (rangeObj.test(v)) { - // satisfies(v, range, options) - if (!max || maxSV.compare(v) === -1) { - // compare(max, v, true) - max = v - maxSV = new SemVer(max, options) - } - } - }) - return max -} + // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + if (inClass) { + this.debug(' in class') + if (c === '!' && i === classStart + 1) c = '^' + re += c + continue + } -exports.minSatisfying = minSatisfying -function minSatisfying (versions, range, options) { - var min = null - var minSV = null - try { - var rangeObj = new Range(range, options) - } catch (er) { - return null - } - versions.forEach(function (v) { - if (rangeObj.test(v)) { - // satisfies(v, range, options) - if (!min || minSV.compare(v) === 1) { - // compare(min, v, true) - min = v - minSV = new SemVer(min, options) - } - } - }) - return min -} + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + self.debug('call clearStateChar %j', stateChar) + clearStateChar() + stateChar = c + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) clearStateChar() + continue -exports.minVersion = minVersion -function minVersion (range, loose) { - range = new Range(range, loose) + case '(': + if (inClass) { + re += '(' + continue + } - var minver = new SemVer('0.0.0') - if (range.test(minver)) { - return minver - } + if (!stateChar) { + re += '\\(' + continue + } - minver = new SemVer('0.0.0-0') - if (range.test(minver)) { - return minver - } + patternListStack.push({ + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close + }) + // negation is (?:(?!js)[^/]*) + re += stateChar === '!' ? '(?:(?!(?:' : '(?:' + this.debug('plType %j %j', stateChar, re) + stateChar = false + continue - minver = null - for (var i = 0; i < range.set.length; ++i) { - var comparators = range.set[i] + case ')': + if (inClass || !patternListStack.length) { + re += '\\)' + continue + } - comparators.forEach(function (comparator) { - // Clone to avoid manipulating the comparator's semver object. - var compver = new SemVer(comparator.semver.version) - switch (comparator.operator) { - case '>': - if (compver.prerelease.length === 0) { - compver.patch++ - } else { - compver.prerelease.push(0) - } - compver.raw = compver.format() - /* fallthrough */ - case '': - case '>=': - if (!minver || gt(minver, compver)) { - minver = compver - } - break - case '<': - case '<=': - /* Ignore maximum versions */ - break - /* istanbul ignore next */ - default: - throw new Error('Unexpected operation: ' + comparator.operator) - } - }) - } + clearStateChar() + hasMagic = true + var pl = patternListStack.pop() + // negation is (?:(?!js)[^/]*) + // The others are (?:) + re += pl.close + if (pl.type === '!') { + negativeLists.push(pl) + } + pl.reEnd = re.length + continue - if (minver && range.test(minver)) { - return minver - } + case '|': + if (inClass || !patternListStack.length || escaping) { + re += '\\|' + escaping = false + continue + } - return null -} + clearStateChar() + re += '|' + continue -exports.validRange = validRange -function validRange (range, options) { - try { - // Return '*' instead of '' so that truthiness works. - // This will throw if it's invalid anyway - return new Range(range, options).range || '*' - } catch (er) { - return null - } -} + // these are mostly the same in regexp and glob + case '[': + // swallow any state-tracking char before the [ + clearStateChar() -// Determine if version is less than all the versions possible in the range -exports.ltr = ltr -function ltr (version, range, options) { - return outside(version, range, '<', options) -} + if (inClass) { + re += '\\' + c + continue + } -// Determine if version is greater than all the versions possible in the range. -exports.gtr = gtr -function gtr (version, range, options) { - return outside(version, range, '>', options) -} + inClass = true + classStart = i + reClassStart = re.length + re += c + continue -exports.outside = outside -function outside (version, range, hilo, options) { - version = new SemVer(version, options) - range = new Range(range, options) + case ']': + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += '\\' + c + escaping = false + continue + } - var gtfn, ltefn, ltfn, comp, ecomp - switch (hilo) { - case '>': - gtfn = gt - ltefn = lte - ltfn = lt - comp = '>' - ecomp = '>=' - break - case '<': - gtfn = lt - ltefn = gte - ltfn = gt - comp = '<' - ecomp = '<=' - break - default: - throw new TypeError('Must provide a hilo val of "<" or ">"') - } + // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = false + continue + } + } - // If it satisifes the range it is not outside - if (satisfies(version, range, options)) { - return false - } + // finish up the class. + hasMagic = true + inClass = false + re += c + continue - // From now on, variable terms are as if we're in "gtr" mode. - // but note that everything is flipped for the "ltr" function. + default: + // swallow any state char that wasn't consumed + clearStateChar() - for (var i = 0; i < range.set.length; ++i) { - var comparators = range.set[i] + if (escaping) { + // no need + escaping = false + } else if (reSpecials[c] + && !(c === '^' && inClass)) { + re += '\\' + } - var high = null - var low = null + re += c - comparators.forEach(function (comparator) { - if (comparator.semver === ANY) { - comparator = new Comparator('>=0.0.0') - } - high = high || comparator - low = low || comparator - if (gtfn(comparator.semver, high.semver, options)) { - high = comparator - } else if (ltfn(comparator.semver, low.semver, options)) { - low = comparator + } // switch + } // for + + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + cs = pattern.substr(classStart + 1) + sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + hasMagic = hasMagic || sp[1] + } + + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + pl.open.length) + this.debug('setting tail', re, pl) + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\' } + + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + '|' }) - // If the edge version comparator has a operator then our version - // isn't outside it - if (high.operator === comp || high.operator === ecomp) { - return false - } + this.debug('tail=%j\n %s', tail, tail, pl, re) + var t = pl.type === '*' ? star + : pl.type === '?' ? qmark + : '\\' + pl.type - // If the lowest version comparator has an operator and our version - // is less than it then it isn't higher than the range - if ((!low.operator || low.operator === comp) && - ltefn(version, low.semver)) { - return false - } else if (low.operator === ecomp && ltfn(version, low.semver)) { - return false - } + hasMagic = true + re = re.slice(0, pl.reStart) + t + '\\(' + tail } - return true -} - -exports.prerelease = prerelease -function prerelease (version, options) { - var parsed = parse(version, options) - return (parsed && parsed.prerelease.length) ? parsed.prerelease : null -} -exports.intersects = intersects -function intersects (r1, r2, options) { - r1 = new Range(r1, options) - r2 = new Range(r2, options) - return r1.intersects(r2) -} - -exports.coerce = coerce -function coerce (version) { - if (version instanceof SemVer) { - return version + // handle trailing things that only matter at the very end. + clearStateChar() + if (escaping) { + // trailing \\ + re += '\\\\' } - if (typeof version !== 'string') { - return null + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + var addPatternStart = false + switch (re.charAt(0)) { + case '.': + case '[': + case '(': addPatternStart = true } - var match = version.match(re[COERCE]) + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n] - if (match == null) { - return null + var nlBefore = re.slice(0, nl.reStart) + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + var nlAfter = re.slice(nl.reEnd) + + nlLast += nlAfter + + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + var openParensBefore = nlBefore.split('(').length - 1 + var cleanAfter = nlAfter + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') + } + nlAfter = cleanAfter + + var dollar = '' + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$' + } + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast + re = newRe } - return parse(match[1] + - '.' + (match[2] || '0') + - '.' + (match[3] || '0')) -} + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== '' && hasMagic) { + re = '(?=.)' + re + } + if (addPatternStart) { + re = patternStart + re + } -/***/ }), -/* 524 */ -/***/ (function(module, exports, __webpack_require__) { + // parsing just a piece of a larger pattern. + if (isSub === SUBPARSE) { + return [re, hasMagic] + } -var parse = __webpack_require__(525); -var correct = __webpack_require__(527); + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(pattern) + } -var genericWarning = ( - 'license should be ' + - 'a valid SPDX license expression (without "LicenseRef"), ' + - '"UNLICENSED", or ' + - '"SEE LICENSE IN "' -); + var flags = options.nocase ? 'i' : '' + try { + var regExp = new RegExp('^' + re + '$', flags) + } catch (er) { + // If it was an invalid regular expression, then it can't match + // anything. This trick looks for a character after the end of + // the string, which is of course impossible, except in multi-line + // mode, but it's not a /m regex. + return new RegExp('$.') + } -var fileReferenceRE = /^SEE LICEN[CS]E IN (.+)$/; + regExp._glob = pattern + regExp._src = re -function startsWith(prefix, string) { - return string.slice(0, prefix.length) === prefix; + return regExp } -function usesLicenseRef(ast) { - if (ast.hasOwnProperty('license')) { - var license = ast.license; - return ( - startsWith('LicenseRef', license) || - startsWith('DocumentRef', license) - ); - } else { - return ( - usesLicenseRef(ast.left) || - usesLicenseRef(ast.right) - ); - } +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe() } -module.exports = function(argument) { - var ast; +Minimatch.prototype.makeRe = makeRe +function makeRe () { + if (this.regexp || this.regexp === false) return this.regexp - try { - ast = parse(argument); - } catch (e) { - var match - if ( - argument === 'UNLICENSED' || - argument === 'UNLICENCED' - ) { - return { - validForOldPackages: true, - validForNewPackages: true, - unlicensed: true - }; - } else if (match = fileReferenceRE.exec(argument)) { - return { - validForOldPackages: true, - validForNewPackages: true, - inFile: match[1] - }; - } else { - var result = { - validForOldPackages: false, - validForNewPackages: false, - warnings: [genericWarning] - }; - var corrected = correct(argument); - if (corrected) { - result.warnings.push( - 'license is similar to the valid expression "' + corrected + '"' - ); - } - return result; - } - } + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + var set = this.set - if (usesLicenseRef(ast)) { - return { - validForNewPackages: false, - validForOldPackages: false, - spdx: true, - warnings: [genericWarning] - }; - } else { - return { - validForNewPackages: true, - validForOldPackages: true, - spdx: true - }; + if (!set.length) { + this.regexp = false + return this.regexp } -}; + var options = this.options + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + var flags = options.nocase ? 'i' : '' -/***/ }), -/* 525 */ -/***/ (function(module, exports, __webpack_require__) { + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return (p === GLOBSTAR) ? twoStar + : (typeof p === 'string') ? regExpEscape(p) + : p._src + }).join('\\\/') + }).join('|') -var parser = __webpack_require__(526).parser + // must match entire pattern + // ending in a * or ** will make it less strict. + re = '^(?:' + re + ')$' -module.exports = function (argument) { - return parser.parse(argument) + // can match anything, as long as it's not this. + if (this.negate) re = '^(?!' + re + ').*$' + + try { + this.regexp = new RegExp(re, flags) + } catch (ex) { + this.regexp = false + } + return this.regexp } +minimatch.match = function (list, pattern, options) { + options = options || {} + var mm = new Minimatch(pattern, options) + list = list.filter(function (f) { + return mm.match(f) + }) + if (mm.options.nonull && !list.length) { + list.push(pattern) + } + return list +} -/***/ }), -/* 526 */ -/***/ (function(module, exports, __webpack_require__) { +Minimatch.prototype.match = match +function match (f, partial) { + this.debug('match', f, this.pattern) + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) return false + if (this.empty) return f === '' -/* WEBPACK VAR INJECTION */(function(module) {/* parser generated by jison 0.4.17 */ -/* - Returns a Parser object of the following structure: + if (f === '/' && partial) return true - Parser: { - yy: {} + var options = this.options + + // windows: need to use /, not \ + if (path.sep !== '/') { + f = f.split(path.sep).join('/') } - Parser.prototype: { - yy: {}, - trace: function(), - symbols_: {associative list: name ==> number}, - terminals_: {associative list: number ==> name}, - productions_: [...], - performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), - table: [...], - defaultActions: {...}, - parseError: function(str, hash), - parse: function(input), + // treat the test path as a set of pathparts. + f = f.split(slashSplit) + this.debug(this.pattern, 'split', f) - lexer: { - EOF: 1, - parseError: function(str, hash), - setInput: function(input), - input: function(), - unput: function(str), - more: function(), - less: function(n), - pastInput: function(), - upcomingInput: function(), - showPosition: function(), - test_match: function(regex_match_array, rule_index), - next: function(), - lex: function(), - begin: function(condition), - popState: function(), - _currentRules: function(), - topState: function(), - pushState: function(condition), + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. - options: { - ranges: boolean (optional: true ==> token location info will include a .range[] member) - flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) - backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) - }, + var set = this.set + this.debug(this.pattern, 'set', set) - performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), - rules: [...], - conditions: {associative list: name ==> set}, + // Find the basename of the path by looking for the last non-empty segment + var filename + var i + for (i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } + + for (i = 0; i < set.length; i++) { + var pattern = set[i] + var file = f + if (options.matchBase && pattern.length === 1) { + file = [filename] + } + var hit = this.matchOne(file, pattern, partial) + if (hit) { + if (options.flipNegate) return true + return !this.negate } } + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) return false + return this.negate +} - token location info (@$, _$, etc.): { - first_line: n, - last_line: n, - first_column: n, - last_column: n, - range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) - } +// set partial to true to test if, for example, +// "/a/b" matches the start of "/*/b/*/d" +// Partial means, if you run out of file before you run +// out of pattern, then that's fine, as long as all +// the parts match. +Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options + this.debug('matchOne', + { 'this': this, file: file, pattern: pattern }) - the parseError function receives a 'hash' object with these members for lexer and parser errors: { - text: (matched text) - token: (the produced terminal token, if any) - line: (yylineno) - } - while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { - loc: (yylloc) - expected: (string describing the set of expected tokens) - recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) - } -*/ -var spdxparse = (function(){ -var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,5],$V1=[1,6],$V2=[1,7],$V3=[1,4],$V4=[1,9],$V5=[1,10],$V6=[5,14,15,17],$V7=[5,12,14,15,17]; -var parser = {trace: function trace() { }, -yy: {}, -symbols_: {"error":2,"start":3,"expression":4,"EOS":5,"simpleExpression":6,"LICENSE":7,"PLUS":8,"LICENSEREF":9,"DOCUMENTREF":10,"COLON":11,"WITH":12,"EXCEPTION":13,"AND":14,"OR":15,"OPEN":16,"CLOSE":17,"$accept":0,"$end":1}, -terminals_: {2:"error",5:"EOS",7:"LICENSE",8:"PLUS",9:"LICENSEREF",10:"DOCUMENTREF",11:"COLON",12:"WITH",13:"EXCEPTION",14:"AND",15:"OR",16:"OPEN",17:"CLOSE"}, -productions_: [0,[3,2],[6,1],[6,2],[6,1],[6,3],[4,1],[4,3],[4,3],[4,3],[4,3]], -performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { -/* this == yyval */ + this.debug('matchOne', file.length, pattern.length) -var $0 = $$.length - 1; -switch (yystate) { -case 1: -return this.$ = $$[$0-1] -break; -case 2: case 4: case 5: -this.$ = {license: yytext} -break; -case 3: -this.$ = {license: $$[$0-1], plus: true} -break; -case 6: -this.$ = $$[$0] -break; -case 7: -this.$ = {exception: $$[$0]} -this.$.license = $$[$0-2].license -if ($$[$0-2].hasOwnProperty('plus')) { - this.$.plus = $$[$0-2].plus -} -break; -case 8: -this.$ = {conjunction: 'and', left: $$[$0-2], right: $$[$0]} -break; -case 9: -this.$ = {conjunction: 'or', left: $$[$0-2], right: $$[$0]} -break; -case 10: -this.$ = $$[$0-1] -break; -} -}, -table: [{3:1,4:2,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{1:[3]},{5:[1,8],14:$V4,15:$V5},o($V6,[2,6],{12:[1,11]}),{4:12,6:3,7:$V0,9:$V1,10:$V2,16:$V3},o($V7,[2,2],{8:[1,13]}),o($V7,[2,4]),{11:[1,14]},{1:[2,1]},{4:15,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{4:16,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{13:[1,17]},{14:$V4,15:$V5,17:[1,18]},o($V7,[2,3]),{9:[1,19]},o($V6,[2,8]),o([5,15,17],[2,9],{14:$V4}),o($V6,[2,7]),o($V6,[2,10]),o($V7,[2,5])], -defaultActions: {8:[2,1]}, -parseError: function parseError(str, hash) { - if (hash.recoverable) { - this.trace(str); - } else { - function _parseError (msg, hash) { - this.message = msg; - this.hash = hash; - } - _parseError.prototype = Error; + for (var fi = 0, + pi = 0, + fl = file.length, + pl = pattern.length + ; (fi < fl) && (pi < pl) + ; fi++, pi++) { + this.debug('matchOne loop') + var p = pattern[pi] + var f = file[fi] - throw new _parseError(str, hash); - } -}, -parse: function parse(input) { - var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; - var args = lstack.slice.call(arguments, 1); - var lexer = Object.create(this.lexer); - var sharedState = { yy: {} }; - for (var k in this.yy) { - if (Object.prototype.hasOwnProperty.call(this.yy, k)) { - sharedState.yy[k] = this.yy[k]; + this.debug(pattern, p, f) + + // should be impossible. + // some invalid regexp stuff in the set. + if (p === false) return false + + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]) + + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi + var pr = pi + 1 + if (pr === pl) { + this.debug('** at the end') + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for (; fi < fl; fi++) { + if (file[fi] === '.' || file[fi] === '..' || + (!options.dot && file[fi].charAt(0) === '.')) return false } - } - lexer.setInput(input, sharedState.yy); - sharedState.yy.lexer = lexer; - sharedState.yy.parser = this; - if (typeof lexer.yylloc == 'undefined') { - lexer.yylloc = {}; - } - var yyloc = lexer.yylloc; - lstack.push(yyloc); - var ranges = lexer.options && lexer.options.ranges; - if (typeof sharedState.yy.parseError === 'function') { - this.parseError = sharedState.yy.parseError; - } else { - this.parseError = Object.getPrototypeOf(this).parseError; - } - function popStack(n) { - stack.length = stack.length - 2 * n; - vstack.length = vstack.length - n; - lstack.length = lstack.length - n; - } - _token_stack: - var lex = function () { - var token; - token = lexer.lex() || EOF; - if (typeof token !== 'number') { - token = self.symbols_[token] || token; - } - return token; - }; - var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; - while (true) { - state = stack[stack.length - 1]; - if (this.defaultActions[state]) { - action = this.defaultActions[state]; + return true + } + + // ok, let's see if we can swallow whatever we can. + while (fr < fl) { + var swallowee = file[fr] + + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) + + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee) + // found a match. + return true } else { - if (symbol === null || typeof symbol == 'undefined') { - symbol = lex(); - } - action = table[state] && table[state][symbol]; - } - if (typeof action === 'undefined' || !action.length || !action[0]) { - var errStr = ''; - expected = []; - for (p in table[state]) { - if (this.terminals_[p] && p > TERROR) { - expected.push('\'' + this.terminals_[p] + '\''); - } - } - if (lexer.showPosition) { - errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; - } else { - errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); - } - this.parseError(errStr, { - text: lexer.match, - token: this.terminals_[symbol] || symbol, - line: lexer.yylineno, - loc: yyloc, - expected: expected - }); - } - if (action[0] instanceof Array && action.length > 1) { - throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); - } - switch (action[0]) { - case 1: - stack.push(symbol); - vstack.push(lexer.yytext); - lstack.push(lexer.yylloc); - stack.push(action[1]); - symbol = null; - if (!preErrorSymbol) { - yyleng = lexer.yyleng; - yytext = lexer.yytext; - yylineno = lexer.yylineno; - yyloc = lexer.yylloc; - if (recovering > 0) { - recovering--; - } - } else { - symbol = preErrorSymbol; - preErrorSymbol = null; - } - break; - case 2: - len = this.productions_[action[1]][1]; - yyval.$ = vstack[vstack.length - len]; - yyval._$ = { - first_line: lstack[lstack.length - (len || 1)].first_line, - last_line: lstack[lstack.length - 1].last_line, - first_column: lstack[lstack.length - (len || 1)].first_column, - last_column: lstack[lstack.length - 1].last_column - }; - if (ranges) { - yyval._$.range = [ - lstack[lstack.length - (len || 1)].range[0], - lstack[lstack.length - 1].range[1] - ]; - } - r = this.performAction.apply(yyval, [ - yytext, - yyleng, - yylineno, - sharedState.yy, - action[1], - vstack, - lstack - ].concat(args)); - if (typeof r !== 'undefined') { - return r; - } - if (len) { - stack = stack.slice(0, -1 * len * 2); - vstack = vstack.slice(0, -1 * len); - lstack = lstack.slice(0, -1 * len); - } - stack.push(this.productions_[action[1]][0]); - vstack.push(yyval.$); - lstack.push(yyval._$); - newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; - stack.push(newState); - break; - case 3: - return true; + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || swallowee === '..' || + (!options.dot && swallowee.charAt(0) === '.')) { + this.debug('dot detected!', file, fr, pattern, pr) + break + } + + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue') + fr++ } + } + + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr) + if (fr === fl) return true + } + return false } - return true; -}}; -/* generated by jison-lex 0.3.4 */ -var lexer = (function(){ -var lexer = ({ -EOF:1, + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + var hit + if (typeof p === 'string') { + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase() + } else { + hit = f === p + } + this.debug('string match', p, f, hit) + } else { + hit = f.match(p) + this.debug('pattern match', p, f, hit) + } -parseError:function parseError(str, hash) { - if (this.yy.parser) { - this.yy.parser.parseError(str, hash); - } else { - throw new Error(str); - } - }, + if (!hit) return false + } -// resets the lexer, sets new input -setInput:function (input, yy) { - this.yy = yy || this.yy || {}; - this._input = input; - this._more = this._backtrack = this.done = false; - this.yylineno = this.yyleng = 0; - this.yytext = this.matched = this.match = ''; - this.conditionStack = ['INITIAL']; - this.yylloc = { - first_line: 1, - first_column: 0, - last_line: 1, - last_column: 0 - }; - if (this.options.ranges) { - this.yylloc.range = [0,0]; - } - this.offset = 0; - return this; - }, + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* -// consumes and returns one char from the input -input:function () { - var ch = this._input[0]; - this.yytext += ch; - this.yyleng++; - this.offset++; - this.match += ch; - this.matched += ch; - var lines = ch.match(/(?:\r\n?|\n).*/g); - if (lines) { - this.yylineno++; - this.yylloc.last_line++; - } else { - this.yylloc.last_column++; - } - if (this.options.ranges) { - this.yylloc.range[1]++; - } + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial + } else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') + return emptyFileEnd + } - this._input = this._input.slice(1); - return ch; - }, + // should be unreachable. + throw new Error('wtf?') +} -// unshifts one char (or a string) into the input -unput:function (ch) { - var len = ch.length; - var lines = ch.split(/(?:\r\n?|\n)/g); +// replace stuff like \* with * +function globUnescape (s) { + return s.replace(/\\(.)/g, '$1') +} - this._input = ch + this._input; - this.yytext = this.yytext.substr(0, this.yytext.length - len); - //this.yyleng -= len; - this.offset -= len; - var oldLines = this.match.split(/(?:\r\n?|\n)/g); - this.match = this.match.substr(0, this.match.length - 1); - this.matched = this.matched.substr(0, this.matched.length - 1); +function regExpEscape (s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +} - if (lines.length - 1) { - this.yylineno -= lines.length - 1; - } - var r = this.yylloc.range; - this.yylloc = { - first_line: this.yylloc.first_line, - last_line: this.yylineno + 1, - first_column: this.yylloc.first_column, - last_column: lines ? - (lines.length === oldLines.length ? this.yylloc.first_column : 0) - + oldLines[oldLines.length - lines.length].length - lines[0].length : - this.yylloc.first_column - len - }; +/***/ }), +/* 507 */ +/***/ (function(module, exports, __webpack_require__) { - if (this.options.ranges) { - this.yylloc.range = [r[0], r[0] + this.yyleng - len]; - } - this.yyleng = this.yytext.length; - return this; - }, +var concatMap = __webpack_require__(508); +var balanced = __webpack_require__(509); -// When called from action, caches matched text and appends it on next action -more:function () { - this._more = true; - return this; - }, +module.exports = expandTop; -// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. -reject:function () { - if (this.options.backtrack_lexer) { - this._backtrack = true; - } else { - return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), { - text: "", - token: null, - line: this.yylineno - }); +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; - } - return this; - }, +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} -// retain first n characters of the match -less:function (n) { - this.unput(this.match.slice(n)); - }, +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} -// displays already matched input, i.e. for error messages -pastInput:function () { - var past = this.matched.substr(0, this.matched.length - this.match.length); - return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); - }, +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} -// displays upcoming input, i.e. for error messages -upcomingInput:function () { - var next = this.match; - if (next.length < 20) { - next += this._input.substr(0, 20-next.length); - } - return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); - }, -// displays the character position where the lexing error occurred, i.e. for error messages -showPosition:function () { - var pre = this.pastInput(); - var c = new Array(pre.length + 1).join("-"); - return pre + this.upcomingInput() + "\n" + c + "^"; - }, +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; -// test the lexed token: return FALSE when not a match, otherwise return token -test_match:function (match, indexed_rule) { - var token, - lines, - backup; + var parts = []; + var m = balanced('{', '}', str); - if (this.options.backtrack_lexer) { - // save context - backup = { - yylineno: this.yylineno, - yylloc: { - first_line: this.yylloc.first_line, - last_line: this.last_line, - first_column: this.yylloc.first_column, - last_column: this.yylloc.last_column - }, - yytext: this.yytext, - match: this.match, - matches: this.matches, - matched: this.matched, - yyleng: this.yyleng, - offset: this.offset, - _more: this._more, - _input: this._input, - yy: this.yy, - conditionStack: this.conditionStack.slice(0), - done: this.done - }; - if (this.options.ranges) { - backup.yylloc.range = this.yylloc.range.slice(0); - } - } + if (!m) + return str.split(','); - lines = match[0].match(/(?:\r\n?|\n).*/g); - if (lines) { - this.yylineno += lines.length; - } - this.yylloc = { - first_line: this.yylloc.last_line, - last_line: this.yylineno + 1, - first_column: this.yylloc.last_column, - last_column: lines ? - lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : - this.yylloc.last_column + match[0].length - }; - this.yytext += match[0]; - this.match += match[0]; - this.matches = match; - this.yyleng = this.yytext.length; - if (this.options.ranges) { - this.yylloc.range = [this.offset, this.offset += this.yyleng]; - } - this._more = false; - this._backtrack = false; - this._input = this._input.slice(match[0].length); - this.matched += match[0]; - token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); - if (this.done && this._input) { - this.done = false; - } - if (token) { - return token; - } else if (this._backtrack) { - // recover context - for (var k in backup) { - this[k] = backup[k]; - } - return false; // rule action called reject() implying the next rule should be tested instead. - } - return false; - }, + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); -// return next match in input -next:function () { - if (this.done) { - return this.EOF; - } - if (!this._input) { - this.done = true; - } + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } - var token, - match, - tempMatch, - index; - if (!this._more) { - this.yytext = ''; - this.match = ''; - } - var rules = this._currentRules(); - for (var i = 0; i < rules.length; i++) { - tempMatch = this._input.match(this.rules[rules[i]]); - if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { - match = tempMatch; - index = i; - if (this.options.backtrack_lexer) { - token = this.test_match(tempMatch, rules[i]); - if (token !== false) { - return token; - } else if (this._backtrack) { - match = false; - continue; // rule action called reject() implying a rule MISmatch. - } else { - // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) - return false; - } - } else if (!this.options.flex) { - break; - } - } - } - if (match) { - token = this.test_match(match, rules[index]); - if (token !== false) { - return token; - } - // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) - return false; - } - if (this._input === "") { - return this.EOF; - } else { - return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { - text: "", - token: null, - line: this.yylineno - }); - } - }, + parts.push.apply(parts, p); -// return next match that has a token -lex:function lex() { - var r = this.next(); - if (r) { - return r; - } else { - return this.lex(); + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } } - }, + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } -// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) -begin:function begin(condition) { - this.conditionStack.push(condition); - }, + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } -// pop the previously active lexer condition state off the condition stack -popState:function popState() { - var n = this.conditionStack.length - 1; - if (n > 0) { - return this.conditionStack.pop(); - } else { - return this.conditionStack[0]; + return expansions; +} + + + +/***/ }), +/* 508 */ +/***/ (function(module, exports) { + +module.exports = function (xs, fn) { + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray(x)) res.push.apply(res, x); + else res.push(x); + } + return res; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + + +/***/ }), +/* 509 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; + + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; } - }, -// produce the lexer rule set which is active for the currently active lexer condition state -_currentRules:function _currentRules() { - if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { - return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; - } else { - return this.conditions["INITIAL"].rules; + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; +} + + +/***/ }), +/* 510 */ +/***/ (function(module, exports, __webpack_require__) { + +try { + var util = __webpack_require__(397); + /* istanbul ignore next */ + if (typeof util.inherits !== 'function') throw ''; + module.exports = util.inherits; +} catch (e) { + /* istanbul ignore next */ + module.exports = __webpack_require__(511); +} + + +/***/ }), +/* 511 */ +/***/ (function(module, exports) { + +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true } - }, + }) + } + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } + } +} -// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available -topState:function topState(n) { - n = this.conditionStack.length - 1 - Math.abs(n || 0); - if (n >= 0) { - return this.conditionStack[n]; - } else { - return "INITIAL"; + +/***/ }), +/* 512 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function posix(path) { + return path.charAt(0) === '/'; +} + +function win32(path) { + // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 + var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; + var result = splitDeviceRe.exec(path); + var device = result[1] || ''; + var isUnc = Boolean(device && device.charAt(1) !== ':'); + + // UNC paths are always absolute + return Boolean(result[2] || isUnc); +} + +module.exports = process.platform === 'win32' ? win32 : posix; +module.exports.posix = posix; +module.exports.win32 = win32; + + +/***/ }), +/* 513 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = globSync +globSync.GlobSync = GlobSync + +var fs = __webpack_require__(349) +var rp = __webpack_require__(504) +var minimatch = __webpack_require__(506) +var Minimatch = minimatch.Minimatch +var Glob = __webpack_require__(503).Glob +var util = __webpack_require__(397) +var path = __webpack_require__(4) +var assert = __webpack_require__(371) +var isAbsolute = __webpack_require__(512) +var common = __webpack_require__(514) +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = rp.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er } - }, + } + }) + } + common.finish(this) +} -// alias for begin(condition) -pushState:function pushState(condition) { - this.begin(condition); - }, -// return the number of states currently on the stack -stateStackSize:function stateStackSize() { - return this.conditionStack.length; - }, -options: {}, -performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { -var YYSTATE=YY_START; -switch($avoiding_name_collisions) { -case 0:return 5 -break; -case 1:/* skip whitespace */ -break; -case 2:return 8 -break; -case 3:return 16 -break; -case 4:return 17 -break; -case 5:return 11 -break; -case 6:return 10 -break; -case 7:return 9 -break; -case 8:return 14 -break; -case 9:return 15 -break; -case 10:return 12 -break; -case 11:return 7 -break; -case 12:return 7 -break; -case 13:return 7 -break; -case 14:return 7 -break; -case 15:return 7 -break; -case 16:return 7 -break; -case 17:return 7 -break; -case 18:return 7 -break; -case 19:return 7 -break; -case 20:return 7 -break; -case 21:return 7 -break; -case 22:return 7 -break; -case 23:return 7 -break; -case 24:return 13 -break; -case 25:return 13 -break; -case 26:return 13 -break; -case 27:return 13 -break; -case 28:return 13 -break; -case 29:return 13 -break; -case 30:return 13 -break; -case 31:return 13 -break; -case 32:return 7 -break; -case 33:return 13 -break; -case 34:return 7 -break; -case 35:return 13 -break; -case 36:return 7 -break; -case 37:return 13 -break; -case 38:return 13 -break; -case 39:return 7 -break; -case 40:return 13 -break; -case 41:return 13 -break; -case 42:return 13 -break; -case 43:return 13 -break; -case 44:return 13 -break; -case 45:return 7 -break; -case 46:return 13 -break; -case 47:return 7 -break; -case 48:return 7 -break; -case 49:return 7 -break; -case 50:return 7 -break; -case 51:return 7 -break; -case 52:return 7 -break; -case 53:return 7 -break; -case 54:return 7 -break; -case 55:return 7 -break; -case 56:return 7 -break; -case 57:return 7 -break; -case 58:return 7 -break; -case 59:return 7 -break; -case 60:return 7 -break; -case 61:return 7 -break; -case 62:return 7 -break; -case 63:return 13 -break; -case 64:return 7 -break; -case 65:return 7 -break; -case 66:return 13 -break; -case 67:return 7 -break; -case 68:return 7 -break; -case 69:return 7 -break; -case 70:return 7 -break; -case 71:return 7 -break; -case 72:return 7 -break; -case 73:return 13 -break; -case 74:return 7 -break; -case 75:return 13 -break; -case 76:return 7 -break; -case 77:return 7 -break; -case 78:return 7 -break; -case 79:return 7 -break; -case 80:return 7 -break; -case 81:return 7 -break; -case 82:return 7 -break; -case 83:return 7 -break; -case 84:return 7 -break; -case 85:return 7 -break; -case 86:return 7 -break; -case 87:return 7 -break; -case 88:return 7 -break; -case 89:return 7 -break; -case 90:return 7 -break; -case 91:return 7 -break; -case 92:return 7 -break; -case 93:return 7 -break; -case 94:return 7 -break; -case 95:return 7 -break; -case 96:return 7 -break; -case 97:return 7 -break; -case 98:return 7 -break; -case 99:return 7 -break; -case 100:return 7 -break; -case 101:return 7 -break; -case 102:return 7 -break; -case 103:return 7 -break; -case 104:return 7 -break; -case 105:return 7 -break; -case 106:return 7 -break; -case 107:return 7 -break; -case 108:return 7 -break; -case 109:return 7 -break; -case 110:return 7 -break; -case 111:return 7 -break; -case 112:return 7 -break; -case 113:return 7 -break; -case 114:return 7 -break; -case 115:return 7 -break; -case 116:return 7 -break; -case 117:return 7 -break; -case 118:return 7 -break; -case 119:return 7 -break; -case 120:return 7 -break; -case 121:return 7 -break; -case 122:return 7 -break; -case 123:return 7 -break; -case 124:return 7 -break; -case 125:return 7 -break; -case 126:return 7 -break; -case 127:return 7 -break; -case 128:return 7 -break; -case 129:return 7 -break; -case 130:return 7 -break; -case 131:return 7 -break; -case 132:return 7 -break; -case 133:return 7 -break; -case 134:return 7 -break; -case 135:return 7 -break; -case 136:return 7 -break; -case 137:return 7 -break; -case 138:return 7 -break; -case 139:return 7 -break; -case 140:return 7 -break; -case 141:return 7 -break; -case 142:return 7 -break; -case 143:return 7 -break; -case 144:return 7 -break; -case 145:return 7 -break; -case 146:return 7 -break; -case 147:return 7 -break; -case 148:return 7 -break; -case 149:return 7 -break; -case 150:return 7 -break; -case 151:return 7 -break; -case 152:return 7 -break; -case 153:return 7 -break; -case 154:return 7 -break; -case 155:return 7 -break; -case 156:return 7 -break; -case 157:return 7 -break; -case 158:return 7 -break; -case 159:return 7 -break; -case 160:return 7 -break; -case 161:return 7 -break; -case 162:return 7 -break; -case 163:return 7 -break; -case 164:return 7 -break; -case 165:return 7 -break; -case 166:return 7 -break; -case 167:return 7 -break; -case 168:return 7 -break; -case 169:return 7 -break; -case 170:return 7 -break; -case 171:return 7 -break; -case 172:return 7 -break; -case 173:return 7 -break; -case 174:return 7 -break; -case 175:return 7 -break; -case 176:return 7 -break; -case 177:return 7 -break; -case 178:return 7 -break; -case 179:return 7 -break; -case 180:return 7 -break; -case 181:return 7 -break; -case 182:return 7 -break; -case 183:return 7 -break; -case 184:return 7 -break; -case 185:return 7 -break; -case 186:return 7 -break; -case 187:return 7 -break; -case 188:return 7 -break; -case 189:return 7 -break; -case 190:return 7 -break; -case 191:return 7 -break; -case 192:return 7 -break; -case 193:return 7 -break; -case 194:return 7 -break; -case 195:return 7 -break; -case 196:return 7 -break; -case 197:return 7 -break; -case 198:return 7 -break; -case 199:return 7 -break; -case 200:return 7 -break; -case 201:return 7 -break; -case 202:return 7 -break; -case 203:return 7 -break; -case 204:return 7 -break; -case 205:return 7 -break; -case 206:return 7 -break; -case 207:return 7 -break; -case 208:return 7 -break; -case 209:return 7 -break; -case 210:return 7 -break; -case 211:return 7 -break; -case 212:return 7 -break; -case 213:return 7 -break; -case 214:return 7 -break; -case 215:return 7 -break; -case 216:return 7 -break; -case 217:return 7 -break; -case 218:return 7 -break; -case 219:return 7 -break; -case 220:return 7 -break; -case 221:return 7 -break; -case 222:return 7 -break; -case 223:return 7 -break; -case 224:return 7 -break; -case 225:return 7 -break; -case 226:return 7 -break; -case 227:return 7 -break; -case 228:return 7 -break; -case 229:return 7 -break; -case 230:return 7 -break; -case 231:return 7 -break; -case 232:return 7 -break; -case 233:return 7 -break; -case 234:return 7 -break; -case 235:return 7 -break; -case 236:return 7 -break; -case 237:return 7 -break; -case 238:return 7 -break; -case 239:return 7 -break; -case 240:return 7 -break; -case 241:return 7 -break; -case 242:return 7 -break; -case 243:return 7 -break; -case 244:return 7 -break; -case 245:return 7 -break; -case 246:return 7 -break; -case 247:return 7 -break; -case 248:return 7 -break; -case 249:return 7 -break; -case 250:return 7 -break; -case 251:return 7 -break; -case 252:return 7 -break; -case 253:return 7 -break; -case 254:return 7 -break; -case 255:return 7 -break; -case 256:return 7 -break; -case 257:return 7 -break; -case 258:return 7 -break; -case 259:return 7 -break; -case 260:return 7 -break; -case 261:return 7 -break; -case 262:return 7 -break; -case 263:return 7 -break; -case 264:return 7 -break; -case 265:return 7 -break; -case 266:return 7 -break; -case 267:return 7 -break; -case 268:return 7 -break; -case 269:return 7 -break; -case 270:return 7 -break; -case 271:return 7 -break; -case 272:return 7 -break; -case 273:return 7 -break; -case 274:return 7 -break; -case 275:return 7 -break; -case 276:return 7 -break; -case 277:return 7 -break; -case 278:return 7 -break; -case 279:return 7 -break; -case 280:return 7 -break; -case 281:return 7 -break; -case 282:return 7 -break; -case 283:return 7 -break; -case 284:return 7 -break; -case 285:return 7 -break; -case 286:return 7 -break; -case 287:return 7 -break; -case 288:return 7 -break; -case 289:return 7 -break; -case 290:return 7 -break; -case 291:return 7 -break; -case 292:return 7 -break; -case 293:return 7 -break; -case 294:return 7 -break; -case 295:return 7 -break; -case 296:return 7 -break; -case 297:return 7 -break; -case 298:return 7 -break; -case 299:return 7 -break; -case 300:return 7 -break; -case 301:return 7 -break; -case 302:return 7 -break; -case 303:return 7 -break; -case 304:return 7 -break; -case 305:return 7 -break; -case 306:return 7 -break; -case 307:return 7 -break; -case 308:return 7 -break; -case 309:return 7 -break; -case 310:return 7 -break; -case 311:return 7 -break; -case 312:return 7 -break; -case 313:return 7 -break; -case 314:return 7 -break; -case 315:return 7 -break; -case 316:return 7 -break; -case 317:return 7 -break; -case 318:return 7 -break; -case 319:return 7 -break; -case 320:return 7 -break; -case 321:return 7 -break; -case 322:return 7 -break; -case 323:return 7 -break; -case 324:return 7 -break; -case 325:return 7 -break; -case 326:return 7 -break; -case 327:return 7 -break; -case 328:return 7 -break; -case 329:return 7 -break; -case 330:return 7 -break; -case 331:return 7 -break; -case 332:return 7 -break; -case 333:return 7 -break; -case 334:return 7 -break; -case 335:return 7 -break; -case 336:return 7 -break; -case 337:return 7 -break; -case 338:return 7 -break; -case 339:return 7 -break; -case 340:return 7 -break; -case 341:return 7 -break; -case 342:return 7 -break; -case 343:return 7 -break; -case 344:return 7 -break; -case 345:return 7 -break; -case 346:return 7 -break; -case 347:return 7 -break; -case 348:return 7 -break; -case 349:return 7 -break; -case 350:return 7 -break; -case 351:return 7 -break; -case 352:return 7 -break; -case 353:return 7 -break; -case 354:return 7 -break; -case 355:return 7 -break; -case 356:return 7 -break; -case 357:return 7 -break; -case 358:return 7 -break; -case 359:return 7 -break; -case 360:return 7 -break; -case 361:return 7 -break; -case 362:return 7 -break; -case 363:return 7 -break; -case 364:return 7 -break; +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + if (isIgnored(this, e)) + return + + var abs = this._makeAbs(e) + + if (this.mark) + e = this._mark(e) + + if (this.absolute) { + e = abs + } + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + if (er.code === 'ENOENT') { + // lstat failed, doesn't exist + return null + } + } + + var isSym = lstat && lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + throw error + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return false + } + } + + if (lstat && lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + + this.cache[abs] = this.cache[abs] || c + + if (needDir && c === 'FILE') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + + +/***/ }), +/* 514 */ +/***/ (function(module, exports, __webpack_require__) { + +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var path = __webpack_require__(4) +var minimatch = __webpack_require__(506) +var isAbsolute = __webpack_require__(512) +var Minimatch = minimatch.Minimatch + +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) +} + +function alphasort (a, b) { + return a.localeCompare(b) +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +// ignore patterns are always in dot:true mode. +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern, { dot: true }) + } + + return { + matcher: new Minimatch(pattern, { dot: true }), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + self.absolute = !!options.absolute + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = path.resolve(options.cwd) + self.changedCwd = self.cwd !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + // TODO: is an absolute `cwd` supposed to be resolved against `root`? + // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') + self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) + if (process.platform === "win32") + self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") + self.nomount = !!options.nomount + + // disable comments and negation in Minimatch. + // Note that they are not supported in Glob itself anyway. + options.nonegate = true + options.nocomment = true + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + var notDir = !(/\/$/.test(e)) + var c = self.cache[e] || self.cache[makeAbs(self, e)] + if (notDir && c) + notDir = c !== 'DIR' && !Array.isArray(c) + return notDir + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + + if (process.platform === 'win32') + abs = abs.replace(/\\/g, '/') + + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + + +/***/ }), +/* 515 */ +/***/ (function(module, exports, __webpack_require__) { + +var wrappy = __webpack_require__(379) +var reqs = Object.create(null) +var once = __webpack_require__(378) + +module.exports = wrappy(inflight) + +function inflight (key, cb) { + if (reqs[key]) { + reqs[key].push(cb) + return null + } else { + reqs[key] = [cb] + return makeres(key) + } +} + +function makeres (key) { + return once(function RES () { + var cbs = reqs[key] + var len = cbs.length + var args = slice(arguments) + + // XXX It's somewhat ambiguous whether a new callback added in this + // pass should be queued for later execution if something in the + // list of callbacks throws, or if it should just be discarded. + // However, it's such an edge case that it hardly matters, and either + // choice is likely as surprising as the other. + // As it happens, we do go ahead and schedule it for later execution. + try { + for (var i = 0; i < len; i++) { + cbs[i].apply(null, args) + } + } finally { + if (cbs.length > len) { + // added more in the interim. + // de-zalgo, just in case, but don't call again. + cbs.splice(0, len) + process.nextTick(function () { + RES.apply(null, args) + }) + } else { + delete reqs[key] + } + } + }) +} + +function slice (args) { + var length = args.length + var array = [] + + for (var i = 0; i < length; i++) array[i] = args[i] + return array +} + + +/***/ }), +/* 516 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CliError", function() { return CliError; }); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +class CliError extends Error { + constructor(message, meta = {}) { + super(message); + this.meta = meta; + } + +} + +/***/ }), +/* 517 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Project", function() { return Project; }); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(349); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(397); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(516); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(500); +/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(518); +/* harmony import */ var _scripts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(563); +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; } + +function _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; } + +function _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; } + +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + + + + + +class Project { + static async fromPath(path) { + const pkgJson = await Object(_package_json__WEBPACK_IMPORTED_MODULE_5__["readPackageJson"])(path); + return new Project(pkgJson, path); + } + /** parsed package.json */ + + + constructor(packageJson, projectPath) { + _defineProperty(this, "json", void 0); + + _defineProperty(this, "packageJsonLocation", void 0); + + _defineProperty(this, "nodeModulesLocation", void 0); + + _defineProperty(this, "targetLocation", void 0); + + _defineProperty(this, "path", void 0); + + _defineProperty(this, "version", void 0); + + _defineProperty(this, "allDependencies", void 0); + + _defineProperty(this, "productionDependencies", void 0); + + _defineProperty(this, "devDependencies", void 0); + + _defineProperty(this, "scripts", void 0); + + _defineProperty(this, "isWorkspaceRoot", false); + + _defineProperty(this, "isWorkspaceProject", false); + + this.json = Object.freeze(packageJson); + this.path = projectPath; + this.packageJsonLocation = path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(this.path, 'package.json'); + this.nodeModulesLocation = path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(this.path, 'node_modules'); + this.targetLocation = path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(this.path, 'target'); + this.version = this.json.version; + this.productionDependencies = this.json.dependencies || {}; + this.devDependencies = this.json.devDependencies || {}; + this.allDependencies = _objectSpread({}, this.devDependencies, {}, this.productionDependencies); + this.isWorkspaceRoot = this.json.hasOwnProperty('workspaces'); + this.scripts = this.json.scripts || {}; + } + + get name() { + return this.json.name; + } + + ensureValidProjectDependency(project, dependentProjectIsInWorkspace) { + const versionInPackageJson = this.allDependencies[project.name]; + let expectedVersionInPackageJson; + + if (dependentProjectIsInWorkspace) { + expectedVersionInPackageJson = project.json.version; + } else { + const relativePathToProject = normalizePath(path__WEBPACK_IMPORTED_MODULE_1___default.a.relative(this.path, project.path)); + expectedVersionInPackageJson = `link:${relativePathToProject}`; + } // No issues! + + + if (versionInPackageJson === expectedVersionInPackageJson) { + return; + } + + let problemMsg; + + if (Object(_package_json__WEBPACK_IMPORTED_MODULE_5__["isLinkDependency"])(versionInPackageJson) && dependentProjectIsInWorkspace) { + problemMsg = `but should be using a workspace`; + } else if (Object(_package_json__WEBPACK_IMPORTED_MODULE_5__["isLinkDependency"])(versionInPackageJson)) { + problemMsg = `using 'link:', but the path is wrong`; + } else { + problemMsg = `but it's not using the local package`; + } + + throw new _errors__WEBPACK_IMPORTED_MODULE_3__["CliError"](`[${this.name}] depends on [${project.name}] ${problemMsg}. Update its package.json to the expected value below.`, { + actual: `"${project.name}": "${versionInPackageJson}"`, + expected: `"${project.name}": "${expectedVersionInPackageJson}"`, + package: `${this.name} (${this.packageJsonLocation})` + }); + } + + getBuildConfig() { + return this.json.kibana && this.json.kibana.build || {}; + } + /** + * Returns the directory that should be copied into the Kibana build artifact. + * This config can be specified to only include the project's build artifacts + * instead of everything located in the project directory. + */ + + + getIntermediateBuildDirectory() { + return path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(this.path, this.getBuildConfig().intermediateBuildDirectory || '.'); + } + + getCleanConfig() { + return this.json.kibana && this.json.kibana.clean || {}; + } + + hasScript(name) { + return name in this.scripts; + } + + getExecutables() { + const raw = this.json.bin; + + if (!raw) { + return {}; + } + + if (typeof raw === 'string') { + return { + [this.name]: path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(this.path, raw) + }; + } + + if (typeof raw === 'object') { + const binsConfig = {}; + + for (const binName of Object.keys(raw)) { + binsConfig[binName] = path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(this.path, raw[binName]); + } + + return binsConfig; + } + + throw new _errors__WEBPACK_IMPORTED_MODULE_3__["CliError"](`[${this.name}] has an invalid "bin" field in its package.json, ` + `expected an object or a string`, { + binConfig: Object(util__WEBPACK_IMPORTED_MODULE_2__["inspect"])(raw), + package: `${this.name} (${this.packageJsonLocation})` + }); + } + + async runScript(scriptName, args = []) { + _log__WEBPACK_IMPORTED_MODULE_4__["log"].info(`Running script [${scriptName}] in [${this.name}]:`); + return Object(_scripts__WEBPACK_IMPORTED_MODULE_6__["runScriptInPackage"])(scriptName, args, this); + } + + runScriptStreaming(scriptName, options = {}) { + return Object(_scripts__WEBPACK_IMPORTED_MODULE_6__["runScriptInPackageStreaming"])({ + script: scriptName, + args: options.args || [], + pkg: this, + debug: options.debug + }); + } + + hasDependencies() { + return Object.keys(this.allDependencies).length > 0; + } + + async installDependencies({ + extraArgs + }) { + _log__WEBPACK_IMPORTED_MODULE_4__["log"].info(`[${this.name}] running yarn`); + _log__WEBPACK_IMPORTED_MODULE_4__["log"].write(''); + await Object(_scripts__WEBPACK_IMPORTED_MODULE_6__["installInDir"])(this.path, extraArgs); + _log__WEBPACK_IMPORTED_MODULE_4__["log"].write(''); + await this.removeExtraneousNodeModules(); + } + /** + * Yarn workspaces symlinks workspace projects to the root node_modules, even + * when there is no depenency on the project. This results in unnecicary, and + * often duplicated code in the build archives. + */ + + + async removeExtraneousNodeModules() { + // this is only relevant for the root workspace + if (!this.isWorkspaceRoot) { + return; + } + + const workspacesInfo = await Object(_scripts__WEBPACK_IMPORTED_MODULE_6__["yarnWorkspacesInfo"])(this.path); + const unusedWorkspaces = new Set(Object.keys(workspacesInfo)); // check for any cross-project dependency + + for (const name of Object.keys(workspacesInfo)) { + const workspace = workspacesInfo[name]; + workspace.workspaceDependencies.forEach(w => unusedWorkspaces.delete(w)); + } + + unusedWorkspaces.forEach(name => { + const { + dependencies, + devDependencies + } = this.json; + const nodeModulesPath = path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(this.nodeModulesLocation, name); + const isDependency = dependencies && dependencies.hasOwnProperty(name); + const isDevDependency = devDependencies && devDependencies.hasOwnProperty(name); + + if (!isDependency && !isDevDependency && fs__WEBPACK_IMPORTED_MODULE_0___default.a.existsSync(nodeModulesPath)) { + _log__WEBPACK_IMPORTED_MODULE_4__["log"].debug(`No dependency on ${name}, removing link in node_modules`); + fs__WEBPACK_IMPORTED_MODULE_0___default.a.unlinkSync(nodeModulesPath); + } + }); + } + +} // We normalize all path separators to `/` in generated files + +function normalizePath(path) { + return path.replace(/[\\\/]+/g, '/'); +} + +/***/ }), +/* 518 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readPackageJson", function() { return readPackageJson; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "writePackageJson", function() { return writePackageJson; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isLinkDependency", function() { return isLinkDependency; }); +/* harmony import */ var read_pkg__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(519); +/* harmony import */ var read_pkg__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(read_pkg__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var write_pkg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(545); +/* harmony import */ var write_pkg__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(write_pkg__WEBPACK_IMPORTED_MODULE_1__); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +function readPackageJson(cwd) { + return read_pkg__WEBPACK_IMPORTED_MODULE_0___default()({ + cwd, + normalize: false + }); +} +function writePackageJson(path, json) { + return write_pkg__WEBPACK_IMPORTED_MODULE_1___default()(path, json); +} +const isLinkDependency = depVersion => depVersion.startsWith('link:'); + +/***/ }), +/* 519 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const {promisify} = __webpack_require__(397); +const fs = __webpack_require__(349); +const path = __webpack_require__(4); +const parseJson = __webpack_require__(520); + +const readFileAsync = promisify(fs.readFile); + +module.exports = async options => { + options = { + cwd: process.cwd(), + normalize: true, + ...options + }; + + const filePath = path.resolve(options.cwd, 'package.json'); + const json = parseJson(await readFileAsync(filePath, 'utf8')); + + if (options.normalize) { + __webpack_require__(521)(json); + } + + return json; +}; + +module.exports.sync = options => { + options = { + cwd: process.cwd(), + normalize: true, + ...options + }; + + const filePath = path.resolve(options.cwd, 'package.json'); + const json = parseJson(fs.readFileSync(filePath, 'utf8')); + + if (options.normalize) { + __webpack_require__(521)(json); + } + + return json; +}; + + +/***/ }), +/* 520 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const errorEx = __webpack_require__(416); +const fallback = __webpack_require__(418); +const {default: LinesAndColumns} = __webpack_require__(419); +const {codeFrameColumns} = __webpack_require__(420); + +const JSONError = errorEx('JSONError', { + fileName: errorEx.append('in %s'), + codeFrame: errorEx.append('\n\n%s\n') +}); + +module.exports = (string, reviver, filename) => { + if (typeof reviver === 'string') { + filename = reviver; + reviver = null; + } + + try { + try { + return JSON.parse(string, reviver); + } catch (error) { + fallback(string, reviver); + throw error; + } + } catch (error) { + error.message = error.message.replace(/\n/g, ''); + const indexMatch = error.message.match(/in JSON at position (\d+) while parsing near/); + + const jsonError = new JSONError(error); + if (filename) { + jsonError.fileName = filename; + } + + if (indexMatch && indexMatch.length > 0) { + const lines = new LinesAndColumns(string); + const index = Number(indexMatch[1]); + const location = lines.locationForIndex(index); + + const codeFrame = codeFrameColumns( + string, + {start: {line: location.line + 1, column: location.column + 1}}, + {highlightCode: true} + ); + + jsonError.codeFrame = codeFrame; + } + + throw jsonError; + } +}; + + +/***/ }), +/* 521 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = normalize + +var fixer = __webpack_require__(522) +normalize.fixer = fixer + +var makeWarning = __webpack_require__(543) + +var fieldsToFix = ['name','version','description','repository','modules','scripts' + ,'files','bin','man','bugs','keywords','readme','homepage','license'] +var otherThingsToFix = ['dependencies','people', 'typos'] + +var thingsToFix = fieldsToFix.map(function(fieldName) { + return ucFirst(fieldName) + "Field" +}) +// two ways to do this in CoffeeScript on only one line, sub-70 chars: +// thingsToFix = fieldsToFix.map (name) -> ucFirst(name) + "Field" +// thingsToFix = (ucFirst(name) + "Field" for name in fieldsToFix) +thingsToFix = thingsToFix.concat(otherThingsToFix) + +function normalize (data, warn, strict) { + if(warn === true) warn = null, strict = true + if(!strict) strict = false + if(!warn || data.private) warn = function(msg) { /* noop */ } + + if (data.scripts && + data.scripts.install === "node-gyp rebuild" && + !data.scripts.preinstall) { + data.gypfile = true + } + fixer.warn = function() { warn(makeWarning.apply(null, arguments)) } + thingsToFix.forEach(function(thingName) { + fixer["fix" + ucFirst(thingName)](data, strict) + }) + data._id = data.name + "@" + data.version +} + +function ucFirst (string) { + return string.charAt(0).toUpperCase() + string.slice(1); +} + + +/***/ }), +/* 522 */ +/***/ (function(module, exports, __webpack_require__) { + +var semver = __webpack_require__(523) +var validateLicense = __webpack_require__(524); +var hostedGitInfo = __webpack_require__(529) +var isBuiltinModule = __webpack_require__(532).isCore +var depTypes = ["dependencies","devDependencies","optionalDependencies"] +var extractDescription = __webpack_require__(541) +var url = __webpack_require__(439) +var typos = __webpack_require__(542) + +var fixer = module.exports = { + // default warning function + warn: function() {}, + + fixRepositoryField: function(data) { + if (data.repositories) { + this.warn("repositories"); + data.repository = data.repositories[0] + } + if (!data.repository) return this.warn("missingRepository") + if (typeof data.repository === "string") { + data.repository = { + type: "git", + url: data.repository + } + } + var r = data.repository.url || "" + if (r) { + var hosted = hostedGitInfo.fromUrl(r) + if (hosted) { + r = data.repository.url + = hosted.getDefaultRepresentation() == "shortcut" ? hosted.https() : hosted.toString() + } + } + + if (r.match(/github.com\/[^\/]+\/[^\/]+\.git\.git$/)) { + this.warn("brokenGitUrl", r) + } + } + +, fixTypos: function(data) { + Object.keys(typos.topLevel).forEach(function (d) { + if (data.hasOwnProperty(d)) { + this.warn("typo", d, typos.topLevel[d]) + } + }, this) + } + +, fixScriptsField: function(data) { + if (!data.scripts) return + if (typeof data.scripts !== "object") { + this.warn("nonObjectScripts") + delete data.scripts + return + } + Object.keys(data.scripts).forEach(function (k) { + if (typeof data.scripts[k] !== "string") { + this.warn("nonStringScript") + delete data.scripts[k] + } else if (typos.script[k] && !data.scripts[typos.script[k]]) { + this.warn("typo", k, typos.script[k], "scripts") + } + }, this) + } + +, fixFilesField: function(data) { + var files = data.files + if (files && !Array.isArray(files)) { + this.warn("nonArrayFiles") + delete data.files + } else if (data.files) { + data.files = data.files.filter(function(file) { + if (!file || typeof file !== "string") { + this.warn("invalidFilename", file) + return false + } else { + return true + } + }, this) + } + } + +, fixBinField: function(data) { + if (!data.bin) return; + if (typeof data.bin === "string") { + var b = {} + var match + if (match = data.name.match(/^@[^/]+[/](.*)$/)) { + b[match[1]] = data.bin + } else { + b[data.name] = data.bin + } + data.bin = b + } + } + +, fixManField: function(data) { + if (!data.man) return; + if (typeof data.man === "string") { + data.man = [ data.man ] + } + } +, fixBundleDependenciesField: function(data) { + var bdd = "bundledDependencies" + var bd = "bundleDependencies" + if (data[bdd] && !data[bd]) { + data[bd] = data[bdd] + delete data[bdd] + } + if (data[bd] && !Array.isArray(data[bd])) { + this.warn("nonArrayBundleDependencies") + delete data[bd] + } else if (data[bd]) { + data[bd] = data[bd].filter(function(bd) { + if (!bd || typeof bd !== 'string') { + this.warn("nonStringBundleDependency", bd) + return false + } else { + if (!data.dependencies) { + data.dependencies = {} + } + if (!data.dependencies.hasOwnProperty(bd)) { + this.warn("nonDependencyBundleDependency", bd) + data.dependencies[bd] = "*" + } + return true + } + }, this) + } + } + +, fixDependencies: function(data, strict) { + var loose = !strict + objectifyDeps(data, this.warn) + addOptionalDepsToDeps(data, this.warn) + this.fixBundleDependenciesField(data) + + ;['dependencies','devDependencies'].forEach(function(deps) { + if (!(deps in data)) return + if (!data[deps] || typeof data[deps] !== "object") { + this.warn("nonObjectDependencies", deps) + delete data[deps] + return + } + Object.keys(data[deps]).forEach(function (d) { + var r = data[deps][d] + if (typeof r !== 'string') { + this.warn("nonStringDependency", d, JSON.stringify(r)) + delete data[deps][d] + } + var hosted = hostedGitInfo.fromUrl(data[deps][d]) + if (hosted) data[deps][d] = hosted.toString() + }, this) + }, this) + } + +, fixModulesField: function (data) { + if (data.modules) { + this.warn("deprecatedModules") + delete data.modules + } + } + +, fixKeywordsField: function (data) { + if (typeof data.keywords === "string") { + data.keywords = data.keywords.split(/,\s+/) + } + if (data.keywords && !Array.isArray(data.keywords)) { + delete data.keywords + this.warn("nonArrayKeywords") + } else if (data.keywords) { + data.keywords = data.keywords.filter(function(kw) { + if (typeof kw !== "string" || !kw) { + this.warn("nonStringKeyword"); + return false + } else { + return true + } + }, this) + } + } + +, fixVersionField: function(data, strict) { + // allow "loose" semver 1.0 versions in non-strict mode + // enforce strict semver 2.0 compliance in strict mode + var loose = !strict + if (!data.version) { + data.version = "" + return true + } + if (!semver.valid(data.version, loose)) { + throw new Error('Invalid version: "'+ data.version + '"') + } + data.version = semver.clean(data.version, loose) + return true + } + +, fixPeople: function(data) { + modifyPeople(data, unParsePerson) + modifyPeople(data, parsePerson) + } + +, fixNameField: function(data, options) { + if (typeof options === "boolean") options = {strict: options} + else if (typeof options === "undefined") options = {} + var strict = options.strict + if (!data.name && !strict) { + data.name = "" + return + } + if (typeof data.name !== "string") { + throw new Error("name field must be a string.") + } + if (!strict) + data.name = data.name.trim() + ensureValidName(data.name, strict, options.allowLegacyCase) + if (isBuiltinModule(data.name)) + this.warn("conflictingName", data.name) + } + + +, fixDescriptionField: function (data) { + if (data.description && typeof data.description !== 'string') { + this.warn("nonStringDescription") + delete data.description + } + if (data.readme && !data.description) + data.description = extractDescription(data.readme) + if(data.description === undefined) delete data.description; + if (!data.description) this.warn("missingDescription") + } + +, fixReadmeField: function (data) { + if (!data.readme) { + this.warn("missingReadme") + data.readme = "ERROR: No README data found!" + } + } + +, fixBugsField: function(data) { + if (!data.bugs && data.repository && data.repository.url) { + var hosted = hostedGitInfo.fromUrl(data.repository.url) + if(hosted && hosted.bugs()) { + data.bugs = {url: hosted.bugs()} + } + } + else if(data.bugs) { + var emailRe = /^.+@.*\..+$/ + if(typeof data.bugs == "string") { + if(emailRe.test(data.bugs)) + data.bugs = {email:data.bugs} + else if(url.parse(data.bugs).protocol) + data.bugs = {url: data.bugs} + else + this.warn("nonEmailUrlBugsString") + } + else { + bugsTypos(data.bugs, this.warn) + var oldBugs = data.bugs + data.bugs = {} + if(oldBugs.url) { + if(typeof(oldBugs.url) == "string" && url.parse(oldBugs.url).protocol) + data.bugs.url = oldBugs.url + else + this.warn("nonUrlBugsUrlField") + } + if(oldBugs.email) { + if(typeof(oldBugs.email) == "string" && emailRe.test(oldBugs.email)) + data.bugs.email = oldBugs.email + else + this.warn("nonEmailBugsEmailField") + } + } + if(!data.bugs.email && !data.bugs.url) { + delete data.bugs + this.warn("emptyNormalizedBugs") + } + } + } + +, fixHomepageField: function(data) { + if (!data.homepage && data.repository && data.repository.url) { + var hosted = hostedGitInfo.fromUrl(data.repository.url) + if (hosted && hosted.docs()) data.homepage = hosted.docs() + } + if (!data.homepage) return + + if(typeof data.homepage !== "string") { + this.warn("nonUrlHomepage") + return delete data.homepage + } + if(!url.parse(data.homepage).protocol) { + data.homepage = "http://" + data.homepage + } + } + +, fixLicenseField: function(data) { + if (!data.license) { + return this.warn("missingLicense") + } else{ + if ( + typeof(data.license) !== 'string' || + data.license.length < 1 || + data.license.trim() === '' + ) { + this.warn("invalidLicense") + } else { + if (!validateLicense(data.license).validForNewPackages) + this.warn("invalidLicense") + } + } + } +} + +function isValidScopedPackageName(spec) { + if (spec.charAt(0) !== '@') return false + + var rest = spec.slice(1).split('/') + if (rest.length !== 2) return false + + return rest[0] && rest[1] && + rest[0] === encodeURIComponent(rest[0]) && + rest[1] === encodeURIComponent(rest[1]) +} + +function isCorrectlyEncodedName(spec) { + return !spec.match(/[\/@\s\+%:]/) && + spec === encodeURIComponent(spec) +} + +function ensureValidName (name, strict, allowLegacyCase) { + if (name.charAt(0) === "." || + !(isValidScopedPackageName(name) || isCorrectlyEncodedName(name)) || + (strict && (!allowLegacyCase) && name !== name.toLowerCase()) || + name.toLowerCase() === "node_modules" || + name.toLowerCase() === "favicon.ico") { + throw new Error("Invalid name: " + JSON.stringify(name)) + } +} + +function modifyPeople (data, fn) { + if (data.author) data.author = fn(data.author) + ;["maintainers", "contributors"].forEach(function (set) { + if (!Array.isArray(data[set])) return; + data[set] = data[set].map(fn) + }) + return data +} + +function unParsePerson (person) { + if (typeof person === "string") return person + var name = person.name || "" + var u = person.url || person.web + var url = u ? (" ("+u+")") : "" + var e = person.email || person.mail + var email = e ? (" <"+e+">") : "" + return name+email+url +} + +function parsePerson (person) { + if (typeof person !== "string") return person + var name = person.match(/^([^\(<]+)/) + var url = person.match(/\(([^\)]+)\)/) + var email = person.match(/<([^>]+)>/) + var obj = {} + if (name && name[0].trim()) obj.name = name[0].trim() + if (email) obj.email = email[1]; + if (url) obj.url = url[1]; + return obj +} + +function addOptionalDepsToDeps (data, warn) { + var o = data.optionalDependencies + if (!o) return; + var d = data.dependencies || {} + Object.keys(o).forEach(function (k) { + d[k] = o[k] + }) + data.dependencies = d +} + +function depObjectify (deps, type, warn) { + if (!deps) return {} + if (typeof deps === "string") { + deps = deps.trim().split(/[\n\r\s\t ,]+/) + } + if (!Array.isArray(deps)) return deps + warn("deprecatedArrayDependencies", type) + var o = {} + deps.filter(function (d) { + return typeof d === "string" + }).forEach(function(d) { + d = d.trim().split(/(:?[@\s><=])/) + var dn = d.shift() + var dv = d.join("") + dv = dv.trim() + dv = dv.replace(/^@/, "") + o[dn] = dv + }) + return o +} + +function objectifyDeps (data, warn) { + depTypes.forEach(function (type) { + if (!data[type]) return; + data[type] = depObjectify(data[type], type, warn) + }) +} + +function bugsTypos(bugs, warn) { + if (!bugs) return + Object.keys(bugs).forEach(function (k) { + if (typos.bugs[k]) { + warn("typo", k, typos.bugs[k], "bugs") + bugs[typos.bugs[k]] = bugs[k] + delete bugs[k] + } + }) +} + + +/***/ }), +/* 523 */ +/***/ (function(module, exports) { + +exports = module.exports = SemVer + +var debug +/* istanbul ignore next */ +if (typeof process === 'object' && + process.env && + process.env.NODE_DEBUG && + /\bsemver\b/i.test(process.env.NODE_DEBUG)) { + debug = function () { + var args = Array.prototype.slice.call(arguments, 0) + args.unshift('SEMVER') + console.log.apply(console, args) + } +} else { + debug = function () {} +} + +// Note: this is the semver.org version of the spec that it implements +// Not necessarily the package version of this code. +exports.SEMVER_SPEC_VERSION = '2.0.0' + +var MAX_LENGTH = 256 +var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || + /* istanbul ignore next */ 9007199254740991 + +// Max safe segment length for coercion. +var MAX_SAFE_COMPONENT_LENGTH = 16 + +// The actual regexps go on exports.re +var re = exports.re = [] +var src = exports.src = [] +var R = 0 + +// The following Regular Expressions can be used for tokenizing, +// validating, and parsing SemVer version strings. + +// ## Numeric Identifier +// A single `0`, or a non-zero digit followed by zero or more digits. + +var NUMERICIDENTIFIER = R++ +src[NUMERICIDENTIFIER] = '0|[1-9]\\d*' +var NUMERICIDENTIFIERLOOSE = R++ +src[NUMERICIDENTIFIERLOOSE] = '[0-9]+' + +// ## Non-numeric Identifier +// Zero or more digits, followed by a letter or hyphen, and then zero or +// more letters, digits, or hyphens. + +var NONNUMERICIDENTIFIER = R++ +src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*' + +// ## Main Version +// Three dot-separated numeric identifiers. + +var MAINVERSION = R++ +src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')\\.' + + '(' + src[NUMERICIDENTIFIER] + ')' + +var MAINVERSIONLOOSE = R++ +src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + + '(' + src[NUMERICIDENTIFIERLOOSE] + ')' + +// ## Pre-release Version Identifier +// A numeric identifier, or a non-numeric identifier. + +var PRERELEASEIDENTIFIER = R++ +src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + + '|' + src[NONNUMERICIDENTIFIER] + ')' + +var PRERELEASEIDENTIFIERLOOSE = R++ +src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + + '|' + src[NONNUMERICIDENTIFIER] + ')' + +// ## Pre-release Version +// Hyphen, followed by one or more dot-separated pre-release version +// identifiers. + +var PRERELEASE = R++ +src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + + '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))' + +var PRERELEASELOOSE = R++ +src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + + '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))' + +// ## Build Metadata Identifier +// Any combination of digits, letters, or hyphens. + +var BUILDIDENTIFIER = R++ +src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+' + +// ## Build Metadata +// Plus sign, followed by one or more period-separated build metadata +// identifiers. + +var BUILD = R++ +src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + + '(?:\\.' + src[BUILDIDENTIFIER] + ')*))' + +// ## Full Version String +// A main version, followed optionally by a pre-release version and +// build metadata. + +// Note that the only major, minor, patch, and pre-release sections of +// the version string are capturing groups. The build metadata is not a +// capturing group, because it should not ever be used in version +// comparison. + +var FULL = R++ +var FULLPLAIN = 'v?' + src[MAINVERSION] + + src[PRERELEASE] + '?' + + src[BUILD] + '?' + +src[FULL] = '^' + FULLPLAIN + '$' + +// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. +// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty +// common in the npm registry. +var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + + src[PRERELEASELOOSE] + '?' + + src[BUILD] + '?' + +var LOOSE = R++ +src[LOOSE] = '^' + LOOSEPLAIN + '$' + +var GTLT = R++ +src[GTLT] = '((?:<|>)?=?)' + +// Something like "2.*" or "1.2.x". +// Note that "x.x" is a valid xRange identifer, meaning "any version" +// Only the first item is strictly required. +var XRANGEIDENTIFIERLOOSE = R++ +src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*' +var XRANGEIDENTIFIER = R++ +src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*' + +var XRANGEPLAIN = R++ +src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + + '(?:' + src[PRERELEASE] + ')?' + + src[BUILD] + '?' + + ')?)?' + +var XRANGEPLAINLOOSE = R++ +src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + + '(?:' + src[PRERELEASELOOSE] + ')?' + + src[BUILD] + '?' + + ')?)?' + +var XRANGE = R++ +src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$' +var XRANGELOOSE = R++ +src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$' + +// Coercion. +// Extract anything that could conceivably be a part of a valid semver +var COERCE = R++ +src[COERCE] = '(?:^|[^\\d])' + + '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' + + '(?:$|[^\\d])' + +// Tilde ranges. +// Meaning is "reasonably at or greater than" +var LONETILDE = R++ +src[LONETILDE] = '(?:~>?)' + +var TILDETRIM = R++ +src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+' +re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g') +var tildeTrimReplace = '$1~' + +var TILDE = R++ +src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$' +var TILDELOOSE = R++ +src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$' + +// Caret ranges. +// Meaning is "at least and backwards compatible with" +var LONECARET = R++ +src[LONECARET] = '(?:\\^)' + +var CARETTRIM = R++ +src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+' +re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g') +var caretTrimReplace = '$1^' + +var CARET = R++ +src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$' +var CARETLOOSE = R++ +src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$' + +// A simple gt/lt/eq thing, or just "" to indicate "any version" +var COMPARATORLOOSE = R++ +src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$' +var COMPARATOR = R++ +src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$' + +// An expression to strip any whitespace between the gtlt and the thing +// it modifies, so that `> 1.2.3` ==> `>1.2.3` +var COMPARATORTRIM = R++ +src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + + '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')' + +// this one has to use the /g flag +re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g') +var comparatorTrimReplace = '$1$2$3' + +// Something like `1.2.3 - 1.2.4` +// Note that these all use the loose form, because they'll be +// checked against either the strict or loose comparator form +// later. +var HYPHENRANGE = R++ +src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAIN] + ')' + + '\\s*$' + +var HYPHENRANGELOOSE = R++ +src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s+-\\s+' + + '(' + src[XRANGEPLAINLOOSE] + ')' + + '\\s*$' + +// Star ranges basically just allow anything at all. +var STAR = R++ +src[STAR] = '(<|>)?=?\\s*\\*' + +// Compile to actual regexp objects. +// All are flag-free, unless they were created above with a flag. +for (var i = 0; i < R; i++) { + debug(i, src[i]) + if (!re[i]) { + re[i] = new RegExp(src[i]) + } +} + +exports.parse = parse +function parse (version, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (version instanceof SemVer) { + return version + } + + if (typeof version !== 'string') { + return null + } + + if (version.length > MAX_LENGTH) { + return null + } + + var r = options.loose ? re[LOOSE] : re[FULL] + if (!r.test(version)) { + return null + } + + try { + return new SemVer(version, options) + } catch (er) { + return null + } +} + +exports.valid = valid +function valid (version, options) { + var v = parse(version, options) + return v ? v.version : null +} + +exports.clean = clean +function clean (version, options) { + var s = parse(version.trim().replace(/^[=v]+/, ''), options) + return s ? s.version : null +} + +exports.SemVer = SemVer + +function SemVer (version, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + if (version instanceof SemVer) { + if (version.loose === options.loose) { + return version + } else { + version = version.version + } + } else if (typeof version !== 'string') { + throw new TypeError('Invalid Version: ' + version) + } + + if (version.length > MAX_LENGTH) { + throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') + } + + if (!(this instanceof SemVer)) { + return new SemVer(version, options) + } + + debug('SemVer', version, options) + this.options = options + this.loose = !!options.loose + + var m = version.trim().match(options.loose ? re[LOOSE] : re[FULL]) + + if (!m) { + throw new TypeError('Invalid Version: ' + version) + } + + this.raw = version + + // these are actually numbers + this.major = +m[1] + this.minor = +m[2] + this.patch = +m[3] + + if (this.major > MAX_SAFE_INTEGER || this.major < 0) { + throw new TypeError('Invalid major version') + } + + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { + throw new TypeError('Invalid minor version') + } + + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { + throw new TypeError('Invalid patch version') + } + + // numberify any prerelease numeric ids + if (!m[4]) { + this.prerelease = [] + } else { + this.prerelease = m[4].split('.').map(function (id) { + if (/^[0-9]+$/.test(id)) { + var num = +id + if (num >= 0 && num < MAX_SAFE_INTEGER) { + return num + } + } + return id + }) + } + + this.build = m[5] ? m[5].split('.') : [] + this.format() } -}, -rules: [/^(?:$)/,/^(?:\s+)/,/^(?:\+)/,/^(?:\()/,/^(?:\))/,/^(?::)/,/^(?:DocumentRef-([0-9A-Za-z-+.]+))/,/^(?:LicenseRef-([0-9A-Za-z-+.]+))/,/^(?:AND)/,/^(?:OR)/,/^(?:WITH)/,/^(?:BSD-3-Clause-No-Nuclear-License-2014)/,/^(?:BSD-3-Clause-No-Nuclear-Warranty)/,/^(?:GPL-2\.0-with-classpath-exception)/,/^(?:GPL-3\.0-with-autoconf-exception)/,/^(?:GPL-2\.0-with-autoconf-exception)/,/^(?:BSD-3-Clause-No-Nuclear-License)/,/^(?:MPL-2\.0-no-copyleft-exception)/,/^(?:GPL-2\.0-with-bison-exception)/,/^(?:GPL-2\.0-with-font-exception)/,/^(?:GPL-2\.0-with-GCC-exception)/,/^(?:CNRI-Python-GPL-Compatible)/,/^(?:GPL-3\.0-with-GCC-exception)/,/^(?:BSD-3-Clause-Attribution)/,/^(?:Classpath-exception-2\.0)/,/^(?:WxWindows-exception-3\.1)/,/^(?:freertos-exception-2\.0)/,/^(?:Autoconf-exception-3\.0)/,/^(?:i2p-gpl-java-exception)/,/^(?:gnu-javamail-exception)/,/^(?:Nokia-Qt-exception-1\.1)/,/^(?:Autoconf-exception-2\.0)/,/^(?:BSD-2-Clause-FreeBSD)/,/^(?:u-boot-exception-2\.0)/,/^(?:zlib-acknowledgement)/,/^(?:Bison-exception-2\.2)/,/^(?:BSD-2-Clause-NetBSD)/,/^(?:CLISP-exception-2\.0)/,/^(?:eCos-exception-2\.0)/,/^(?:BSD-3-Clause-Clear)/,/^(?:Font-exception-2\.0)/,/^(?:FLTK-exception-2\.0)/,/^(?:GCC-exception-2\.0)/,/^(?:Qwt-exception-1\.0)/,/^(?:Libtool-exception)/,/^(?:BSD-3-Clause-LBNL)/,/^(?:GCC-exception-3\.1)/,/^(?:Artistic-1\.0-Perl)/,/^(?:Artistic-1\.0-cl8)/,/^(?:CC-BY-NC-SA-2\.5)/,/^(?:MIT-advertising)/,/^(?:BSD-Source-Code)/,/^(?:CC-BY-NC-SA-4\.0)/,/^(?:LiLiQ-Rplus-1\.1)/,/^(?:CC-BY-NC-SA-3\.0)/,/^(?:BSD-4-Clause-UC)/,/^(?:CC-BY-NC-SA-2\.0)/,/^(?:CC-BY-NC-SA-1\.0)/,/^(?:CC-BY-NC-ND-4\.0)/,/^(?:CC-BY-NC-ND-3\.0)/,/^(?:CC-BY-NC-ND-2\.5)/,/^(?:CC-BY-NC-ND-2\.0)/,/^(?:CC-BY-NC-ND-1\.0)/,/^(?:LZMA-exception)/,/^(?:BitTorrent-1\.1)/,/^(?:CrystalStacker)/,/^(?:FLTK-exception)/,/^(?:SugarCRM-1\.1\.3)/,/^(?:BSD-Protection)/,/^(?:BitTorrent-1\.0)/,/^(?:HaskellReport)/,/^(?:Interbase-1\.0)/,/^(?:StandardML-NJ)/,/^(?:mif-exception)/,/^(?:Frameworx-1\.0)/,/^(?:389-exception)/,/^(?:CC-BY-NC-2\.0)/,/^(?:CC-BY-NC-2\.5)/,/^(?:CC-BY-NC-3\.0)/,/^(?:CC-BY-NC-4\.0)/,/^(?:W3C-19980720)/,/^(?:CC-BY-SA-1\.0)/,/^(?:CC-BY-SA-2\.0)/,/^(?:CC-BY-SA-2\.5)/,/^(?:CC-BY-ND-2\.0)/,/^(?:CC-BY-SA-4\.0)/,/^(?:CC-BY-SA-3\.0)/,/^(?:Artistic-1\.0)/,/^(?:Artistic-2\.0)/,/^(?:CC-BY-ND-2\.5)/,/^(?:CC-BY-ND-3\.0)/,/^(?:CC-BY-ND-4\.0)/,/^(?:CC-BY-ND-1\.0)/,/^(?:BSD-4-Clause)/,/^(?:BSD-3-Clause)/,/^(?:BSD-2-Clause)/,/^(?:CC-BY-NC-1\.0)/,/^(?:bzip2-1\.0\.6)/,/^(?:Unicode-TOU)/,/^(?:CNRI-Jython)/,/^(?:ImageMagick)/,/^(?:Adobe-Glyph)/,/^(?:CUA-OPL-1\.0)/,/^(?:OLDAP-2\.2\.2)/,/^(?:LiLiQ-R-1\.1)/,/^(?:bzip2-1\.0\.5)/,/^(?:LiLiQ-P-1\.1)/,/^(?:OLDAP-2\.0\.1)/,/^(?:OLDAP-2\.2\.1)/,/^(?:CNRI-Python)/,/^(?:XFree86-1\.1)/,/^(?:OSET-PL-2\.1)/,/^(?:Apache-2\.0)/,/^(?:Watcom-1\.0)/,/^(?:PostgreSQL)/,/^(?:Python-2\.0)/,/^(?:RHeCos-1\.1)/,/^(?:EUDatagrid)/,/^(?:Spencer-99)/,/^(?:Intel-ACPI)/,/^(?:CECILL-1\.0)/,/^(?:CECILL-1\.1)/,/^(?:JasPer-2\.0)/,/^(?:CECILL-2\.0)/,/^(?:CECILL-2\.1)/,/^(?:gSOAP-1\.3b)/,/^(?:Spencer-94)/,/^(?:Apache-1\.1)/,/^(?:Spencer-86)/,/^(?:Apache-1\.0)/,/^(?:ClArtistic)/,/^(?:TORQUE-1\.1)/,/^(?:CATOSL-1\.1)/,/^(?:Adobe-2006)/,/^(?:Zimbra-1\.4)/,/^(?:Zimbra-1\.3)/,/^(?:Condor-1\.1)/,/^(?:CC-BY-3\.0)/,/^(?:CC-BY-2\.5)/,/^(?:OLDAP-2\.4)/,/^(?:SGI-B-1\.1)/,/^(?:SISSL-1\.2)/,/^(?:SGI-B-1\.0)/,/^(?:OLDAP-2\.3)/,/^(?:CC-BY-4\.0)/,/^(?:Crossword)/,/^(?:SimPL-2\.0)/,/^(?:OLDAP-2\.2)/,/^(?:OLDAP-2\.1)/,/^(?:ErlPL-1\.1)/,/^(?:LPPL-1\.3a)/,/^(?:LPPL-1\.3c)/,/^(?:OLDAP-2\.0)/,/^(?:Leptonica)/,/^(?:CPOL-1\.02)/,/^(?:OLDAP-1\.4)/,/^(?:OLDAP-1\.3)/,/^(?:CC-BY-2\.0)/,/^(?:Unlicense)/,/^(?:OLDAP-2\.8)/,/^(?:OLDAP-1\.2)/,/^(?:MakeIndex)/,/^(?:OLDAP-2\.7)/,/^(?:OLDAP-1\.1)/,/^(?:Sleepycat)/,/^(?:D-FSL-1\.0)/,/^(?:CC-BY-1\.0)/,/^(?:OLDAP-2\.6)/,/^(?:WXwindows)/,/^(?:NPOSL-3\.0)/,/^(?:FreeImage)/,/^(?:SGI-B-2\.0)/,/^(?:OLDAP-2\.5)/,/^(?:Beerware)/,/^(?:Newsletr)/,/^(?:NBPL-1\.0)/,/^(?:NASA-1\.3)/,/^(?:NLOD-1\.0)/,/^(?:AGPL-1\.0)/,/^(?:OCLC-2\.0)/,/^(?:ODbL-1\.0)/,/^(?:PDDL-1\.0)/,/^(?:Motosoto)/,/^(?:Afmparse)/,/^(?:ANTLR-PD)/,/^(?:LPL-1\.02)/,/^(?:Abstyles)/,/^(?:eCos-2\.0)/,/^(?:APSL-1\.0)/,/^(?:LPPL-1\.2)/,/^(?:LPPL-1\.1)/,/^(?:LPPL-1\.0)/,/^(?:APSL-1\.1)/,/^(?:APSL-2\.0)/,/^(?:Info-ZIP)/,/^(?:Zend-2\.0)/,/^(?:IBM-pibs)/,/^(?:LGPL-2\.0)/,/^(?:LGPL-3\.0)/,/^(?:LGPL-2\.1)/,/^(?:GFDL-1\.3)/,/^(?:PHP-3\.01)/,/^(?:GFDL-1\.2)/,/^(?:GFDL-1\.1)/,/^(?:AGPL-3\.0)/,/^(?:Giftware)/,/^(?:EUPL-1\.1)/,/^(?:RPSL-1\.0)/,/^(?:EUPL-1\.0)/,/^(?:MIT-enna)/,/^(?:CECILL-B)/,/^(?:diffmark)/,/^(?:CECILL-C)/,/^(?:CDDL-1\.0)/,/^(?:Sendmail)/,/^(?:CDDL-1\.1)/,/^(?:CPAL-1\.0)/,/^(?:APSL-1\.2)/,/^(?:NPL-1\.1)/,/^(?:AFL-1\.2)/,/^(?:Caldera)/,/^(?:AFL-2\.0)/,/^(?:FSFULLR)/,/^(?:AFL-2\.1)/,/^(?:VSL-1\.0)/,/^(?:VOSTROM)/,/^(?:UPL-1\.0)/,/^(?:Dotseqn)/,/^(?:CPL-1\.0)/,/^(?:dvipdfm)/,/^(?:EPL-1\.0)/,/^(?:OCCT-PL)/,/^(?:ECL-1\.0)/,/^(?:Latex2e)/,/^(?:ECL-2\.0)/,/^(?:GPL-1\.0)/,/^(?:GPL-2\.0)/,/^(?:GPL-3\.0)/,/^(?:AFL-3\.0)/,/^(?:LAL-1\.2)/,/^(?:LAL-1\.3)/,/^(?:EFL-1\.0)/,/^(?:EFL-2\.0)/,/^(?:gnuplot)/,/^(?:Aladdin)/,/^(?:LPL-1\.0)/,/^(?:libtiff)/,/^(?:Entessa)/,/^(?:AMDPLPA)/,/^(?:IPL-1\.0)/,/^(?:OPL-1\.0)/,/^(?:OSL-1\.0)/,/^(?:OSL-1\.1)/,/^(?:OSL-2\.0)/,/^(?:OSL-2\.1)/,/^(?:OSL-3\.0)/,/^(?:OpenSSL)/,/^(?:ZPL-2\.1)/,/^(?:PHP-3\.0)/,/^(?:ZPL-2\.0)/,/^(?:ZPL-1\.1)/,/^(?:CC0-1\.0)/,/^(?:SPL-1\.0)/,/^(?:psutils)/,/^(?:MPL-1\.0)/,/^(?:QPL-1\.0)/,/^(?:MPL-1\.1)/,/^(?:MPL-2\.0)/,/^(?:APL-1\.0)/,/^(?:RPL-1\.1)/,/^(?:RPL-1\.5)/,/^(?:MIT-CMU)/,/^(?:Multics)/,/^(?:Eurosym)/,/^(?:BSL-1\.0)/,/^(?:MIT-feh)/,/^(?:Saxpath)/,/^(?:Borceux)/,/^(?:OFL-1\.1)/,/^(?:OFL-1\.0)/,/^(?:AFL-1\.1)/,/^(?:YPL-1\.1)/,/^(?:YPL-1\.0)/,/^(?:NPL-1\.0)/,/^(?:iMatix)/,/^(?:mpich2)/,/^(?:APAFML)/,/^(?:Bahyph)/,/^(?:RSA-MD)/,/^(?:psfrag)/,/^(?:Plexus)/,/^(?:eGenix)/,/^(?:Glulxe)/,/^(?:SAX-PD)/,/^(?:Imlib2)/,/^(?:Wsuipa)/,/^(?:LGPLLR)/,/^(?:Libpng)/,/^(?:xinetd)/,/^(?:MITNFA)/,/^(?:NetCDF)/,/^(?:Naumen)/,/^(?:SMPPL)/,/^(?:Nunit)/,/^(?:FSFUL)/,/^(?:GL2PS)/,/^(?:SMLNJ)/,/^(?:Rdisc)/,/^(?:Noweb)/,/^(?:Nokia)/,/^(?:SISSL)/,/^(?:Qhull)/,/^(?:Intel)/,/^(?:Glide)/,/^(?:Xerox)/,/^(?:AMPAS)/,/^(?:WTFPL)/,/^(?:MS-PL)/,/^(?:XSkat)/,/^(?:MS-RL)/,/^(?:MirOS)/,/^(?:RSCPL)/,/^(?:TMate)/,/^(?:OGTSL)/,/^(?:FSFAP)/,/^(?:NCSA)/,/^(?:Zlib)/,/^(?:SCEA)/,/^(?:SNIA)/,/^(?:NGPL)/,/^(?:NOSL)/,/^(?:ADSL)/,/^(?:MTLL)/,/^(?:NLPL)/,/^(?:Ruby)/,/^(?:JSON)/,/^(?:Barr)/,/^(?:0BSD)/,/^(?:Xnet)/,/^(?:Cube)/,/^(?:curl)/,/^(?:DSDP)/,/^(?:Fair)/,/^(?:HPND)/,/^(?:TOSL)/,/^(?:IJG)/,/^(?:SWL)/,/^(?:Vim)/,/^(?:FTL)/,/^(?:ICU)/,/^(?:OML)/,/^(?:NRL)/,/^(?:DOC)/,/^(?:TCL)/,/^(?:W3C)/,/^(?:NTP)/,/^(?:IPA)/,/^(?:ISC)/,/^(?:X11)/,/^(?:AAL)/,/^(?:AML)/,/^(?:xpp)/,/^(?:Zed)/,/^(?:MIT)/,/^(?:Mup)/], -conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364],"inclusive":true}} -}); -return lexer; -})(); -parser.lexer = lexer; -function Parser () { - this.yy = {}; + +SemVer.prototype.format = function () { + this.version = this.major + '.' + this.minor + '.' + this.patch + if (this.prerelease.length) { + this.version += '-' + this.prerelease.join('.') + } + return this.version } -Parser.prototype = parser;parser.Parser = Parser; -return new Parser; -})(); +SemVer.prototype.toString = function () { + return this.version +} + +SemVer.prototype.compare = function (other) { + debug('SemVer.compare', this.version, this.options, other) + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + return this.compareMain(other) || this.comparePre(other) +} + +SemVer.prototype.compareMain = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + return compareIdentifiers(this.major, other.major) || + compareIdentifiers(this.minor, other.minor) || + compareIdentifiers(this.patch, other.patch) +} + +SemVer.prototype.comparePre = function (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + // NOT having a prerelease is > having one + if (this.prerelease.length && !other.prerelease.length) { + return -1 + } else if (!this.prerelease.length && other.prerelease.length) { + return 1 + } else if (!this.prerelease.length && !other.prerelease.length) { + return 0 + } + + var i = 0 + do { + var a = this.prerelease[i] + var b = other.prerelease[i] + debug('prerelease compare', i, a, b) + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) +} + +// preminor will bump the version up to the next minor release, and immediately +// down to pre-release. premajor and prepatch work the same way. +SemVer.prototype.inc = function (release, identifier) { + switch (release) { + case 'premajor': + this.prerelease.length = 0 + this.patch = 0 + this.minor = 0 + this.major++ + this.inc('pre', identifier) + break + case 'preminor': + this.prerelease.length = 0 + this.patch = 0 + this.minor++ + this.inc('pre', identifier) + break + case 'prepatch': + // If this is already a prerelease, it will bump to the next version + // drop any prereleases that might already exist, since they are not + // relevant at this point. + this.prerelease.length = 0 + this.inc('patch', identifier) + this.inc('pre', identifier) + break + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case 'prerelease': + if (this.prerelease.length === 0) { + this.inc('patch', identifier) + } + this.inc('pre', identifier) + break + + case 'major': + // If this is a pre-major version, bump up to the same major version. + // Otherwise increment major. + // 1.0.0-5 bumps to 1.0.0 + // 1.1.0 bumps to 2.0.0 + if (this.minor !== 0 || + this.patch !== 0 || + this.prerelease.length === 0) { + this.major++ + } + this.minor = 0 + this.patch = 0 + this.prerelease = [] + break + case 'minor': + // If this is a pre-minor version, bump up to the same minor version. + // Otherwise increment minor. + // 1.2.0-5 bumps to 1.2.0 + // 1.2.1 bumps to 1.3.0 + if (this.patch !== 0 || this.prerelease.length === 0) { + this.minor++ + } + this.patch = 0 + this.prerelease = [] + break + case 'patch': + // If this is not a pre-release version, it will increment the patch. + // If it is a pre-release it will bump up to the same patch version. + // 1.2.0-5 patches to 1.2.0 + // 1.2.0 patches to 1.2.1 + if (this.prerelease.length === 0) { + this.patch++ + } + this.prerelease = [] + break + // This probably shouldn't be used publicly. + // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. + case 'pre': + if (this.prerelease.length === 0) { + this.prerelease = [0] + } else { + var i = this.prerelease.length + while (--i >= 0) { + if (typeof this.prerelease[i] === 'number') { + this.prerelease[i]++ + i = -2 + } + } + if (i === -1) { + // didn't increment anything + this.prerelease.push(0) + } + } + if (identifier) { + // 1.2.0-beta.1 bumps to 1.2.0-beta.2, + // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + if (this.prerelease[0] === identifier) { + if (isNaN(this.prerelease[1])) { + this.prerelease = [identifier, 0] + } + } else { + this.prerelease = [identifier, 0] + } + } + break + + default: + throw new Error('invalid increment argument: ' + release) + } + this.format() + this.raw = this.version + return this +} + +exports.inc = inc +function inc (version, release, loose, identifier) { + if (typeof (loose) === 'string') { + identifier = loose + loose = undefined + } + + try { + return new SemVer(version, loose).inc(release, identifier).version + } catch (er) { + return null + } +} + +exports.diff = diff +function diff (version1, version2) { + if (eq(version1, version2)) { + return null + } else { + var v1 = parse(version1) + var v2 = parse(version2) + var prefix = '' + if (v1.prerelease.length || v2.prerelease.length) { + prefix = 'pre' + var defaultResult = 'prerelease' + } + for (var key in v1) { + if (key === 'major' || key === 'minor' || key === 'patch') { + if (v1[key] !== v2[key]) { + return prefix + key + } + } + } + return defaultResult // may be undefined + } +} + +exports.compareIdentifiers = compareIdentifiers + +var numeric = /^[0-9]+$/ +function compareIdentifiers (a, b) { + var anum = numeric.test(a) + var bnum = numeric.test(b) + + if (anum && bnum) { + a = +a + b = +b + } + + return a === b ? 0 + : (anum && !bnum) ? -1 + : (bnum && !anum) ? 1 + : a < b ? -1 + : 1 +} + +exports.rcompareIdentifiers = rcompareIdentifiers +function rcompareIdentifiers (a, b) { + return compareIdentifiers(b, a) +} + +exports.major = major +function major (a, loose) { + return new SemVer(a, loose).major +} + +exports.minor = minor +function minor (a, loose) { + return new SemVer(a, loose).minor +} + +exports.patch = patch +function patch (a, loose) { + return new SemVer(a, loose).patch +} + +exports.compare = compare +function compare (a, b, loose) { + return new SemVer(a, loose).compare(new SemVer(b, loose)) +} + +exports.compareLoose = compareLoose +function compareLoose (a, b) { + return compare(a, b, true) +} + +exports.rcompare = rcompare +function rcompare (a, b, loose) { + return compare(b, a, loose) +} + +exports.sort = sort +function sort (list, loose) { + return list.sort(function (a, b) { + return exports.compare(a, b, loose) + }) +} + +exports.rsort = rsort +function rsort (list, loose) { + return list.sort(function (a, b) { + return exports.rcompare(a, b, loose) + }) +} + +exports.gt = gt +function gt (a, b, loose) { + return compare(a, b, loose) > 0 +} + +exports.lt = lt +function lt (a, b, loose) { + return compare(a, b, loose) < 0 +} + +exports.eq = eq +function eq (a, b, loose) { + return compare(a, b, loose) === 0 +} + +exports.neq = neq +function neq (a, b, loose) { + return compare(a, b, loose) !== 0 +} + +exports.gte = gte +function gte (a, b, loose) { + return compare(a, b, loose) >= 0 +} + +exports.lte = lte +function lte (a, b, loose) { + return compare(a, b, loose) <= 0 +} + +exports.cmp = cmp +function cmp (a, op, b, loose) { + switch (op) { + case '===': + if (typeof a === 'object') + a = a.version + if (typeof b === 'object') + b = b.version + return a === b + + case '!==': + if (typeof a === 'object') + a = a.version + if (typeof b === 'object') + b = b.version + return a !== b + + case '': + case '=': + case '==': + return eq(a, b, loose) + + case '!=': + return neq(a, b, loose) + + case '>': + return gt(a, b, loose) + + case '>=': + return gte(a, b, loose) + + case '<': + return lt(a, b, loose) + + case '<=': + return lte(a, b, loose) + + default: + throw new TypeError('Invalid operator: ' + op) + } +} + +exports.Comparator = Comparator +function Comparator (comp, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (comp instanceof Comparator) { + if (comp.loose === !!options.loose) { + return comp + } else { + comp = comp.value + } + } + + if (!(this instanceof Comparator)) { + return new Comparator(comp, options) + } + + debug('comparator', comp, options) + this.options = options + this.loose = !!options.loose + this.parse(comp) + + if (this.semver === ANY) { + this.value = '' + } else { + this.value = this.operator + this.semver.version + } + + debug('comp', this) +} + +var ANY = {} +Comparator.prototype.parse = function (comp) { + var r = this.options.loose ? re[COMPARATORLOOSE] : re[COMPARATOR] + var m = comp.match(r) + + if (!m) { + throw new TypeError('Invalid comparator: ' + comp) + } + + this.operator = m[1] + if (this.operator === '=') { + this.operator = '' + } + + // if it literally is just '>' or '' then allow anything. + if (!m[2]) { + this.semver = ANY + } else { + this.semver = new SemVer(m[2], this.options.loose) + } +} + +Comparator.prototype.toString = function () { + return this.value +} + +Comparator.prototype.test = function (version) { + debug('Comparator.test', version, this.options.loose) + + if (this.semver === ANY) { + return true + } + + if (typeof version === 'string') { + version = new SemVer(version, this.options) + } + + return cmp(version, this.operator, this.semver, this.options) +} + +Comparator.prototype.intersects = function (comp, options) { + if (!(comp instanceof Comparator)) { + throw new TypeError('a Comparator is required') + } + + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + var rangeTmp + + if (this.operator === '') { + rangeTmp = new Range(comp.value, options) + return satisfies(this.value, rangeTmp, options) + } else if (comp.operator === '') { + rangeTmp = new Range(this.value, options) + return satisfies(comp.semver, rangeTmp, options) + } + + var sameDirectionIncreasing = + (this.operator === '>=' || this.operator === '>') && + (comp.operator === '>=' || comp.operator === '>') + var sameDirectionDecreasing = + (this.operator === '<=' || this.operator === '<') && + (comp.operator === '<=' || comp.operator === '<') + var sameSemVer = this.semver.version === comp.semver.version + var differentDirectionsInclusive = + (this.operator === '>=' || this.operator === '<=') && + (comp.operator === '>=' || comp.operator === '<=') + var oppositeDirectionsLessThan = + cmp(this.semver, '<', comp.semver, options) && + ((this.operator === '>=' || this.operator === '>') && + (comp.operator === '<=' || comp.operator === '<')) + var oppositeDirectionsGreaterThan = + cmp(this.semver, '>', comp.semver, options) && + ((this.operator === '<=' || this.operator === '<') && + (comp.operator === '>=' || comp.operator === '>')) + + return sameDirectionIncreasing || sameDirectionDecreasing || + (sameSemVer && differentDirectionsInclusive) || + oppositeDirectionsLessThan || oppositeDirectionsGreaterThan +} + +exports.Range = Range +function Range (range, options) { + if (!options || typeof options !== 'object') { + options = { + loose: !!options, + includePrerelease: false + } + } + + if (range instanceof Range) { + if (range.loose === !!options.loose && + range.includePrerelease === !!options.includePrerelease) { + return range + } else { + return new Range(range.raw, options) + } + } + + if (range instanceof Comparator) { + return new Range(range.value, options) + } + + if (!(this instanceof Range)) { + return new Range(range, options) + } + + this.options = options + this.loose = !!options.loose + this.includePrerelease = !!options.includePrerelease + + // First, split based on boolean or || + this.raw = range + this.set = range.split(/\s*\|\|\s*/).map(function (range) { + return this.parseRange(range.trim()) + }, this).filter(function (c) { + // throw out any that are not relevant for whatever reason + return c.length + }) -if (true) { -exports.parser = spdxparse; -exports.Parser = spdxparse.Parser; -exports.parse = function () { return spdxparse.parse.apply(spdxparse, arguments); }; -exports.main = function commonjsMain(args) { - if (!args[1]) { - console.log('Usage: '+args[0]+' FILE'); - process.exit(1); - } - var source = __webpack_require__(23).readFileSync(__webpack_require__(16).normalize(args[1]), "utf8"); - return exports.parser.parse(source); -}; -if ( true && __webpack_require__.c[__webpack_require__.s] === module) { - exports.main(process.argv.slice(1)); + if (!this.set.length) { + throw new TypeError('Invalid SemVer Range: ' + range) + } + + this.format() } + +Range.prototype.format = function () { + this.range = this.set.map(function (comps) { + return comps.join(' ').trim() + }).join('||').trim() + return this.range } -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(5)(module))) +Range.prototype.toString = function () { + return this.range +} -/***/ }), -/* 527 */ -/***/ (function(module, exports, __webpack_require__) { +Range.prototype.parseRange = function (range) { + var loose = this.options.loose + range = range.trim() + // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE] + range = range.replace(hr, hyphenReplace) + debug('hyphen replace', range) + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace) + debug('comparator trim', range, re[COMPARATORTRIM]) -var licenseIDs = __webpack_require__(528); + // `~ 1.2.3` => `~1.2.3` + range = range.replace(re[TILDETRIM], tildeTrimReplace) -function valid(string) { - return licenseIDs.indexOf(string) > -1; -} + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[CARETTRIM], caretTrimReplace) -// Common transpositions of license identifier acronyms -var transpositions = [ - ['APGL', 'AGPL'], - ['Gpl', 'GPL'], - ['GLP', 'GPL'], - ['APL', 'Apache'], - ['ISD', 'ISC'], - ['GLP', 'GPL'], - ['IST', 'ISC'], - ['Claude', 'Clause'], - [' or later', '+'], - [' International', ''], - ['GNU', 'GPL'], - ['GUN', 'GPL'], - ['+', ''], - ['GNU GPL', 'GPL'], - ['GNU/GPL', 'GPL'], - ['GNU GLP', 'GPL'], - ['GNU General Public License', 'GPL'], - ['Gnu public license', 'GPL'], - ['GNU Public License', 'GPL'], - ['GNU GENERAL PUBLIC LICENSE', 'GPL'], - ['MTI', 'MIT'], - ['Mozilla Public License', 'MPL'], - ['WTH', 'WTF'], - ['-License', ''] -]; + // normalize spaces + range = range.split(/\s+/).join(' ') -var TRANSPOSED = 0; -var CORRECT = 1; + // At this point, the range is completely trimmed and + // ready to be split into comparators. -// Simple corrections to nearly valid identifiers. -var transforms = [ - // e.g. 'mit' - function(argument) { - return argument.toUpperCase(); - }, - // e.g. 'MIT ' - function(argument) { - return argument.trim(); - }, - // e.g. 'M.I.T.' - function(argument) { - return argument.replace(/\./g, ''); - }, - // e.g. 'Apache- 2.0' - function(argument) { - return argument.replace(/\s+/g, ''); - }, - // e.g. 'CC BY 4.0'' - function(argument) { - return argument.replace(/\s+/g, '-'); - }, - // e.g. 'LGPLv2.1' - function(argument) { - return argument.replace('v', '-'); - }, - // e.g. 'Apache 2.0' - function(argument) { - return argument.replace(/,?\s*(\d)/, '-$1'); - }, - // e.g. 'GPL 2' - function(argument) { - return argument.replace(/,?\s*(\d)/, '-$1.0'); - }, - // e.g. 'Apache Version 2.0' - function(argument) { - return argument.replace(/,?\s*(V\.|v\.|V|v|Version|version)\s*(\d)/, '-$2'); - }, - // e.g. 'Apache Version 2' - function(argument) { - return argument.replace(/,?\s*(V\.|v\.|V|v|Version|version)\s*(\d)/, '-$2.0'); - }, - // e.g. 'ZLIB' - function(argument) { - return argument[0].toUpperCase() + argument.slice(1); - }, - // e.g. 'MPL/2.0' - function(argument) { - return argument.replace('/', '-'); - }, - // e.g. 'Apache 2' - function(argument) { - return argument - .replace(/\s*V\s*(\d)/, '-$1') - .replace(/(\d)$/, '$1.0'); - }, - // e.g. 'GPL-2.0-' - function(argument) { - return argument.slice(0, argument.length - 1); - }, - // e.g. 'GPL2' - function(argument) { - return argument.replace(/(\d)$/, '-$1.0'); - }, - // e.g. 'BSD 3' - function(argument) { - return argument.replace(/(-| )?(\d)$/, '-$2-Clause'); - }, - // e.g. 'BSD clause 3' - function(argument) { - return argument.replace(/(-| )clause(-| )(\d)/, '-$3-Clause'); - }, - // e.g. 'BY-NC-4.0' - function(argument) { - return 'CC-' + argument; - }, - // e.g. 'BY-NC' - function(argument) { - return 'CC-' + argument + '-4.0'; - }, - // e.g. 'Attribution-NonCommercial' - function(argument) { - return argument - .replace('Attribution', 'BY') - .replace('NonCommercial', 'NC') - .replace('NoDerivatives', 'ND') - .replace(/ (\d)/, '-$1') - .replace(/ ?International/, ''); - }, - // e.g. 'Attribution-NonCommercial' - function(argument) { - return 'CC-' + - argument - .replace('Attribution', 'BY') - .replace('NonCommercial', 'NC') - .replace('NoDerivatives', 'ND') - .replace(/ (\d)/, '-$1') - .replace(/ ?International/, '') + - '-4.0'; + var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR] + var set = range.split(' ').map(function (comp) { + return parseComparator(comp, this.options) + }, this).join(' ').split(/\s+/) + if (this.options.loose) { + // in loose mode, throw out any that are not valid comparators + set = set.filter(function (comp) { + return !!comp.match(compRe) + }) } -]; - -// If all else fails, guess that strings containing certain substrings -// meant to identify certain licenses. -var lastResorts = [ - ['UNLI', 'Unlicense'], - ['WTF', 'WTFPL'], - ['2 CLAUSE', 'BSD-2-Clause'], - ['2-CLAUSE', 'BSD-2-Clause'], - ['3 CLAUSE', 'BSD-3-Clause'], - ['3-CLAUSE', 'BSD-3-Clause'], - ['AFFERO', 'AGPL-3.0'], - ['AGPL', 'AGPL-3.0'], - ['APACHE', 'Apache-2.0'], - ['ARTISTIC', 'Artistic-2.0'], - ['Affero', 'AGPL-3.0'], - ['BEER', 'Beerware'], - ['BOOST', 'BSL-1.0'], - ['BSD', 'BSD-2-Clause'], - ['ECLIPSE', 'EPL-1.0'], - ['FUCK', 'WTFPL'], - ['GNU', 'GPL-3.0'], - ['LGPL', 'LGPL-3.0'], - ['GPL', 'GPL-3.0'], - ['MIT', 'MIT'], - ['MPL', 'MPL-2.0'], - ['X11', 'X11'], - ['ZLIB', 'Zlib'] -]; + set = set.map(function (comp) { + return new Comparator(comp, this.options) + }, this) -var SUBSTRING = 0; -var IDENTIFIER = 1; + return set +} -var validTransformation = function(identifier) { - for (var i = 0; i < transforms.length; i++) { - var transformed = transforms[i](identifier); - if (transformed !== identifier && valid(transformed)) { - return transformed; - } +Range.prototype.intersects = function (range, options) { + if (!(range instanceof Range)) { + throw new TypeError('a Range is required') } - return null; -}; -var validLastResort = function(identifier) { - var upperCased = identifier.toUpperCase(); - for (var i = 0; i < lastResorts.length; i++) { - var lastResort = lastResorts[i]; - if (upperCased.indexOf(lastResort[SUBSTRING]) > -1) { - return lastResort[IDENTIFIER]; - } - } - return null; -}; + return this.set.some(function (thisComparators) { + return thisComparators.every(function (thisComparator) { + return range.set.some(function (rangeComparators) { + return rangeComparators.every(function (rangeComparator) { + return thisComparator.intersects(rangeComparator, options) + }) + }) + }) + }) +} -var anyCorrection = function(identifier, check) { - for (var i = 0; i < transpositions.length; i++) { - var transposition = transpositions[i]; - var transposed = transposition[TRANSPOSED]; - if (identifier.indexOf(transposed) > -1) { - var corrected = identifier.replace( - transposed, - transposition[CORRECT] - ); - var checked = check(corrected); - if (checked !== null) { - return checked; - } +// Mostly just for testing and legacy API reasons +exports.toComparators = toComparators +function toComparators (range, options) { + return new Range(range, options).set.map(function (comp) { + return comp.map(function (c) { + return c.value + }).join(' ').trim().split(' ') + }) +} + +// comprised of xranges, tildes, stars, and gtlt's at this point. +// already replaced the hyphen ranges +// turn into a set of JUST comparators. +function parseComparator (comp, options) { + debug('comp', comp, options) + comp = replaceCarets(comp, options) + debug('caret', comp) + comp = replaceTildes(comp, options) + debug('tildes', comp) + comp = replaceXRanges(comp, options) + debug('xrange', comp) + comp = replaceStars(comp, options) + debug('stars', comp) + return comp +} + +function isX (id) { + return !id || id.toLowerCase() === 'x' || id === '*' +} + +// ~, ~> --> * (any, kinda silly) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 +function replaceTildes (comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceTilde(comp, options) + }).join(' ') +} + +function replaceTilde (comp, options) { + var r = options.loose ? re[TILDELOOSE] : re[TILDE] + return comp.replace(r, function (_, M, m, p, pr) { + debug('tilde', comp, _, M, m, p, pr) + var ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (isX(p)) { + // ~1.2 == >=1.2.0 <1.3.0 + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } else if (pr) { + debug('replaceTilde pr', pr) + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + } else { + // ~1.2.3 == >=1.2.3 <1.3.0 + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0' } - } - return null; -}; -module.exports = function(identifier) { - identifier = identifier.replace(/\+$/, ''); - if (valid(identifier)) { - return identifier; - } - var transformed = validTransformation(identifier); - if (transformed !== null) { - return transformed; - } - transformed = anyCorrection(identifier, function(argument) { - if (valid(argument)) { - return argument; + debug('tilde return', ret) + return ret + }) +} + +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2.0 --> >=1.2.0 <2.0.0 +function replaceCarets (comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceCaret(comp, options) + }).join(' ') +} + +function replaceCaret (comp, options) { + debug('caret', comp, options) + var r = options.loose ? re[CARETLOOSE] : re[CARET] + return comp.replace(r, function (_, M, m, p, pr) { + debug('caret', comp, _, M, m, p, pr) + var ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (isX(p)) { + if (M === '0') { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } else { + ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0' + } + } else if (pr) { + debug('replaceCaret pr', pr) + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + m + '.' + (+p + 1) + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + } + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + (+M + 1) + '.0.0' + } + } else { + debug('no pr') + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + m + '.' + (+p + 1) + } else { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0' + } + } else { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + (+M + 1) + '.0.0' + } } - return validTransformation(argument); - }); - if (transformed !== null) { - return transformed; - } - transformed = validLastResort(identifier); - if (transformed !== null) { - return transformed; - } - transformed = anyCorrection(identifier, validLastResort); - if (transformed !== null) { - return transformed; - } - return null; -}; + debug('caret return', ret) + return ret + }) +} -/***/ }), -/* 528 */ -/***/ (function(module) { +function replaceXRanges (comp, options) { + debug('replaceXRanges', comp, options) + return comp.split(/\s+/).map(function (comp) { + return replaceXRange(comp, options) + }).join(' ') +} -module.exports = JSON.parse("[\"Glide\",\"Abstyles\",\"AFL-1.1\",\"AFL-1.2\",\"AFL-2.0\",\"AFL-2.1\",\"AFL-3.0\",\"AMPAS\",\"APL-1.0\",\"Adobe-Glyph\",\"APAFML\",\"Adobe-2006\",\"AGPL-1.0\",\"Afmparse\",\"Aladdin\",\"ADSL\",\"AMDPLPA\",\"ANTLR-PD\",\"Apache-1.0\",\"Apache-1.1\",\"Apache-2.0\",\"AML\",\"APSL-1.0\",\"APSL-1.1\",\"APSL-1.2\",\"APSL-2.0\",\"Artistic-1.0\",\"Artistic-1.0-Perl\",\"Artistic-1.0-cl8\",\"Artistic-2.0\",\"AAL\",\"Bahyph\",\"Barr\",\"Beerware\",\"BitTorrent-1.0\",\"BitTorrent-1.1\",\"BSL-1.0\",\"Borceux\",\"BSD-2-Clause\",\"BSD-2-Clause-FreeBSD\",\"BSD-2-Clause-NetBSD\",\"BSD-3-Clause\",\"BSD-3-Clause-Clear\",\"BSD-4-Clause\",\"BSD-Protection\",\"BSD-Source-Code\",\"BSD-3-Clause-Attribution\",\"0BSD\",\"BSD-4-Clause-UC\",\"bzip2-1.0.5\",\"bzip2-1.0.6\",\"Caldera\",\"CECILL-1.0\",\"CECILL-1.1\",\"CECILL-2.0\",\"CECILL-2.1\",\"CECILL-B\",\"CECILL-C\",\"ClArtistic\",\"MIT-CMU\",\"CNRI-Jython\",\"CNRI-Python\",\"CNRI-Python-GPL-Compatible\",\"CPOL-1.02\",\"CDDL-1.0\",\"CDDL-1.1\",\"CPAL-1.0\",\"CPL-1.0\",\"CATOSL-1.1\",\"Condor-1.1\",\"CC-BY-1.0\",\"CC-BY-2.0\",\"CC-BY-2.5\",\"CC-BY-3.0\",\"CC-BY-4.0\",\"CC-BY-ND-1.0\",\"CC-BY-ND-2.0\",\"CC-BY-ND-2.5\",\"CC-BY-ND-3.0\",\"CC-BY-ND-4.0\",\"CC-BY-NC-1.0\",\"CC-BY-NC-2.0\",\"CC-BY-NC-2.5\",\"CC-BY-NC-3.0\",\"CC-BY-NC-4.0\",\"CC-BY-NC-ND-1.0\",\"CC-BY-NC-ND-2.0\",\"CC-BY-NC-ND-2.5\",\"CC-BY-NC-ND-3.0\",\"CC-BY-NC-ND-4.0\",\"CC-BY-NC-SA-1.0\",\"CC-BY-NC-SA-2.0\",\"CC-BY-NC-SA-2.5\",\"CC-BY-NC-SA-3.0\",\"CC-BY-NC-SA-4.0\",\"CC-BY-SA-1.0\",\"CC-BY-SA-2.0\",\"CC-BY-SA-2.5\",\"CC-BY-SA-3.0\",\"CC-BY-SA-4.0\",\"CC0-1.0\",\"Crossword\",\"CrystalStacker\",\"CUA-OPL-1.0\",\"Cube\",\"curl\",\"D-FSL-1.0\",\"diffmark\",\"WTFPL\",\"DOC\",\"Dotseqn\",\"DSDP\",\"dvipdfm\",\"EPL-1.0\",\"ECL-1.0\",\"ECL-2.0\",\"eGenix\",\"EFL-1.0\",\"EFL-2.0\",\"MIT-advertising\",\"MIT-enna\",\"Entessa\",\"ErlPL-1.1\",\"EUDatagrid\",\"EUPL-1.0\",\"EUPL-1.1\",\"Eurosym\",\"Fair\",\"MIT-feh\",\"Frameworx-1.0\",\"FreeImage\",\"FTL\",\"FSFAP\",\"FSFUL\",\"FSFULLR\",\"Giftware\",\"GL2PS\",\"Glulxe\",\"AGPL-3.0\",\"GFDL-1.1\",\"GFDL-1.2\",\"GFDL-1.3\",\"GPL-1.0\",\"GPL-2.0\",\"GPL-3.0\",\"LGPL-2.1\",\"LGPL-3.0\",\"LGPL-2.0\",\"gnuplot\",\"gSOAP-1.3b\",\"HaskellReport\",\"HPND\",\"IBM-pibs\",\"IPL-1.0\",\"ICU\",\"ImageMagick\",\"iMatix\",\"Imlib2\",\"IJG\",\"Info-ZIP\",\"Intel-ACPI\",\"Intel\",\"Interbase-1.0\",\"IPA\",\"ISC\",\"JasPer-2.0\",\"JSON\",\"LPPL-1.0\",\"LPPL-1.1\",\"LPPL-1.2\",\"LPPL-1.3a\",\"LPPL-1.3c\",\"Latex2e\",\"BSD-3-Clause-LBNL\",\"Leptonica\",\"LGPLLR\",\"Libpng\",\"libtiff\",\"LAL-1.2\",\"LAL-1.3\",\"LiLiQ-P-1.1\",\"LiLiQ-Rplus-1.1\",\"LiLiQ-R-1.1\",\"LPL-1.02\",\"LPL-1.0\",\"MakeIndex\",\"MTLL\",\"MS-PL\",\"MS-RL\",\"MirOS\",\"MITNFA\",\"MIT\",\"Motosoto\",\"MPL-1.0\",\"MPL-1.1\",\"MPL-2.0\",\"MPL-2.0-no-copyleft-exception\",\"mpich2\",\"Multics\",\"Mup\",\"NASA-1.3\",\"Naumen\",\"NBPL-1.0\",\"NetCDF\",\"NGPL\",\"NOSL\",\"NPL-1.0\",\"NPL-1.1\",\"Newsletr\",\"NLPL\",\"Nokia\",\"NPOSL-3.0\",\"NLOD-1.0\",\"Noweb\",\"NRL\",\"NTP\",\"Nunit\",\"OCLC-2.0\",\"ODbL-1.0\",\"PDDL-1.0\",\"OCCT-PL\",\"OGTSL\",\"OLDAP-2.2.2\",\"OLDAP-1.1\",\"OLDAP-1.2\",\"OLDAP-1.3\",\"OLDAP-1.4\",\"OLDAP-2.0\",\"OLDAP-2.0.1\",\"OLDAP-2.1\",\"OLDAP-2.2\",\"OLDAP-2.2.1\",\"OLDAP-2.3\",\"OLDAP-2.4\",\"OLDAP-2.5\",\"OLDAP-2.6\",\"OLDAP-2.7\",\"OLDAP-2.8\",\"OML\",\"OPL-1.0\",\"OSL-1.0\",\"OSL-1.1\",\"OSL-2.0\",\"OSL-2.1\",\"OSL-3.0\",\"OpenSSL\",\"OSET-PL-2.1\",\"PHP-3.0\",\"PHP-3.01\",\"Plexus\",\"PostgreSQL\",\"psfrag\",\"psutils\",\"Python-2.0\",\"QPL-1.0\",\"Qhull\",\"Rdisc\",\"RPSL-1.0\",\"RPL-1.1\",\"RPL-1.5\",\"RHeCos-1.1\",\"RSCPL\",\"RSA-MD\",\"Ruby\",\"SAX-PD\",\"Saxpath\",\"SCEA\",\"SWL\",\"SMPPL\",\"Sendmail\",\"SGI-B-1.0\",\"SGI-B-1.1\",\"SGI-B-2.0\",\"OFL-1.0\",\"OFL-1.1\",\"SimPL-2.0\",\"Sleepycat\",\"SNIA\",\"Spencer-86\",\"Spencer-94\",\"Spencer-99\",\"SMLNJ\",\"SugarCRM-1.1.3\",\"SISSL\",\"SISSL-1.2\",\"SPL-1.0\",\"Watcom-1.0\",\"TCL\",\"Unlicense\",\"TMate\",\"TORQUE-1.1\",\"TOSL\",\"Unicode-TOU\",\"UPL-1.0\",\"NCSA\",\"Vim\",\"VOSTROM\",\"VSL-1.0\",\"W3C-19980720\",\"W3C\",\"Wsuipa\",\"Xnet\",\"X11\",\"Xerox\",\"XFree86-1.1\",\"xinetd\",\"xpp\",\"XSkat\",\"YPL-1.0\",\"YPL-1.1\",\"Zed\",\"Zend-2.0\",\"Zimbra-1.3\",\"Zimbra-1.4\",\"Zlib\",\"zlib-acknowledgement\",\"ZPL-1.1\",\"ZPL-2.0\",\"ZPL-2.1\",\"BSD-3-Clause-No-Nuclear-License\",\"BSD-3-Clause-No-Nuclear-Warranty\",\"BSD-3-Clause-No-Nuclear-License-2014\",\"eCos-2.0\",\"GPL-2.0-with-autoconf-exception\",\"GPL-2.0-with-bison-exception\",\"GPL-2.0-with-classpath-exception\",\"GPL-2.0-with-font-exception\",\"GPL-2.0-with-GCC-exception\",\"GPL-3.0-with-autoconf-exception\",\"GPL-3.0-with-GCC-exception\",\"StandardML-NJ\",\"WXwindows\"]"); +function replaceXRange (comp, options) { + comp = comp.trim() + var r = options.loose ? re[XRANGELOOSE] : re[XRANGE] + return comp.replace(r, function (ret, gtlt, M, m, p, pr) { + debug('xRange', comp, ret, gtlt, M, m, p, pr) + var xM = isX(M) + var xm = xM || isX(m) + var xp = xm || isX(p) + var anyX = xp -/***/ }), -/* 529 */ -/***/ (function(module, exports, __webpack_require__) { + if (gtlt === '=' && anyX) { + gtlt = '' + } -"use strict"; + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0' + } else { + // nothing is forbidden + ret = '*' + } + } else if (gtlt && anyX) { + // we know patch is an x, because we have any x at all. + // replace X with 0 + if (xm) { + m = 0 + } + p = 0 -var url = __webpack_require__(452) -var gitHosts = __webpack_require__(530) -var GitHost = module.exports = __webpack_require__(531) + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + // >1.2.3 => >= 1.2.4 + gtlt = '>=' + if (xm) { + M = +M + 1 + m = 0 + p = 0 + } else { + m = +m + 1 + p = 0 + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<' + if (xm) { + M = +M + 1 + } else { + m = +m + 1 + } + } -var protocolToRepresentationMap = { - 'git+ssh': 'sshurl', - 'git+https': 'https', - 'ssh': 'sshurl', - 'git': 'git' -} + ret = gtlt + M + '.' + m + '.' + p + } else if (xm) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (xp) { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } -function protocolToRepresentation (protocol) { - if (protocol.substr(-1) === ':') protocol = protocol.slice(0, -1) - return protocolToRepresentationMap[protocol] || protocol -} + debug('xRange return', ret) -var authProtocols = { - 'git:': true, - 'https:': true, - 'git+https:': true, - 'http:': true, - 'git+http:': true + return ret + }) } -var cache = {} +// Because * is AND-ed with everything else in the comparator, +// and '' means "any version", just remove the *s entirely. +function replaceStars (comp, options) { + debug('replaceStars', comp, options) + // Looseness is ignored here. star is always as loose as it gets! + return comp.trim().replace(re[STAR], '') +} -module.exports.fromUrl = function (giturl, opts) { - var key = giturl + JSON.stringify(opts || {}) +// This function is passed to string.replace(re[HYPHENRANGE]) +// M, m, patch, prerelease, build +// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do +// 1.2 - 3.4 => >=1.2.0 <3.5.0 +function hyphenReplace ($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr, tb) { + if (isX(fM)) { + from = '' + } else if (isX(fm)) { + from = '>=' + fM + '.0.0' + } else if (isX(fp)) { + from = '>=' + fM + '.' + fm + '.0' + } else { + from = '>=' + from + } - if (!(key in cache)) { - cache[key] = fromUrl(giturl, opts) + if (isX(tM)) { + to = '' + } else if (isX(tm)) { + to = '<' + (+tM + 1) + '.0.0' + } else if (isX(tp)) { + to = '<' + tM + '.' + (+tm + 1) + '.0' + } else if (tpr) { + to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr + } else { + to = '<=' + to } - return cache[key] + return (from + ' ' + to).trim() } -function fromUrl (giturl, opts) { - if (giturl == null || giturl === '') return - var url = fixupUnqualifiedGist( - isGitHubShorthand(giturl) ? 'github:' + giturl : giturl - ) - var parsed = parseGitUrl(url) - var shortcutMatch = url.match(new RegExp('^([^:]+):(?:(?:[^@:]+(?:[^@]+)?@)?([^/]*))[/](.+?)(?:[.]git)?($|#)')) - var matches = Object.keys(gitHosts).map(function (gitHostName) { - try { - var gitHostInfo = gitHosts[gitHostName] - var auth = null - if (parsed.auth && authProtocols[parsed.protocol]) { - auth = decodeURIComponent(parsed.auth) - } - var committish = parsed.hash ? decodeURIComponent(parsed.hash.substr(1)) : null - var user = null - var project = null - var defaultRepresentation = null - if (shortcutMatch && shortcutMatch[1] === gitHostName) { - user = shortcutMatch[2] && decodeURIComponent(shortcutMatch[2]) - project = decodeURIComponent(shortcutMatch[3]) - defaultRepresentation = 'shortcut' - } else { - if (parsed.host !== gitHostInfo.domain) return - if (!gitHostInfo.protocols_re.test(parsed.protocol)) return - if (!parsed.path) return - var pathmatch = gitHostInfo.pathmatch - var matched = parsed.path.match(pathmatch) - if (!matched) return - if (matched[1] != null) user = decodeURIComponent(matched[1].replace(/^:/, '')) - if (matched[2] != null) project = decodeURIComponent(matched[2]) - defaultRepresentation = protocolToRepresentation(parsed.protocol) - } - return new GitHost(gitHostName, user, auth, project, committish, defaultRepresentation, opts) - } catch (ex) { - if (!(ex instanceof URIError)) throw ex - } - }).filter(function (gitHostInfo) { return gitHostInfo }) - if (matches.length !== 1) return - return matches[0] -} +// if ANY of the sets match ALL of its comparators, then pass +Range.prototype.test = function (version) { + if (!version) { + return false + } -function isGitHubShorthand (arg) { - // Note: This does not fully test the git ref format. - // See https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html - // - // The only way to do this properly would be to shell out to - // git-check-ref-format, and as this is a fast sync function, - // we don't want to do that. Just let git fail if it turns - // out that the commit-ish is invalid. - // GH usernames cannot start with . or - - return /^[^:@%/\s.-][^:@%/\s]*[/][^:@\s/%]+(?:#.*)?$/.test(arg) -} + if (typeof version === 'string') { + version = new SemVer(version, this.options) + } -function fixupUnqualifiedGist (giturl) { - // necessary for round-tripping gists - var parsed = url.parse(giturl) - if (parsed.protocol === 'gist:' && parsed.host && !parsed.path) { - return parsed.protocol + '/' + parsed.host - } else { - return giturl + for (var i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version, this.options)) { + return true + } } + return false } -function parseGitUrl (giturl) { - if (typeof giturl !== 'string') giturl = '' + giturl - var matched = giturl.match(/^([^@]+)@([^:/]+):[/]?((?:[^/]+[/])?[^/]+?)(?:[.]git)?(#.*)?$/) - if (!matched) return url.parse(giturl) - return { - protocol: 'git+ssh:', - slashes: true, - auth: matched[1], - host: matched[2], - port: null, - hostname: matched[2], - hash: matched[4], - search: null, - query: null, - pathname: '/' + matched[3], - path: '/' + matched[3], - href: 'git+ssh://' + matched[1] + '@' + matched[2] + - '/' + matched[3] + (matched[4] || '') +function testSet (set, version, options) { + for (var i = 0; i < set.length; i++) { + if (!set[i].test(version)) { + return false + } } -} + if (version.prerelease.length && !options.includePrerelease) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (i = 0; i < set.length; i++) { + debug(set[i].semver) + if (set[i].semver === ANY) { + continue + } -/***/ }), -/* 530 */ -/***/ (function(module, exports, __webpack_require__) { + if (set[i].semver.prerelease.length > 0) { + var allowed = set[i].semver + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) { + return true + } + } + } -"use strict"; + // Version has a -pre, but it's not one of the ones we like. + return false + } + return true +} -var gitHosts = module.exports = { - github: { - // First two are insecure and generally shouldn't be used any more, but - // they are still supported. - 'protocols': [ 'git', 'http', 'git+ssh', 'git+https', 'ssh', 'https' ], - 'domain': 'github.com', - 'treepath': 'tree', - 'filetemplate': 'https://{auth@}raw.githubusercontent.com/{user}/{project}/{committish}/{path}', - 'bugstemplate': 'https://{domain}/{user}/{project}/issues', - 'gittemplate': 'git://{auth@}{domain}/{user}/{project}.git{#committish}', - 'tarballtemplate': 'https://{domain}/{user}/{project}/archive/{committish}.tar.gz' - }, - bitbucket: { - 'protocols': [ 'git+ssh', 'git+https', 'ssh', 'https' ], - 'domain': 'bitbucket.org', - 'treepath': 'src', - 'tarballtemplate': 'https://{domain}/{user}/{project}/get/{committish}.tar.gz' - }, - gitlab: { - 'protocols': [ 'git+ssh', 'git+https', 'ssh', 'https' ], - 'domain': 'gitlab.com', - 'treepath': 'tree', - 'docstemplate': 'https://{domain}/{user}/{project}{/tree/committish}#README', - 'bugstemplate': 'https://{domain}/{user}/{project}/issues', - 'tarballtemplate': 'https://{domain}/{user}/{project}/repository/archive.tar.gz?ref={committish}' - }, - gist: { - 'protocols': [ 'git', 'git+ssh', 'git+https', 'ssh', 'https' ], - 'domain': 'gist.github.com', - 'pathmatch': /^[/](?:([^/]+)[/])?([a-z0-9]+)(?:[.]git)?$/, - 'filetemplate': 'https://gist.githubusercontent.com/{user}/{project}/raw{/committish}/{path}', - 'bugstemplate': 'https://{domain}/{project}', - 'gittemplate': 'git://{domain}/{project}.git{#committish}', - 'sshtemplate': 'git@{domain}:/{project}.git{#committish}', - 'sshurltemplate': 'git+ssh://git@{domain}/{project}.git{#committish}', - 'browsetemplate': 'https://{domain}/{project}{/committish}', - 'docstemplate': 'https://{domain}/{project}{/committish}', - 'httpstemplate': 'git+https://{domain}/{project}.git{#committish}', - 'shortcuttemplate': '{type}:{project}{#committish}', - 'pathtemplate': '{project}{#committish}', - 'tarballtemplate': 'https://{domain}/{user}/{project}/archive/{committish}.tar.gz' +exports.satisfies = satisfies +function satisfies (version, range, options) { + try { + range = new Range(range, options) + } catch (er) { + return false } + return range.test(version) } -var gitHostDefaults = { - 'sshtemplate': 'git@{domain}:{user}/{project}.git{#committish}', - 'sshurltemplate': 'git+ssh://git@{domain}/{user}/{project}.git{#committish}', - 'browsetemplate': 'https://{domain}/{user}/{project}{/tree/committish}', - 'docstemplate': 'https://{domain}/{user}/{project}{/tree/committish}#readme', - 'httpstemplate': 'git+https://{auth@}{domain}/{user}/{project}.git{#committish}', - 'filetemplate': 'https://{domain}/{user}/{project}/raw/{committish}/{path}', - 'shortcuttemplate': '{type}:{user}/{project}{#committish}', - 'pathtemplate': '{user}/{project}{#committish}', - 'pathmatch': /^[/]([^/]+)[/]([^/]+?)(?:[.]git|[/])?$/ +exports.maxSatisfying = maxSatisfying +function maxSatisfying (versions, range, options) { + var max = null + var maxSV = null + try { + var rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!max || maxSV.compare(v) === -1) { + // compare(max, v, true) + max = v + maxSV = new SemVer(max, options) + } + } + }) + return max } -Object.keys(gitHosts).forEach(function (name) { - Object.keys(gitHostDefaults).forEach(function (key) { - if (gitHosts[name][key]) return - gitHosts[name][key] = gitHostDefaults[key] +exports.minSatisfying = minSatisfying +function minSatisfying (versions, range, options) { + var min = null + var minSV = null + try { + var rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!min || minSV.compare(v) === 1) { + // compare(min, v, true) + min = v + minSV = new SemVer(min, options) + } + } }) - gitHosts[name].protocols_re = RegExp('^(' + - gitHosts[name].protocols.map(function (protocol) { - return protocol.replace(/([\\+*{}()[\]$^|])/g, '\\$1') - }).join('|') + '):$') -}) + return min +} +exports.minVersion = minVersion +function minVersion (range, loose) { + range = new Range(range, loose) -/***/ }), -/* 531 */ -/***/ (function(module, exports, __webpack_require__) { + var minver = new SemVer('0.0.0') + if (range.test(minver)) { + return minver + } -"use strict"; + minver = new SemVer('0.0.0-0') + if (range.test(minver)) { + return minver + } -var gitHosts = __webpack_require__(530) -var extend = Object.assign || __webpack_require__(29)._extend + minver = null + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i] -var GitHost = module.exports = function (type, user, auth, project, committish, defaultRepresentation, opts) { - var gitHostInfo = this - gitHostInfo.type = type - Object.keys(gitHosts[type]).forEach(function (key) { - gitHostInfo[key] = gitHosts[type][key] - }) - gitHostInfo.user = user - gitHostInfo.auth = auth - gitHostInfo.project = project - gitHostInfo.committish = committish - gitHostInfo.default = defaultRepresentation - gitHostInfo.opts = opts || {} -} -GitHost.prototype = {} + comparators.forEach(function (comparator) { + // Clone to avoid manipulating the comparator's semver object. + var compver = new SemVer(comparator.semver.version) + switch (comparator.operator) { + case '>': + if (compver.prerelease.length === 0) { + compver.patch++ + } else { + compver.prerelease.push(0) + } + compver.raw = compver.format() + /* fallthrough */ + case '': + case '>=': + if (!minver || gt(minver, compver)) { + minver = compver + } + break + case '<': + case '<=': + /* Ignore maximum versions */ + break + /* istanbul ignore next */ + default: + throw new Error('Unexpected operation: ' + comparator.operator) + } + }) + } -GitHost.prototype.hash = function () { - return this.committish ? '#' + this.committish : '' + if (minver && range.test(minver)) { + return minver + } + + return null } -GitHost.prototype._fill = function (template, opts) { - if (!template) return - var vars = extend({}, opts) - opts = extend(extend({}, this.opts), opts) - var self = this - Object.keys(this).forEach(function (key) { - if (self[key] != null && vars[key] == null) vars[key] = self[key] - }) - var rawAuth = vars.auth - var rawComittish = vars.committish - Object.keys(vars).forEach(function (key) { - vars[key] = encodeURIComponent(vars[key]) - }) - vars['auth@'] = rawAuth ? rawAuth + '@' : '' - if (opts.noCommittish) { - vars['#committish'] = '' - vars['/tree/committish'] = '' - vars['/comittish'] = '' - vars.comittish = '' - } else { - vars['#committish'] = rawComittish ? '#' + rawComittish : '' - vars['/tree/committish'] = vars.committish - ? '/' + vars.treepath + '/' + vars.committish - : '' - vars['/committish'] = vars.committish ? '/' + vars.committish : '' - vars.committish = vars.committish || 'master' - } - var res = template - Object.keys(vars).forEach(function (key) { - res = res.replace(new RegExp('[{]' + key + '[}]', 'g'), vars[key]) - }) - if (opts.noGitPlus) { - return res.replace(/^git[+]/, '') - } else { - return res +exports.validRange = validRange +function validRange (range, options) { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, options).range || '*' + } catch (er) { + return null } } -GitHost.prototype.ssh = function (opts) { - return this._fill(this.sshtemplate, opts) +// Determine if version is less than all the versions possible in the range +exports.ltr = ltr +function ltr (version, range, options) { + return outside(version, range, '<', options) } -GitHost.prototype.sshurl = function (opts) { - return this._fill(this.sshurltemplate, opts) +// Determine if version is greater than all the versions possible in the range. +exports.gtr = gtr +function gtr (version, range, options) { + return outside(version, range, '>', options) } -GitHost.prototype.browse = function (opts) { - return this._fill(this.browsetemplate, opts) -} +exports.outside = outside +function outside (version, range, hilo, options) { + version = new SemVer(version, options) + range = new Range(range, options) -GitHost.prototype.docs = function (opts) { - return this._fill(this.docstemplate, opts) -} + var gtfn, ltefn, ltfn, comp, ecomp + switch (hilo) { + case '>': + gtfn = gt + ltefn = lte + ltfn = lt + comp = '>' + ecomp = '>=' + break + case '<': + gtfn = lt + ltefn = gte + ltfn = gt + comp = '<' + ecomp = '<=' + break + default: + throw new TypeError('Must provide a hilo val of "<" or ">"') + } -GitHost.prototype.bugs = function (opts) { - return this._fill(this.bugstemplate, opts) -} + // If it satisifes the range it is not outside + if (satisfies(version, range, options)) { + return false + } -GitHost.prototype.https = function (opts) { - return this._fill(this.httpstemplate, opts) -} + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. -GitHost.prototype.git = function (opts) { - return this._fill(this.gittemplate, opts) -} + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i] -GitHost.prototype.shortcut = function (opts) { - return this._fill(this.shortcuttemplate, opts) -} + var high = null + var low = null -GitHost.prototype.path = function (opts) { - return this._fill(this.pathtemplate, opts) -} + comparators.forEach(function (comparator) { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0') + } + high = high || comparator + low = low || comparator + if (gtfn(comparator.semver, high.semver, options)) { + high = comparator + } else if (ltfn(comparator.semver, low.semver, options)) { + low = comparator + } + }) -GitHost.prototype.tarball = function (opts) { - return this._fill(this.tarballtemplate, opts) + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false + } + } + return true } -GitHost.prototype.file = function (P, opts) { - return this._fill(this.filetemplate, extend({ - path: P.replace(/^[/]+/g, '') - }, opts)) +exports.prerelease = prerelease +function prerelease (version, options) { + var parsed = parse(version, options) + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null } -GitHost.prototype.getDefaultRepresentation = function () { - return this.default +exports.intersects = intersects +function intersects (r1, r2, options) { + r1 = new Range(r1, options) + r2 = new Range(r2, options) + return r1.intersects(r2) } -GitHost.prototype.toString = function (opts) { - return (this[this.default] || this.sshurl).call(this, opts) -} +exports.coerce = coerce +function coerce (version) { + if (version instanceof SemVer) { + return version + } + if (typeof version !== 'string') { + return null + } -/***/ }), -/* 532 */ -/***/ (function(module, exports, __webpack_require__) { + var match = version.match(re[COERCE]) -var core = __webpack_require__(533); -var async = __webpack_require__(535); -async.core = core; -async.isCore = function isCore(x) { return core[x]; }; -async.sync = __webpack_require__(540); + if (match == null) { + return null + } -exports = async; -module.exports = async; + return parse(match[1] + + '.' + (match[2] || '0') + + '.' + (match[3] || '0')) +} /***/ }), -/* 533 */ +/* 524 */ /***/ (function(module, exports, __webpack_require__) { -var current = (process.versions && process.versions.node && process.versions.node.split('.')) || []; +var parse = __webpack_require__(525); +var correct = __webpack_require__(527); -function specifierIncluded(specifier) { - var parts = specifier.split(' '); - var op = parts.length > 1 ? parts[0] : '='; - var versionParts = (parts.length > 1 ? parts[1] : parts[0]).split('.'); +var genericWarning = ( + 'license should be ' + + 'a valid SPDX license expression (without "LicenseRef"), ' + + '"UNLICENSED", or ' + + '"SEE LICENSE IN "' +); - for (var i = 0; i < 3; ++i) { - var cur = Number(current[i] || 0); - var ver = Number(versionParts[i] || 0); - if (cur === ver) { - continue; // eslint-disable-line no-restricted-syntax, no-continue - } - if (op === '<') { - return cur < ver; - } else if (op === '>=') { - return cur >= ver; - } else { - return false; - } - } - return op === '>='; -} +var fileReferenceRE = /^SEE LICEN[CS]E IN (.+)$/; -function matchesRange(range) { - var specifiers = range.split(/ ?&& ?/); - if (specifiers.length === 0) { return false; } - for (var i = 0; i < specifiers.length; ++i) { - if (!specifierIncluded(specifiers[i])) { return false; } - } - return true; +function startsWith(prefix, string) { + return string.slice(0, prefix.length) === prefix; } -function versionIncluded(specifierValue) { - if (typeof specifierValue === 'boolean') { return specifierValue; } - if (specifierValue && typeof specifierValue === 'object') { - for (var i = 0; i < specifierValue.length; ++i) { - if (matchesRange(specifierValue[i])) { return true; } - } - return false; - } - return matchesRange(specifierValue); +function usesLicenseRef(ast) { + if (ast.hasOwnProperty('license')) { + var license = ast.license; + return ( + startsWith('LicenseRef', license) || + startsWith('DocumentRef', license) + ); + } else { + return ( + usesLicenseRef(ast.left) || + usesLicenseRef(ast.right) + ); + } } -var data = __webpack_require__(534); +module.exports = function(argument) { + var ast; -var core = {}; -for (var mod in data) { // eslint-disable-line no-restricted-syntax - if (Object.prototype.hasOwnProperty.call(data, mod)) { - core[mod] = versionIncluded(data[mod]); + try { + ast = parse(argument); + } catch (e) { + var match + if ( + argument === 'UNLICENSED' || + argument === 'UNLICENCED' + ) { + return { + validForOldPackages: true, + validForNewPackages: true, + unlicensed: true + }; + } else if (match = fileReferenceRE.exec(argument)) { + return { + validForOldPackages: true, + validForNewPackages: true, + inFile: match[1] + }; + } else { + var result = { + validForOldPackages: false, + validForNewPackages: false, + warnings: [genericWarning] + }; + var corrected = correct(argument); + if (corrected) { + result.warnings.push( + 'license is similar to the valid expression "' + corrected + '"' + ); + } + return result; } -} -module.exports = core; + } + + if (usesLicenseRef(ast)) { + return { + validForNewPackages: false, + validForOldPackages: false, + spdx: true, + warnings: [genericWarning] + }; + } else { + return { + validForNewPackages: true, + validForOldPackages: true, + spdx: true + }; + } +}; /***/ }), -/* 534 */ -/***/ (function(module) { +/* 525 */ +/***/ (function(module, exports, __webpack_require__) { + +var parser = __webpack_require__(526).parser + +module.exports = function (argument) { + return parser.parse(argument) +} -module.exports = JSON.parse("{\"assert\":true,\"async_hooks\":\">= 8\",\"buffer_ieee754\":\"< 0.9.7\",\"buffer\":true,\"child_process\":true,\"cluster\":true,\"console\":true,\"constants\":true,\"crypto\":true,\"_debugger\":\"< 8\",\"dgram\":true,\"dns\":true,\"domain\":true,\"events\":true,\"freelist\":\"< 6\",\"fs\":true,\"fs/promises\":\">= 10 && < 10.1\",\"_http_agent\":\">= 0.11.1\",\"_http_client\":\">= 0.11.1\",\"_http_common\":\">= 0.11.1\",\"_http_incoming\":\">= 0.11.1\",\"_http_outgoing\":\">= 0.11.1\",\"_http_server\":\">= 0.11.1\",\"http\":true,\"http2\":\">= 8.8\",\"https\":true,\"inspector\":\">= 8.0.0\",\"_linklist\":\"< 8\",\"module\":true,\"net\":true,\"node-inspect/lib/_inspect\":\">= 7.6.0\",\"node-inspect/lib/internal/inspect_client\":\">= 7.6.0\",\"node-inspect/lib/internal/inspect_repl\":\">= 7.6.0\",\"os\":true,\"path\":true,\"perf_hooks\":\">= 8.5\",\"process\":\">= 1\",\"punycode\":true,\"querystring\":true,\"readline\":true,\"repl\":true,\"smalloc\":\">= 0.11.5 && < 3\",\"_stream_duplex\":\">= 0.9.4\",\"_stream_transform\":\">= 0.9.4\",\"_stream_wrap\":\">= 1.4.1\",\"_stream_passthrough\":\">= 0.9.4\",\"_stream_readable\":\">= 0.9.4\",\"_stream_writable\":\">= 0.9.4\",\"stream\":true,\"string_decoder\":true,\"sys\":true,\"timers\":true,\"_tls_common\":\">= 0.11.13\",\"_tls_legacy\":\">= 0.11.3 && < 10\",\"_tls_wrap\":\">= 0.11.3\",\"tls\":true,\"trace_events\":\">= 10\",\"tty\":true,\"url\":true,\"util\":true,\"v8/tools/arguments\":\">= 10\",\"v8/tools/codemap\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8/tools/consarray\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8/tools/csvparser\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8/tools/logreader\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8/tools/profile_view\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8/tools/splaytree\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8\":\">= 1\",\"vm\":true,\"worker_threads\":\">= 11.7\",\"zlib\":true}"); /***/ }), -/* 535 */ +/* 526 */ /***/ (function(module, exports, __webpack_require__) { -var core = __webpack_require__(533); -var fs = __webpack_require__(23); -var path = __webpack_require__(16); -var caller = __webpack_require__(536); -var nodeModulesPaths = __webpack_require__(537); -var normalizeOptions = __webpack_require__(539); +/* WEBPACK VAR INJECTION */(function(module) {/* parser generated by jison 0.4.17 */ +/* + Returns a Parser object of the following structure: -var defaultIsFile = function isFile(file, cb) { - fs.stat(file, function (err, stat) { - if (!err) { - return cb(null, stat.isFile() || stat.isFIFO()); - } - if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false); - return cb(err); - }); -}; + Parser: { + yy: {} + } -module.exports = function resolve(x, options, callback) { - var cb = callback; - var opts = options; - if (typeof options === 'function') { - cb = opts; - opts = {}; - } - if (typeof x !== 'string') { - var err = new TypeError('Path must be a string.'); - return process.nextTick(function () { - cb(err); - }); + Parser.prototype: { + yy: {}, + trace: function(), + symbols_: {associative list: name ==> number}, + terminals_: {associative list: number ==> name}, + productions_: [...], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), + table: [...], + defaultActions: {...}, + parseError: function(str, hash), + parse: function(input), + + lexer: { + EOF: 1, + parseError: function(str, hash), + setInput: function(input), + input: function(), + unput: function(str), + more: function(), + less: function(n), + pastInput: function(), + upcomingInput: function(), + showPosition: function(), + test_match: function(regex_match_array, rule_index), + next: function(), + lex: function(), + begin: function(condition), + popState: function(), + _currentRules: function(), + topState: function(), + pushState: function(condition), + + options: { + ranges: boolean (optional: true ==> token location info will include a .range[] member) + flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) + backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) + }, + + performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), + rules: [...], + conditions: {associative list: name ==> set}, } + } - opts = normalizeOptions(x, opts); - var isFile = opts.isFile || defaultIsFile; - var readFile = opts.readFile || fs.readFile; + token location info (@$, _$, etc.): { + first_line: n, + last_line: n, + first_column: n, + last_column: n, + range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) + } - var extensions = opts.extensions || ['.js']; - var basedir = opts.basedir || path.dirname(caller()); - var parent = opts.filename || basedir; - opts.paths = opts.paths || []; + the parseError function receives a 'hash' object with these members for lexer and parser errors: { + text: (matched text) + token: (the produced terminal token, if any) + line: (yylineno) + } + while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { + loc: (yylloc) + expected: (string describing the set of expected tokens) + recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) + } +*/ +var spdxparse = (function(){ +var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,5],$V1=[1,6],$V2=[1,7],$V3=[1,4],$V4=[1,9],$V5=[1,10],$V6=[5,14,15,17],$V7=[5,12,14,15,17]; +var parser = {trace: function trace() { }, +yy: {}, +symbols_: {"error":2,"start":3,"expression":4,"EOS":5,"simpleExpression":6,"LICENSE":7,"PLUS":8,"LICENSEREF":9,"DOCUMENTREF":10,"COLON":11,"WITH":12,"EXCEPTION":13,"AND":14,"OR":15,"OPEN":16,"CLOSE":17,"$accept":0,"$end":1}, +terminals_: {2:"error",5:"EOS",7:"LICENSE",8:"PLUS",9:"LICENSEREF",10:"DOCUMENTREF",11:"COLON",12:"WITH",13:"EXCEPTION",14:"AND",15:"OR",16:"OPEN",17:"CLOSE"}, +productions_: [0,[3,2],[6,1],[6,2],[6,1],[6,3],[4,1],[4,3],[4,3],[4,3],[4,3]], +performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { +/* this == yyval */ - // ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory - var absoluteStart = path.resolve(basedir); +var $0 = $$.length - 1; +switch (yystate) { +case 1: +return this.$ = $$[$0-1] +break; +case 2: case 4: case 5: +this.$ = {license: yytext} +break; +case 3: +this.$ = {license: $$[$0-1], plus: true} +break; +case 6: +this.$ = $$[$0] +break; +case 7: +this.$ = {exception: $$[$0]} +this.$.license = $$[$0-2].license +if ($$[$0-2].hasOwnProperty('plus')) { + this.$.plus = $$[$0-2].plus +} +break; +case 8: +this.$ = {conjunction: 'and', left: $$[$0-2], right: $$[$0]} +break; +case 9: +this.$ = {conjunction: 'or', left: $$[$0-2], right: $$[$0]} +break; +case 10: +this.$ = $$[$0-1] +break; +} +}, +table: [{3:1,4:2,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{1:[3]},{5:[1,8],14:$V4,15:$V5},o($V6,[2,6],{12:[1,11]}),{4:12,6:3,7:$V0,9:$V1,10:$V2,16:$V3},o($V7,[2,2],{8:[1,13]}),o($V7,[2,4]),{11:[1,14]},{1:[2,1]},{4:15,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{4:16,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{13:[1,17]},{14:$V4,15:$V5,17:[1,18]},o($V7,[2,3]),{9:[1,19]},o($V6,[2,8]),o([5,15,17],[2,9],{14:$V4}),o($V6,[2,7]),o($V6,[2,10]),o($V7,[2,5])], +defaultActions: {8:[2,1]}, +parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + function _parseError (msg, hash) { + this.message = msg; + this.hash = hash; + } + _parseError.prototype = Error; - if (opts.preserveSymlinks === false) { - fs.realpath(absoluteStart, function (realPathErr, realStart) { - if (realPathErr && realPathErr.code !== 'ENOENT') cb(err); - else init(realPathErr ? absoluteStart : realStart); - }); + throw new _parseError(str, hash); + } +}, +parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer; + sharedState.yy.parser = this; + if (typeof lexer.yylloc == 'undefined') { + lexer.yylloc = {}; + } + var yyloc = lexer.yylloc; + lstack.push(yyloc); + var ranges = lexer.options && lexer.options.ranges; + if (typeof sharedState.yy.parseError === 'function') { + this.parseError = sharedState.yy.parseError; } else { - init(absoluteStart); + this.parseError = Object.getPrototypeOf(this).parseError; } - - var res; - function init(basedir) { - if ((/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/).test(x)) { - res = path.resolve(basedir, x); - if (x === '..' || x.slice(-1) === '/') res += '/'; - if ((/\/$/).test(x) && res === basedir) { - loadAsDirectory(res, opts.package, onfile); - } else loadAsFile(res, opts.package, onfile); - } else loadNodeModules(x, basedir, function (err, n, pkg) { - if (err) cb(err); - else if (n) cb(null, n, pkg); - else if (core[x]) return cb(null, x); - else { - var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'"); - moduleError.code = 'MODULE_NOT_FOUND'; - cb(moduleError); - } - }); + function popStack(n) { + stack.length = stack.length - 2 * n; + vstack.length = vstack.length - n; + lstack.length = lstack.length - n; } - - function onfile(err, m, pkg) { - if (err) cb(err); - else if (m) cb(null, m, pkg); - else loadAsDirectory(res, function (err, d, pkg) { - if (err) cb(err); - else if (d) cb(null, d, pkg); - else { - var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'"); - moduleError.code = 'MODULE_NOT_FOUND'; - cb(moduleError); + _token_stack: + var lex = function () { + var token; + token = lexer.lex() || EOF; + if (typeof token !== 'number') { + token = self.symbols_[token] || token; } - }); + return token; + }; + var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == 'undefined') { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === 'undefined' || !action.length || !action[0]) { + var errStr = ''; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push('\'' + this.terminals_[p] + '\''); + } + } + if (lexer.showPosition) { + errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; + } else { + errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); + } + this.parseError(errStr, { + text: lexer.match, + token: this.terminals_[symbol] || symbol, + line: lexer.yylineno, + loc: yyloc, + expected: expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer.yytext); + lstack.push(lexer.yylloc); + stack.push(action[1]); + symbol = null; + if (!preErrorSymbol) { + yyleng = lexer.yyleng; + yytext = lexer.yytext; + yylineno = lexer.yylineno; + yyloc = lexer.yylloc; + if (recovering > 0) { + recovering--; + } + } else { + symbol = preErrorSymbol; + preErrorSymbol = null; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== 'undefined') { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } } + return true; +}}; +/* generated by jison-lex 0.3.4 */ +var lexer = (function(){ +var lexer = ({ + +EOF:1, + +parseError:function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + +// resets the lexer, sets new input +setInput:function (input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ''; + this.conditionStack = ['INITIAL']; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0,0]; + } + this.offset = 0; + return this; + }, - function loadAsFile(x, thePackage, callback) { - var loadAsFilePackage = thePackage; - var cb = callback; - if (typeof loadAsFilePackage === 'function') { - cb = loadAsFilePackage; - loadAsFilePackage = undefined; +// consumes and returns one char from the input +input:function () { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; } - var exts = [''].concat(extensions); - load(exts, x, loadAsFilePackage); + this._input = this._input.slice(1); + return ch; + }, - function load(exts, x, loadPackage) { - if (exts.length === 0) return cb(null, undefined, loadPackage); - var file = x + exts[0]; +// unshifts one char (or a string) into the input +unput:function (ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); - var pkg = loadPackage; - if (pkg) onpkg(null, pkg); - else loadpkg(path.dirname(file), onpkg); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + //this.yyleng -= len; + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); - function onpkg(err, pkg_, dir) { - pkg = pkg_; - if (err) return cb(err); - if (dir && pkg && opts.pathFilter) { - var rfile = path.relative(dir, file); - var rel = rfile.slice(0, rfile.length - exts[0].length); - var r = opts.pathFilter(pkg, x, rel); - if (r) return load( - [''].concat(extensions.slice()), - path.resolve(dir, r), - pkg - ); - } - isFile(file, onex); - } - function onex(err, ex) { - if (err) return cb(err); - if (ex) return cb(null, file, pkg); - load(exts.slice(1), x, pkg); - } + if (lines.length - 1) { + this.yylineno -= lines.length - 1; } - } + var r = this.yylloc.range; - function loadpkg(dir, cb) { - if (dir === '' || dir === '/') return cb(null); - if (process.platform === 'win32' && (/^\w:[/\\]*$/).test(dir)) { - return cb(null); - } - if ((/[/\\]node_modules[/\\]*$/).test(dir)) return cb(null); + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? + (lines.length === oldLines.length ? this.yylloc.first_column : 0) + + oldLines[oldLines.length - lines.length].length - lines[0].length : + this.yylloc.first_column - len + }; - var pkgfile = path.join(dir, 'package.json'); - isFile(pkgfile, function (err, ex) { - // on err, ex is false - if (!ex) return loadpkg(path.dirname(dir), cb); + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, - readFile(pkgfile, function (err, body) { - if (err) cb(err); - try { var pkg = JSON.parse(body); } catch (jsonErr) {} +// When called from action, caches matched text and appends it on next action +more:function () { + this._more = true; + return this; + }, - if (pkg && opts.packageFilter) { - pkg = opts.packageFilter(pkg, pkgfile); - } - cb(null, pkg, dir); +// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. +reject:function () { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), { + text: "", + token: null, + line: this.yylineno }); - }); - } - function loadAsDirectory(x, loadAsDirectoryPackage, callback) { - var cb = callback; - var fpkg = loadAsDirectoryPackage; - if (typeof fpkg === 'function') { - cb = fpkg; - fpkg = opts.package; } + return this; + }, - var pkgfile = path.join(x, 'package.json'); - isFile(pkgfile, function (err, ex) { - if (err) return cb(err); - if (!ex) return loadAsFile(path.join(x, 'index'), fpkg, cb); - - readFile(pkgfile, function (err, body) { - if (err) return cb(err); - try { - var pkg = JSON.parse(body); - } catch (jsonErr) {} - - if (opts.packageFilter) { - pkg = opts.packageFilter(pkg, pkgfile); - } - - if (pkg.main) { - if (typeof pkg.main !== 'string') { - var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string'); - mainError.code = 'INVALID_PACKAGE_MAIN'; - return cb(mainError); - } - if (pkg.main === '.' || pkg.main === './') { - pkg.main = 'index'; - } - loadAsFile(path.resolve(x, pkg.main), pkg, function (err, m, pkg) { - if (err) return cb(err); - if (m) return cb(null, m, pkg); - if (!pkg) return loadAsFile(path.join(x, 'index'), pkg, cb); +// retain first n characters of the match +less:function (n) { + this.unput(this.match.slice(n)); + }, - var dir = path.resolve(x, pkg.main); - loadAsDirectory(dir, pkg, function (err, n, pkg) { - if (err) return cb(err); - if (n) return cb(null, n, pkg); - loadAsFile(path.join(x, 'index'), pkg, cb); - }); - }); - return; - } +// displays already matched input, i.e. for error messages +pastInput:function () { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); + }, - loadAsFile(path.join(x, '/index'), pkg, cb); - }); - }); - } +// displays upcoming input, i.e. for error messages +upcomingInput:function () { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20-next.length); + } + return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); + }, - function processDirs(cb, dirs) { - if (dirs.length === 0) return cb(null, undefined); - var dir = dirs[0]; +// displays the character position where the lexing error occurred, i.e. for error messages +showPosition:function () { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, - var file = path.join(dir, x); - loadAsFile(file, opts.package, onfile); +// test the lexed token: return FALSE when not a match, otherwise return token +test_match:function (match, indexed_rule) { + var token, + lines, + backup; - function onfile(err, m, pkg) { - if (err) return cb(err); - if (m) return cb(null, m, pkg); - loadAsDirectory(path.join(dir, x), opts.package, ondir); + if (this.options.backtrack_lexer) { + // save context + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } } - function ondir(err, n, pkg) { - if (err) return cb(err); - if (n) return cb(null, n, pkg); - processDirs(cb, dirs.slice(1)); + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; } - } - function loadNodeModules(x, start, cb) { - processDirs(cb, nodeModulesPaths(start, opts, x)); - } -}; + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? + lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : + this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + // recover context + for (var k in backup) { + this[k] = backup[k]; + } + return false; // rule action called reject() implying the next rule should be tested instead. + } + return false; + }, +// return next match in input +next:function () { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } -/***/ }), -/* 536 */ -/***/ (function(module, exports) { + var token, + match, + tempMatch, + index; + if (!this._more) { + this.yytext = ''; + this.match = ''; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; // rule action called reject() implying a rule MISmatch. + } else { + // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, -module.exports = function () { - // see https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi - var origPrepareStackTrace = Error.prepareStackTrace; - Error.prepareStackTrace = function (_, stack) { return stack; }; - var stack = (new Error()).stack; - Error.prepareStackTrace = origPrepareStackTrace; - return stack[2].getFileName(); -}; +// return next match that has a token +lex:function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, +// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) +begin:function begin(condition) { + this.conditionStack.push(condition); + }, -/***/ }), -/* 537 */ -/***/ (function(module, exports, __webpack_require__) { +// pop the previously active lexer condition state off the condition stack +popState:function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, -var path = __webpack_require__(16); -var parse = path.parse || __webpack_require__(538); +// produce the lexer rule set which is active for the currently active lexer condition state +_currentRules:function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, -var getNodeModulesDirs = function getNodeModulesDirs(absoluteStart, modules) { - var prefix = '/'; - if ((/^([A-Za-z]:)/).test(absoluteStart)) { - prefix = ''; - } else if ((/^\\\\/).test(absoluteStart)) { - prefix = '\\\\'; - } +// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available +topState:function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, - var paths = [absoluteStart]; - var parsed = parse(absoluteStart); - while (parsed.dir !== paths[paths.length - 1]) { - paths.push(parsed.dir); - parsed = parse(parsed.dir); - } +// alias for begin(condition) +pushState:function pushState(condition) { + this.begin(condition); + }, - return paths.reduce(function (dirs, aPath) { - return dirs.concat(modules.map(function (moduleDir) { - return path.join(prefix, aPath, moduleDir); - })); - }, []); -}; +// return the number of states currently on the stack +stateStackSize:function stateStackSize() { + return this.conditionStack.length; + }, +options: {}, +performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { +var YYSTATE=YY_START; +switch($avoiding_name_collisions) { +case 0:return 5 +break; +case 1:/* skip whitespace */ +break; +case 2:return 8 +break; +case 3:return 16 +break; +case 4:return 17 +break; +case 5:return 11 +break; +case 6:return 10 +break; +case 7:return 9 +break; +case 8:return 14 +break; +case 9:return 15 +break; +case 10:return 12 +break; +case 11:return 7 +break; +case 12:return 7 +break; +case 13:return 7 +break; +case 14:return 7 +break; +case 15:return 7 +break; +case 16:return 7 +break; +case 17:return 7 +break; +case 18:return 7 +break; +case 19:return 7 +break; +case 20:return 7 +break; +case 21:return 7 +break; +case 22:return 7 +break; +case 23:return 7 +break; +case 24:return 13 +break; +case 25:return 13 +break; +case 26:return 13 +break; +case 27:return 13 +break; +case 28:return 13 +break; +case 29:return 13 +break; +case 30:return 13 +break; +case 31:return 13 +break; +case 32:return 7 +break; +case 33:return 13 +break; +case 34:return 7 +break; +case 35:return 13 +break; +case 36:return 7 +break; +case 37:return 13 +break; +case 38:return 13 +break; +case 39:return 7 +break; +case 40:return 13 +break; +case 41:return 13 +break; +case 42:return 13 +break; +case 43:return 13 +break; +case 44:return 13 +break; +case 45:return 7 +break; +case 46:return 13 +break; +case 47:return 7 +break; +case 48:return 7 +break; +case 49:return 7 +break; +case 50:return 7 +break; +case 51:return 7 +break; +case 52:return 7 +break; +case 53:return 7 +break; +case 54:return 7 +break; +case 55:return 7 +break; +case 56:return 7 +break; +case 57:return 7 +break; +case 58:return 7 +break; +case 59:return 7 +break; +case 60:return 7 +break; +case 61:return 7 +break; +case 62:return 7 +break; +case 63:return 13 +break; +case 64:return 7 +break; +case 65:return 7 +break; +case 66:return 13 +break; +case 67:return 7 +break; +case 68:return 7 +break; +case 69:return 7 +break; +case 70:return 7 +break; +case 71:return 7 +break; +case 72:return 7 +break; +case 73:return 13 +break; +case 74:return 7 +break; +case 75:return 13 +break; +case 76:return 7 +break; +case 77:return 7 +break; +case 78:return 7 +break; +case 79:return 7 +break; +case 80:return 7 +break; +case 81:return 7 +break; +case 82:return 7 +break; +case 83:return 7 +break; +case 84:return 7 +break; +case 85:return 7 +break; +case 86:return 7 +break; +case 87:return 7 +break; +case 88:return 7 +break; +case 89:return 7 +break; +case 90:return 7 +break; +case 91:return 7 +break; +case 92:return 7 +break; +case 93:return 7 +break; +case 94:return 7 +break; +case 95:return 7 +break; +case 96:return 7 +break; +case 97:return 7 +break; +case 98:return 7 +break; +case 99:return 7 +break; +case 100:return 7 +break; +case 101:return 7 +break; +case 102:return 7 +break; +case 103:return 7 +break; +case 104:return 7 +break; +case 105:return 7 +break; +case 106:return 7 +break; +case 107:return 7 +break; +case 108:return 7 +break; +case 109:return 7 +break; +case 110:return 7 +break; +case 111:return 7 +break; +case 112:return 7 +break; +case 113:return 7 +break; +case 114:return 7 +break; +case 115:return 7 +break; +case 116:return 7 +break; +case 117:return 7 +break; +case 118:return 7 +break; +case 119:return 7 +break; +case 120:return 7 +break; +case 121:return 7 +break; +case 122:return 7 +break; +case 123:return 7 +break; +case 124:return 7 +break; +case 125:return 7 +break; +case 126:return 7 +break; +case 127:return 7 +break; +case 128:return 7 +break; +case 129:return 7 +break; +case 130:return 7 +break; +case 131:return 7 +break; +case 132:return 7 +break; +case 133:return 7 +break; +case 134:return 7 +break; +case 135:return 7 +break; +case 136:return 7 +break; +case 137:return 7 +break; +case 138:return 7 +break; +case 139:return 7 +break; +case 140:return 7 +break; +case 141:return 7 +break; +case 142:return 7 +break; +case 143:return 7 +break; +case 144:return 7 +break; +case 145:return 7 +break; +case 146:return 7 +break; +case 147:return 7 +break; +case 148:return 7 +break; +case 149:return 7 +break; +case 150:return 7 +break; +case 151:return 7 +break; +case 152:return 7 +break; +case 153:return 7 +break; +case 154:return 7 +break; +case 155:return 7 +break; +case 156:return 7 +break; +case 157:return 7 +break; +case 158:return 7 +break; +case 159:return 7 +break; +case 160:return 7 +break; +case 161:return 7 +break; +case 162:return 7 +break; +case 163:return 7 +break; +case 164:return 7 +break; +case 165:return 7 +break; +case 166:return 7 +break; +case 167:return 7 +break; +case 168:return 7 +break; +case 169:return 7 +break; +case 170:return 7 +break; +case 171:return 7 +break; +case 172:return 7 +break; +case 173:return 7 +break; +case 174:return 7 +break; +case 175:return 7 +break; +case 176:return 7 +break; +case 177:return 7 +break; +case 178:return 7 +break; +case 179:return 7 +break; +case 180:return 7 +break; +case 181:return 7 +break; +case 182:return 7 +break; +case 183:return 7 +break; +case 184:return 7 +break; +case 185:return 7 +break; +case 186:return 7 +break; +case 187:return 7 +break; +case 188:return 7 +break; +case 189:return 7 +break; +case 190:return 7 +break; +case 191:return 7 +break; +case 192:return 7 +break; +case 193:return 7 +break; +case 194:return 7 +break; +case 195:return 7 +break; +case 196:return 7 +break; +case 197:return 7 +break; +case 198:return 7 +break; +case 199:return 7 +break; +case 200:return 7 +break; +case 201:return 7 +break; +case 202:return 7 +break; +case 203:return 7 +break; +case 204:return 7 +break; +case 205:return 7 +break; +case 206:return 7 +break; +case 207:return 7 +break; +case 208:return 7 +break; +case 209:return 7 +break; +case 210:return 7 +break; +case 211:return 7 +break; +case 212:return 7 +break; +case 213:return 7 +break; +case 214:return 7 +break; +case 215:return 7 +break; +case 216:return 7 +break; +case 217:return 7 +break; +case 218:return 7 +break; +case 219:return 7 +break; +case 220:return 7 +break; +case 221:return 7 +break; +case 222:return 7 +break; +case 223:return 7 +break; +case 224:return 7 +break; +case 225:return 7 +break; +case 226:return 7 +break; +case 227:return 7 +break; +case 228:return 7 +break; +case 229:return 7 +break; +case 230:return 7 +break; +case 231:return 7 +break; +case 232:return 7 +break; +case 233:return 7 +break; +case 234:return 7 +break; +case 235:return 7 +break; +case 236:return 7 +break; +case 237:return 7 +break; +case 238:return 7 +break; +case 239:return 7 +break; +case 240:return 7 +break; +case 241:return 7 +break; +case 242:return 7 +break; +case 243:return 7 +break; +case 244:return 7 +break; +case 245:return 7 +break; +case 246:return 7 +break; +case 247:return 7 +break; +case 248:return 7 +break; +case 249:return 7 +break; +case 250:return 7 +break; +case 251:return 7 +break; +case 252:return 7 +break; +case 253:return 7 +break; +case 254:return 7 +break; +case 255:return 7 +break; +case 256:return 7 +break; +case 257:return 7 +break; +case 258:return 7 +break; +case 259:return 7 +break; +case 260:return 7 +break; +case 261:return 7 +break; +case 262:return 7 +break; +case 263:return 7 +break; +case 264:return 7 +break; +case 265:return 7 +break; +case 266:return 7 +break; +case 267:return 7 +break; +case 268:return 7 +break; +case 269:return 7 +break; +case 270:return 7 +break; +case 271:return 7 +break; +case 272:return 7 +break; +case 273:return 7 +break; +case 274:return 7 +break; +case 275:return 7 +break; +case 276:return 7 +break; +case 277:return 7 +break; +case 278:return 7 +break; +case 279:return 7 +break; +case 280:return 7 +break; +case 281:return 7 +break; +case 282:return 7 +break; +case 283:return 7 +break; +case 284:return 7 +break; +case 285:return 7 +break; +case 286:return 7 +break; +case 287:return 7 +break; +case 288:return 7 +break; +case 289:return 7 +break; +case 290:return 7 +break; +case 291:return 7 +break; +case 292:return 7 +break; +case 293:return 7 +break; +case 294:return 7 +break; +case 295:return 7 +break; +case 296:return 7 +break; +case 297:return 7 +break; +case 298:return 7 +break; +case 299:return 7 +break; +case 300:return 7 +break; +case 301:return 7 +break; +case 302:return 7 +break; +case 303:return 7 +break; +case 304:return 7 +break; +case 305:return 7 +break; +case 306:return 7 +break; +case 307:return 7 +break; +case 308:return 7 +break; +case 309:return 7 +break; +case 310:return 7 +break; +case 311:return 7 +break; +case 312:return 7 +break; +case 313:return 7 +break; +case 314:return 7 +break; +case 315:return 7 +break; +case 316:return 7 +break; +case 317:return 7 +break; +case 318:return 7 +break; +case 319:return 7 +break; +case 320:return 7 +break; +case 321:return 7 +break; +case 322:return 7 +break; +case 323:return 7 +break; +case 324:return 7 +break; +case 325:return 7 +break; +case 326:return 7 +break; +case 327:return 7 +break; +case 328:return 7 +break; +case 329:return 7 +break; +case 330:return 7 +break; +case 331:return 7 +break; +case 332:return 7 +break; +case 333:return 7 +break; +case 334:return 7 +break; +case 335:return 7 +break; +case 336:return 7 +break; +case 337:return 7 +break; +case 338:return 7 +break; +case 339:return 7 +break; +case 340:return 7 +break; +case 341:return 7 +break; +case 342:return 7 +break; +case 343:return 7 +break; +case 344:return 7 +break; +case 345:return 7 +break; +case 346:return 7 +break; +case 347:return 7 +break; +case 348:return 7 +break; +case 349:return 7 +break; +case 350:return 7 +break; +case 351:return 7 +break; +case 352:return 7 +break; +case 353:return 7 +break; +case 354:return 7 +break; +case 355:return 7 +break; +case 356:return 7 +break; +case 357:return 7 +break; +case 358:return 7 +break; +case 359:return 7 +break; +case 360:return 7 +break; +case 361:return 7 +break; +case 362:return 7 +break; +case 363:return 7 +break; +case 364:return 7 +break; +} +}, +rules: [/^(?:$)/,/^(?:\s+)/,/^(?:\+)/,/^(?:\()/,/^(?:\))/,/^(?::)/,/^(?:DocumentRef-([0-9A-Za-z-+.]+))/,/^(?:LicenseRef-([0-9A-Za-z-+.]+))/,/^(?:AND)/,/^(?:OR)/,/^(?:WITH)/,/^(?:BSD-3-Clause-No-Nuclear-License-2014)/,/^(?:BSD-3-Clause-No-Nuclear-Warranty)/,/^(?:GPL-2\.0-with-classpath-exception)/,/^(?:GPL-3\.0-with-autoconf-exception)/,/^(?:GPL-2\.0-with-autoconf-exception)/,/^(?:BSD-3-Clause-No-Nuclear-License)/,/^(?:MPL-2\.0-no-copyleft-exception)/,/^(?:GPL-2\.0-with-bison-exception)/,/^(?:GPL-2\.0-with-font-exception)/,/^(?:GPL-2\.0-with-GCC-exception)/,/^(?:CNRI-Python-GPL-Compatible)/,/^(?:GPL-3\.0-with-GCC-exception)/,/^(?:BSD-3-Clause-Attribution)/,/^(?:Classpath-exception-2\.0)/,/^(?:WxWindows-exception-3\.1)/,/^(?:freertos-exception-2\.0)/,/^(?:Autoconf-exception-3\.0)/,/^(?:i2p-gpl-java-exception)/,/^(?:gnu-javamail-exception)/,/^(?:Nokia-Qt-exception-1\.1)/,/^(?:Autoconf-exception-2\.0)/,/^(?:BSD-2-Clause-FreeBSD)/,/^(?:u-boot-exception-2\.0)/,/^(?:zlib-acknowledgement)/,/^(?:Bison-exception-2\.2)/,/^(?:BSD-2-Clause-NetBSD)/,/^(?:CLISP-exception-2\.0)/,/^(?:eCos-exception-2\.0)/,/^(?:BSD-3-Clause-Clear)/,/^(?:Font-exception-2\.0)/,/^(?:FLTK-exception-2\.0)/,/^(?:GCC-exception-2\.0)/,/^(?:Qwt-exception-1\.0)/,/^(?:Libtool-exception)/,/^(?:BSD-3-Clause-LBNL)/,/^(?:GCC-exception-3\.1)/,/^(?:Artistic-1\.0-Perl)/,/^(?:Artistic-1\.0-cl8)/,/^(?:CC-BY-NC-SA-2\.5)/,/^(?:MIT-advertising)/,/^(?:BSD-Source-Code)/,/^(?:CC-BY-NC-SA-4\.0)/,/^(?:LiLiQ-Rplus-1\.1)/,/^(?:CC-BY-NC-SA-3\.0)/,/^(?:BSD-4-Clause-UC)/,/^(?:CC-BY-NC-SA-2\.0)/,/^(?:CC-BY-NC-SA-1\.0)/,/^(?:CC-BY-NC-ND-4\.0)/,/^(?:CC-BY-NC-ND-3\.0)/,/^(?:CC-BY-NC-ND-2\.5)/,/^(?:CC-BY-NC-ND-2\.0)/,/^(?:CC-BY-NC-ND-1\.0)/,/^(?:LZMA-exception)/,/^(?:BitTorrent-1\.1)/,/^(?:CrystalStacker)/,/^(?:FLTK-exception)/,/^(?:SugarCRM-1\.1\.3)/,/^(?:BSD-Protection)/,/^(?:BitTorrent-1\.0)/,/^(?:HaskellReport)/,/^(?:Interbase-1\.0)/,/^(?:StandardML-NJ)/,/^(?:mif-exception)/,/^(?:Frameworx-1\.0)/,/^(?:389-exception)/,/^(?:CC-BY-NC-2\.0)/,/^(?:CC-BY-NC-2\.5)/,/^(?:CC-BY-NC-3\.0)/,/^(?:CC-BY-NC-4\.0)/,/^(?:W3C-19980720)/,/^(?:CC-BY-SA-1\.0)/,/^(?:CC-BY-SA-2\.0)/,/^(?:CC-BY-SA-2\.5)/,/^(?:CC-BY-ND-2\.0)/,/^(?:CC-BY-SA-4\.0)/,/^(?:CC-BY-SA-3\.0)/,/^(?:Artistic-1\.0)/,/^(?:Artistic-2\.0)/,/^(?:CC-BY-ND-2\.5)/,/^(?:CC-BY-ND-3\.0)/,/^(?:CC-BY-ND-4\.0)/,/^(?:CC-BY-ND-1\.0)/,/^(?:BSD-4-Clause)/,/^(?:BSD-3-Clause)/,/^(?:BSD-2-Clause)/,/^(?:CC-BY-NC-1\.0)/,/^(?:bzip2-1\.0\.6)/,/^(?:Unicode-TOU)/,/^(?:CNRI-Jython)/,/^(?:ImageMagick)/,/^(?:Adobe-Glyph)/,/^(?:CUA-OPL-1\.0)/,/^(?:OLDAP-2\.2\.2)/,/^(?:LiLiQ-R-1\.1)/,/^(?:bzip2-1\.0\.5)/,/^(?:LiLiQ-P-1\.1)/,/^(?:OLDAP-2\.0\.1)/,/^(?:OLDAP-2\.2\.1)/,/^(?:CNRI-Python)/,/^(?:XFree86-1\.1)/,/^(?:OSET-PL-2\.1)/,/^(?:Apache-2\.0)/,/^(?:Watcom-1\.0)/,/^(?:PostgreSQL)/,/^(?:Python-2\.0)/,/^(?:RHeCos-1\.1)/,/^(?:EUDatagrid)/,/^(?:Spencer-99)/,/^(?:Intel-ACPI)/,/^(?:CECILL-1\.0)/,/^(?:CECILL-1\.1)/,/^(?:JasPer-2\.0)/,/^(?:CECILL-2\.0)/,/^(?:CECILL-2\.1)/,/^(?:gSOAP-1\.3b)/,/^(?:Spencer-94)/,/^(?:Apache-1\.1)/,/^(?:Spencer-86)/,/^(?:Apache-1\.0)/,/^(?:ClArtistic)/,/^(?:TORQUE-1\.1)/,/^(?:CATOSL-1\.1)/,/^(?:Adobe-2006)/,/^(?:Zimbra-1\.4)/,/^(?:Zimbra-1\.3)/,/^(?:Condor-1\.1)/,/^(?:CC-BY-3\.0)/,/^(?:CC-BY-2\.5)/,/^(?:OLDAP-2\.4)/,/^(?:SGI-B-1\.1)/,/^(?:SISSL-1\.2)/,/^(?:SGI-B-1\.0)/,/^(?:OLDAP-2\.3)/,/^(?:CC-BY-4\.0)/,/^(?:Crossword)/,/^(?:SimPL-2\.0)/,/^(?:OLDAP-2\.2)/,/^(?:OLDAP-2\.1)/,/^(?:ErlPL-1\.1)/,/^(?:LPPL-1\.3a)/,/^(?:LPPL-1\.3c)/,/^(?:OLDAP-2\.0)/,/^(?:Leptonica)/,/^(?:CPOL-1\.02)/,/^(?:OLDAP-1\.4)/,/^(?:OLDAP-1\.3)/,/^(?:CC-BY-2\.0)/,/^(?:Unlicense)/,/^(?:OLDAP-2\.8)/,/^(?:OLDAP-1\.2)/,/^(?:MakeIndex)/,/^(?:OLDAP-2\.7)/,/^(?:OLDAP-1\.1)/,/^(?:Sleepycat)/,/^(?:D-FSL-1\.0)/,/^(?:CC-BY-1\.0)/,/^(?:OLDAP-2\.6)/,/^(?:WXwindows)/,/^(?:NPOSL-3\.0)/,/^(?:FreeImage)/,/^(?:SGI-B-2\.0)/,/^(?:OLDAP-2\.5)/,/^(?:Beerware)/,/^(?:Newsletr)/,/^(?:NBPL-1\.0)/,/^(?:NASA-1\.3)/,/^(?:NLOD-1\.0)/,/^(?:AGPL-1\.0)/,/^(?:OCLC-2\.0)/,/^(?:ODbL-1\.0)/,/^(?:PDDL-1\.0)/,/^(?:Motosoto)/,/^(?:Afmparse)/,/^(?:ANTLR-PD)/,/^(?:LPL-1\.02)/,/^(?:Abstyles)/,/^(?:eCos-2\.0)/,/^(?:APSL-1\.0)/,/^(?:LPPL-1\.2)/,/^(?:LPPL-1\.1)/,/^(?:LPPL-1\.0)/,/^(?:APSL-1\.1)/,/^(?:APSL-2\.0)/,/^(?:Info-ZIP)/,/^(?:Zend-2\.0)/,/^(?:IBM-pibs)/,/^(?:LGPL-2\.0)/,/^(?:LGPL-3\.0)/,/^(?:LGPL-2\.1)/,/^(?:GFDL-1\.3)/,/^(?:PHP-3\.01)/,/^(?:GFDL-1\.2)/,/^(?:GFDL-1\.1)/,/^(?:AGPL-3\.0)/,/^(?:Giftware)/,/^(?:EUPL-1\.1)/,/^(?:RPSL-1\.0)/,/^(?:EUPL-1\.0)/,/^(?:MIT-enna)/,/^(?:CECILL-B)/,/^(?:diffmark)/,/^(?:CECILL-C)/,/^(?:CDDL-1\.0)/,/^(?:Sendmail)/,/^(?:CDDL-1\.1)/,/^(?:CPAL-1\.0)/,/^(?:APSL-1\.2)/,/^(?:NPL-1\.1)/,/^(?:AFL-1\.2)/,/^(?:Caldera)/,/^(?:AFL-2\.0)/,/^(?:FSFULLR)/,/^(?:AFL-2\.1)/,/^(?:VSL-1\.0)/,/^(?:VOSTROM)/,/^(?:UPL-1\.0)/,/^(?:Dotseqn)/,/^(?:CPL-1\.0)/,/^(?:dvipdfm)/,/^(?:EPL-1\.0)/,/^(?:OCCT-PL)/,/^(?:ECL-1\.0)/,/^(?:Latex2e)/,/^(?:ECL-2\.0)/,/^(?:GPL-1\.0)/,/^(?:GPL-2\.0)/,/^(?:GPL-3\.0)/,/^(?:AFL-3\.0)/,/^(?:LAL-1\.2)/,/^(?:LAL-1\.3)/,/^(?:EFL-1\.0)/,/^(?:EFL-2\.0)/,/^(?:gnuplot)/,/^(?:Aladdin)/,/^(?:LPL-1\.0)/,/^(?:libtiff)/,/^(?:Entessa)/,/^(?:AMDPLPA)/,/^(?:IPL-1\.0)/,/^(?:OPL-1\.0)/,/^(?:OSL-1\.0)/,/^(?:OSL-1\.1)/,/^(?:OSL-2\.0)/,/^(?:OSL-2\.1)/,/^(?:OSL-3\.0)/,/^(?:OpenSSL)/,/^(?:ZPL-2\.1)/,/^(?:PHP-3\.0)/,/^(?:ZPL-2\.0)/,/^(?:ZPL-1\.1)/,/^(?:CC0-1\.0)/,/^(?:SPL-1\.0)/,/^(?:psutils)/,/^(?:MPL-1\.0)/,/^(?:QPL-1\.0)/,/^(?:MPL-1\.1)/,/^(?:MPL-2\.0)/,/^(?:APL-1\.0)/,/^(?:RPL-1\.1)/,/^(?:RPL-1\.5)/,/^(?:MIT-CMU)/,/^(?:Multics)/,/^(?:Eurosym)/,/^(?:BSL-1\.0)/,/^(?:MIT-feh)/,/^(?:Saxpath)/,/^(?:Borceux)/,/^(?:OFL-1\.1)/,/^(?:OFL-1\.0)/,/^(?:AFL-1\.1)/,/^(?:YPL-1\.1)/,/^(?:YPL-1\.0)/,/^(?:NPL-1\.0)/,/^(?:iMatix)/,/^(?:mpich2)/,/^(?:APAFML)/,/^(?:Bahyph)/,/^(?:RSA-MD)/,/^(?:psfrag)/,/^(?:Plexus)/,/^(?:eGenix)/,/^(?:Glulxe)/,/^(?:SAX-PD)/,/^(?:Imlib2)/,/^(?:Wsuipa)/,/^(?:LGPLLR)/,/^(?:Libpng)/,/^(?:xinetd)/,/^(?:MITNFA)/,/^(?:NetCDF)/,/^(?:Naumen)/,/^(?:SMPPL)/,/^(?:Nunit)/,/^(?:FSFUL)/,/^(?:GL2PS)/,/^(?:SMLNJ)/,/^(?:Rdisc)/,/^(?:Noweb)/,/^(?:Nokia)/,/^(?:SISSL)/,/^(?:Qhull)/,/^(?:Intel)/,/^(?:Glide)/,/^(?:Xerox)/,/^(?:AMPAS)/,/^(?:WTFPL)/,/^(?:MS-PL)/,/^(?:XSkat)/,/^(?:MS-RL)/,/^(?:MirOS)/,/^(?:RSCPL)/,/^(?:TMate)/,/^(?:OGTSL)/,/^(?:FSFAP)/,/^(?:NCSA)/,/^(?:Zlib)/,/^(?:SCEA)/,/^(?:SNIA)/,/^(?:NGPL)/,/^(?:NOSL)/,/^(?:ADSL)/,/^(?:MTLL)/,/^(?:NLPL)/,/^(?:Ruby)/,/^(?:JSON)/,/^(?:Barr)/,/^(?:0BSD)/,/^(?:Xnet)/,/^(?:Cube)/,/^(?:curl)/,/^(?:DSDP)/,/^(?:Fair)/,/^(?:HPND)/,/^(?:TOSL)/,/^(?:IJG)/,/^(?:SWL)/,/^(?:Vim)/,/^(?:FTL)/,/^(?:ICU)/,/^(?:OML)/,/^(?:NRL)/,/^(?:DOC)/,/^(?:TCL)/,/^(?:W3C)/,/^(?:NTP)/,/^(?:IPA)/,/^(?:ISC)/,/^(?:X11)/,/^(?:AAL)/,/^(?:AML)/,/^(?:xpp)/,/^(?:Zed)/,/^(?:MIT)/,/^(?:Mup)/], +conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364],"inclusive":true}} +}); +return lexer; +})(); +parser.lexer = lexer; +function Parser () { + this.yy = {}; +} +Parser.prototype = parser;parser.Parser = Parser; +return new Parser; +})(); -module.exports = function nodeModulesPaths(start, opts, request) { - var modules = opts && opts.moduleDirectory - ? [].concat(opts.moduleDirectory) - : ['node_modules']; - if (opts && typeof opts.paths === 'function') { - return opts.paths( - request, - start, - function () { return getNodeModulesDirs(start, modules); }, - opts - ); +if (true) { +exports.parser = spdxparse; +exports.Parser = spdxparse.Parser; +exports.parse = function () { return spdxparse.parse.apply(spdxparse, arguments); }; +exports.main = function commonjsMain(args) { + if (!args[1]) { + console.log('Usage: '+args[0]+' FILE'); + process.exit(1); } - - var dirs = getNodeModulesDirs(start, modules); - return opts && opts.paths ? dirs.concat(opts.paths) : dirs; + var source = __webpack_require__(349).readFileSync(__webpack_require__(4).normalize(args[1]), "utf8"); + return exports.parser.parse(source); }; - - -/***/ }), -/* 538 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var isWindows = process.platform === 'win32'; - -// Regex to split a windows path into three parts: [*, device, slash, -// tail] windows-only -var splitDeviceRe = - /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; - -// Regex to split the tail part of the above into [*, dir, basename, ext] -var splitTailRe = - /^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/; - -var win32 = {}; - -// Function to split a filename into [root, dir, basename, ext] -function win32SplitPath(filename) { - // Separate device+slash from tail - var result = splitDeviceRe.exec(filename), - device = (result[1] || '') + (result[2] || ''), - tail = result[3] || ''; - // Split the tail into dir, basename and extension - var result2 = splitTailRe.exec(tail), - dir = result2[1], - basename = result2[2], - ext = result2[3]; - return [device, dir, basename, ext]; +if ( true && __webpack_require__.c[__webpack_require__.s] === module) { + exports.main(process.argv.slice(1)); } - -win32.parse = function(pathString) { - if (typeof pathString !== 'string') { - throw new TypeError( - "Parameter 'pathString' must be a string, not " + typeof pathString - ); - } - var allParts = win32SplitPath(pathString); - if (!allParts || allParts.length !== 4) { - throw new TypeError("Invalid path '" + pathString + "'"); - } - return { - root: allParts[0], - dir: allParts[0] + allParts[1].slice(0, -1), - base: allParts[2], - ext: allParts[3], - name: allParts[2].slice(0, allParts[2].length - allParts[3].length) - }; -}; - - - -// Split a filename into [root, dir, basename, ext], unix version -// 'root' is just a slash, or nothing. -var splitPathRe = - /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; -var posix = {}; - - -function posixSplitPath(filename) { - return splitPathRe.exec(filename).slice(1); } - -posix.parse = function(pathString) { - if (typeof pathString !== 'string') { - throw new TypeError( - "Parameter 'pathString' must be a string, not " + typeof pathString - ); - } - var allParts = posixSplitPath(pathString); - if (!allParts || allParts.length !== 4) { - throw new TypeError("Invalid path '" + pathString + "'"); - } - allParts[1] = allParts[1] || ''; - allParts[2] = allParts[2] || ''; - allParts[3] = allParts[3] || ''; - - return { - root: allParts[0], - dir: allParts[0] + allParts[1].slice(0, -1), - base: allParts[2], - ext: allParts[3], - name: allParts[2].slice(0, allParts[2].length - allParts[3].length) - }; -}; - - -if (isWindows) - module.exports = win32.parse; -else /* posix */ - module.exports = posix.parse; - -module.exports.posix = posix.parse; -module.exports.win32 = win32.parse; - - -/***/ }), -/* 539 */ -/***/ (function(module, exports) { - -module.exports = function (x, opts) { - /** - * This file is purposefully a passthrough. It's expected that third-party - * environments will override it at runtime in order to inject special logic - * into `resolve` (by manipulating the options). One such example is the PnP - * code path in Yarn. - */ - - return opts || {}; -}; - +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(11)(module))) /***/ }), -/* 540 */ +/* 527 */ /***/ (function(module, exports, __webpack_require__) { -var core = __webpack_require__(533); -var fs = __webpack_require__(23); -var path = __webpack_require__(16); -var caller = __webpack_require__(536); -var nodeModulesPaths = __webpack_require__(537); -var normalizeOptions = __webpack_require__(539); - -var defaultIsFile = function isFile(file) { - try { - var stat = fs.statSync(file); - } catch (e) { - if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false; - throw e; - } - return stat.isFile() || stat.isFIFO(); -}; - -module.exports = function (x, options) { - if (typeof x !== 'string') { - throw new TypeError('Path must be a string.'); - } - var opts = normalizeOptions(x, options); - - var isFile = opts.isFile || defaultIsFile; - var readFileSync = opts.readFileSync || fs.readFileSync; - - var extensions = opts.extensions || ['.js']; - var basedir = opts.basedir || path.dirname(caller()); - var parent = opts.filename || basedir; - - opts.paths = opts.paths || []; +var licenseIDs = __webpack_require__(528); - // ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory - var absoluteStart = path.resolve(basedir); +function valid(string) { + return licenseIDs.indexOf(string) > -1; +} - if (opts.preserveSymlinks === false) { - try { - absoluteStart = fs.realpathSync(absoluteStart); - } catch (realPathErr) { - if (realPathErr.code !== 'ENOENT') { - throw realPathErr; - } - } - } +// Common transpositions of license identifier acronyms +var transpositions = [ + ['APGL', 'AGPL'], + ['Gpl', 'GPL'], + ['GLP', 'GPL'], + ['APL', 'Apache'], + ['ISD', 'ISC'], + ['GLP', 'GPL'], + ['IST', 'ISC'], + ['Claude', 'Clause'], + [' or later', '+'], + [' International', ''], + ['GNU', 'GPL'], + ['GUN', 'GPL'], + ['+', ''], + ['GNU GPL', 'GPL'], + ['GNU/GPL', 'GPL'], + ['GNU GLP', 'GPL'], + ['GNU General Public License', 'GPL'], + ['Gnu public license', 'GPL'], + ['GNU Public License', 'GPL'], + ['GNU GENERAL PUBLIC LICENSE', 'GPL'], + ['MTI', 'MIT'], + ['Mozilla Public License', 'MPL'], + ['WTH', 'WTF'], + ['-License', ''] +]; - if ((/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/).test(x)) { - var res = path.resolve(absoluteStart, x); - if (x === '..' || x.slice(-1) === '/') res += '/'; - var m = loadAsFileSync(res) || loadAsDirectorySync(res); - if (m) return m; - } else { - var n = loadNodeModulesSync(x, absoluteStart); - if (n) return n; - } +var TRANSPOSED = 0; +var CORRECT = 1; - if (core[x]) return x; +// Simple corrections to nearly valid identifiers. +var transforms = [ + // e.g. 'mit' + function(argument) { + return argument.toUpperCase(); + }, + // e.g. 'MIT ' + function(argument) { + return argument.trim(); + }, + // e.g. 'M.I.T.' + function(argument) { + return argument.replace(/\./g, ''); + }, + // e.g. 'Apache- 2.0' + function(argument) { + return argument.replace(/\s+/g, ''); + }, + // e.g. 'CC BY 4.0'' + function(argument) { + return argument.replace(/\s+/g, '-'); + }, + // e.g. 'LGPLv2.1' + function(argument) { + return argument.replace('v', '-'); + }, + // e.g. 'Apache 2.0' + function(argument) { + return argument.replace(/,?\s*(\d)/, '-$1'); + }, + // e.g. 'GPL 2' + function(argument) { + return argument.replace(/,?\s*(\d)/, '-$1.0'); + }, + // e.g. 'Apache Version 2.0' + function(argument) { + return argument.replace(/,?\s*(V\.|v\.|V|v|Version|version)\s*(\d)/, '-$2'); + }, + // e.g. 'Apache Version 2' + function(argument) { + return argument.replace(/,?\s*(V\.|v\.|V|v|Version|version)\s*(\d)/, '-$2.0'); + }, + // e.g. 'ZLIB' + function(argument) { + return argument[0].toUpperCase() + argument.slice(1); + }, + // e.g. 'MPL/2.0' + function(argument) { + return argument.replace('/', '-'); + }, + // e.g. 'Apache 2' + function(argument) { + return argument + .replace(/\s*V\s*(\d)/, '-$1') + .replace(/(\d)$/, '$1.0'); + }, + // e.g. 'GPL-2.0-' + function(argument) { + return argument.slice(0, argument.length - 1); + }, + // e.g. 'GPL2' + function(argument) { + return argument.replace(/(\d)$/, '-$1.0'); + }, + // e.g. 'BSD 3' + function(argument) { + return argument.replace(/(-| )?(\d)$/, '-$2-Clause'); + }, + // e.g. 'BSD clause 3' + function(argument) { + return argument.replace(/(-| )clause(-| )(\d)/, '-$3-Clause'); + }, + // e.g. 'BY-NC-4.0' + function(argument) { + return 'CC-' + argument; + }, + // e.g. 'BY-NC' + function(argument) { + return 'CC-' + argument + '-4.0'; + }, + // e.g. 'Attribution-NonCommercial' + function(argument) { + return argument + .replace('Attribution', 'BY') + .replace('NonCommercial', 'NC') + .replace('NoDerivatives', 'ND') + .replace(/ (\d)/, '-$1') + .replace(/ ?International/, ''); + }, + // e.g. 'Attribution-NonCommercial' + function(argument) { + return 'CC-' + + argument + .replace('Attribution', 'BY') + .replace('NonCommercial', 'NC') + .replace('NoDerivatives', 'ND') + .replace(/ (\d)/, '-$1') + .replace(/ ?International/, '') + + '-4.0'; + } +]; - var err = new Error("Cannot find module '" + x + "' from '" + parent + "'"); - err.code = 'MODULE_NOT_FOUND'; - throw err; +// If all else fails, guess that strings containing certain substrings +// meant to identify certain licenses. +var lastResorts = [ + ['UNLI', 'Unlicense'], + ['WTF', 'WTFPL'], + ['2 CLAUSE', 'BSD-2-Clause'], + ['2-CLAUSE', 'BSD-2-Clause'], + ['3 CLAUSE', 'BSD-3-Clause'], + ['3-CLAUSE', 'BSD-3-Clause'], + ['AFFERO', 'AGPL-3.0'], + ['AGPL', 'AGPL-3.0'], + ['APACHE', 'Apache-2.0'], + ['ARTISTIC', 'Artistic-2.0'], + ['Affero', 'AGPL-3.0'], + ['BEER', 'Beerware'], + ['BOOST', 'BSL-1.0'], + ['BSD', 'BSD-2-Clause'], + ['ECLIPSE', 'EPL-1.0'], + ['FUCK', 'WTFPL'], + ['GNU', 'GPL-3.0'], + ['LGPL', 'LGPL-3.0'], + ['GPL', 'GPL-3.0'], + ['MIT', 'MIT'], + ['MPL', 'MPL-2.0'], + ['X11', 'X11'], + ['ZLIB', 'Zlib'] +]; - function loadAsFileSync(x) { - var pkg = loadpkg(path.dirname(x)); +var SUBSTRING = 0; +var IDENTIFIER = 1; - if (pkg && pkg.dir && pkg.pkg && opts.pathFilter) { - var rfile = path.relative(pkg.dir, x); - var r = opts.pathFilter(pkg.pkg, x, rfile); - if (r) { - x = path.resolve(pkg.dir, r); // eslint-disable-line no-param-reassign - } - } +var validTransformation = function(identifier) { + for (var i = 0; i < transforms.length; i++) { + var transformed = transforms[i](identifier); + if (transformed !== identifier && valid(transformed)) { + return transformed; + } + } + return null; +}; - if (isFile(x)) { - return x; - } +var validLastResort = function(identifier) { + var upperCased = identifier.toUpperCase(); + for (var i = 0; i < lastResorts.length; i++) { + var lastResort = lastResorts[i]; + if (upperCased.indexOf(lastResort[SUBSTRING]) > -1) { + return lastResort[IDENTIFIER]; + } + } + return null; +}; - for (var i = 0; i < extensions.length; i++) { - var file = x + extensions[i]; - if (isFile(file)) { - return file; - } - } +var anyCorrection = function(identifier, check) { + for (var i = 0; i < transpositions.length; i++) { + var transposition = transpositions[i]; + var transposed = transposition[TRANSPOSED]; + if (identifier.indexOf(transposed) > -1) { + var corrected = identifier.replace( + transposed, + transposition[CORRECT] + ); + var checked = check(corrected); + if (checked !== null) { + return checked; + } } + } + return null; +}; - function loadpkg(dir) { - if (dir === '' || dir === '/') return; - if (process.platform === 'win32' && (/^\w:[/\\]*$/).test(dir)) { - return; - } - if ((/[/\\]node_modules[/\\]*$/).test(dir)) return; +module.exports = function(identifier) { + identifier = identifier.replace(/\+$/, ''); + if (valid(identifier)) { + return identifier; + } + var transformed = validTransformation(identifier); + if (transformed !== null) { + return transformed; + } + transformed = anyCorrection(identifier, function(argument) { + if (valid(argument)) { + return argument; + } + return validTransformation(argument); + }); + if (transformed !== null) { + return transformed; + } + transformed = validLastResort(identifier); + if (transformed !== null) { + return transformed; + } + transformed = anyCorrection(identifier, validLastResort); + if (transformed !== null) { + return transformed; + } + return null; +}; - var pkgfile = path.join(dir, 'package.json'); - if (!isFile(pkgfile)) { - return loadpkg(path.dirname(dir)); - } +/***/ }), +/* 528 */ +/***/ (function(module) { - var body = readFileSync(pkgfile); +module.exports = JSON.parse("[\"Glide\",\"Abstyles\",\"AFL-1.1\",\"AFL-1.2\",\"AFL-2.0\",\"AFL-2.1\",\"AFL-3.0\",\"AMPAS\",\"APL-1.0\",\"Adobe-Glyph\",\"APAFML\",\"Adobe-2006\",\"AGPL-1.0\",\"Afmparse\",\"Aladdin\",\"ADSL\",\"AMDPLPA\",\"ANTLR-PD\",\"Apache-1.0\",\"Apache-1.1\",\"Apache-2.0\",\"AML\",\"APSL-1.0\",\"APSL-1.1\",\"APSL-1.2\",\"APSL-2.0\",\"Artistic-1.0\",\"Artistic-1.0-Perl\",\"Artistic-1.0-cl8\",\"Artistic-2.0\",\"AAL\",\"Bahyph\",\"Barr\",\"Beerware\",\"BitTorrent-1.0\",\"BitTorrent-1.1\",\"BSL-1.0\",\"Borceux\",\"BSD-2-Clause\",\"BSD-2-Clause-FreeBSD\",\"BSD-2-Clause-NetBSD\",\"BSD-3-Clause\",\"BSD-3-Clause-Clear\",\"BSD-4-Clause\",\"BSD-Protection\",\"BSD-Source-Code\",\"BSD-3-Clause-Attribution\",\"0BSD\",\"BSD-4-Clause-UC\",\"bzip2-1.0.5\",\"bzip2-1.0.6\",\"Caldera\",\"CECILL-1.0\",\"CECILL-1.1\",\"CECILL-2.0\",\"CECILL-2.1\",\"CECILL-B\",\"CECILL-C\",\"ClArtistic\",\"MIT-CMU\",\"CNRI-Jython\",\"CNRI-Python\",\"CNRI-Python-GPL-Compatible\",\"CPOL-1.02\",\"CDDL-1.0\",\"CDDL-1.1\",\"CPAL-1.0\",\"CPL-1.0\",\"CATOSL-1.1\",\"Condor-1.1\",\"CC-BY-1.0\",\"CC-BY-2.0\",\"CC-BY-2.5\",\"CC-BY-3.0\",\"CC-BY-4.0\",\"CC-BY-ND-1.0\",\"CC-BY-ND-2.0\",\"CC-BY-ND-2.5\",\"CC-BY-ND-3.0\",\"CC-BY-ND-4.0\",\"CC-BY-NC-1.0\",\"CC-BY-NC-2.0\",\"CC-BY-NC-2.5\",\"CC-BY-NC-3.0\",\"CC-BY-NC-4.0\",\"CC-BY-NC-ND-1.0\",\"CC-BY-NC-ND-2.0\",\"CC-BY-NC-ND-2.5\",\"CC-BY-NC-ND-3.0\",\"CC-BY-NC-ND-4.0\",\"CC-BY-NC-SA-1.0\",\"CC-BY-NC-SA-2.0\",\"CC-BY-NC-SA-2.5\",\"CC-BY-NC-SA-3.0\",\"CC-BY-NC-SA-4.0\",\"CC-BY-SA-1.0\",\"CC-BY-SA-2.0\",\"CC-BY-SA-2.5\",\"CC-BY-SA-3.0\",\"CC-BY-SA-4.0\",\"CC0-1.0\",\"Crossword\",\"CrystalStacker\",\"CUA-OPL-1.0\",\"Cube\",\"curl\",\"D-FSL-1.0\",\"diffmark\",\"WTFPL\",\"DOC\",\"Dotseqn\",\"DSDP\",\"dvipdfm\",\"EPL-1.0\",\"ECL-1.0\",\"ECL-2.0\",\"eGenix\",\"EFL-1.0\",\"EFL-2.0\",\"MIT-advertising\",\"MIT-enna\",\"Entessa\",\"ErlPL-1.1\",\"EUDatagrid\",\"EUPL-1.0\",\"EUPL-1.1\",\"Eurosym\",\"Fair\",\"MIT-feh\",\"Frameworx-1.0\",\"FreeImage\",\"FTL\",\"FSFAP\",\"FSFUL\",\"FSFULLR\",\"Giftware\",\"GL2PS\",\"Glulxe\",\"AGPL-3.0\",\"GFDL-1.1\",\"GFDL-1.2\",\"GFDL-1.3\",\"GPL-1.0\",\"GPL-2.0\",\"GPL-3.0\",\"LGPL-2.1\",\"LGPL-3.0\",\"LGPL-2.0\",\"gnuplot\",\"gSOAP-1.3b\",\"HaskellReport\",\"HPND\",\"IBM-pibs\",\"IPL-1.0\",\"ICU\",\"ImageMagick\",\"iMatix\",\"Imlib2\",\"IJG\",\"Info-ZIP\",\"Intel-ACPI\",\"Intel\",\"Interbase-1.0\",\"IPA\",\"ISC\",\"JasPer-2.0\",\"JSON\",\"LPPL-1.0\",\"LPPL-1.1\",\"LPPL-1.2\",\"LPPL-1.3a\",\"LPPL-1.3c\",\"Latex2e\",\"BSD-3-Clause-LBNL\",\"Leptonica\",\"LGPLLR\",\"Libpng\",\"libtiff\",\"LAL-1.2\",\"LAL-1.3\",\"LiLiQ-P-1.1\",\"LiLiQ-Rplus-1.1\",\"LiLiQ-R-1.1\",\"LPL-1.02\",\"LPL-1.0\",\"MakeIndex\",\"MTLL\",\"MS-PL\",\"MS-RL\",\"MirOS\",\"MITNFA\",\"MIT\",\"Motosoto\",\"MPL-1.0\",\"MPL-1.1\",\"MPL-2.0\",\"MPL-2.0-no-copyleft-exception\",\"mpich2\",\"Multics\",\"Mup\",\"NASA-1.3\",\"Naumen\",\"NBPL-1.0\",\"NetCDF\",\"NGPL\",\"NOSL\",\"NPL-1.0\",\"NPL-1.1\",\"Newsletr\",\"NLPL\",\"Nokia\",\"NPOSL-3.0\",\"NLOD-1.0\",\"Noweb\",\"NRL\",\"NTP\",\"Nunit\",\"OCLC-2.0\",\"ODbL-1.0\",\"PDDL-1.0\",\"OCCT-PL\",\"OGTSL\",\"OLDAP-2.2.2\",\"OLDAP-1.1\",\"OLDAP-1.2\",\"OLDAP-1.3\",\"OLDAP-1.4\",\"OLDAP-2.0\",\"OLDAP-2.0.1\",\"OLDAP-2.1\",\"OLDAP-2.2\",\"OLDAP-2.2.1\",\"OLDAP-2.3\",\"OLDAP-2.4\",\"OLDAP-2.5\",\"OLDAP-2.6\",\"OLDAP-2.7\",\"OLDAP-2.8\",\"OML\",\"OPL-1.0\",\"OSL-1.0\",\"OSL-1.1\",\"OSL-2.0\",\"OSL-2.1\",\"OSL-3.0\",\"OpenSSL\",\"OSET-PL-2.1\",\"PHP-3.0\",\"PHP-3.01\",\"Plexus\",\"PostgreSQL\",\"psfrag\",\"psutils\",\"Python-2.0\",\"QPL-1.0\",\"Qhull\",\"Rdisc\",\"RPSL-1.0\",\"RPL-1.1\",\"RPL-1.5\",\"RHeCos-1.1\",\"RSCPL\",\"RSA-MD\",\"Ruby\",\"SAX-PD\",\"Saxpath\",\"SCEA\",\"SWL\",\"SMPPL\",\"Sendmail\",\"SGI-B-1.0\",\"SGI-B-1.1\",\"SGI-B-2.0\",\"OFL-1.0\",\"OFL-1.1\",\"SimPL-2.0\",\"Sleepycat\",\"SNIA\",\"Spencer-86\",\"Spencer-94\",\"Spencer-99\",\"SMLNJ\",\"SugarCRM-1.1.3\",\"SISSL\",\"SISSL-1.2\",\"SPL-1.0\",\"Watcom-1.0\",\"TCL\",\"Unlicense\",\"TMate\",\"TORQUE-1.1\",\"TOSL\",\"Unicode-TOU\",\"UPL-1.0\",\"NCSA\",\"Vim\",\"VOSTROM\",\"VSL-1.0\",\"W3C-19980720\",\"W3C\",\"Wsuipa\",\"Xnet\",\"X11\",\"Xerox\",\"XFree86-1.1\",\"xinetd\",\"xpp\",\"XSkat\",\"YPL-1.0\",\"YPL-1.1\",\"Zed\",\"Zend-2.0\",\"Zimbra-1.3\",\"Zimbra-1.4\",\"Zlib\",\"zlib-acknowledgement\",\"ZPL-1.1\",\"ZPL-2.0\",\"ZPL-2.1\",\"BSD-3-Clause-No-Nuclear-License\",\"BSD-3-Clause-No-Nuclear-Warranty\",\"BSD-3-Clause-No-Nuclear-License-2014\",\"eCos-2.0\",\"GPL-2.0-with-autoconf-exception\",\"GPL-2.0-with-bison-exception\",\"GPL-2.0-with-classpath-exception\",\"GPL-2.0-with-font-exception\",\"GPL-2.0-with-GCC-exception\",\"GPL-3.0-with-autoconf-exception\",\"GPL-3.0-with-GCC-exception\",\"StandardML-NJ\",\"WXwindows\"]"); - try { - var pkg = JSON.parse(body); - } catch (jsonErr) {} +/***/ }), +/* 529 */ +/***/ (function(module, exports, __webpack_require__) { - if (pkg && opts.packageFilter) { - pkg = opts.packageFilter(pkg, dir); - } +"use strict"; - return { pkg: pkg, dir: dir }; - } +var url = __webpack_require__(439) +var gitHosts = __webpack_require__(530) +var GitHost = module.exports = __webpack_require__(531) - function loadAsDirectorySync(x) { - var pkgfile = path.join(x, '/package.json'); - if (isFile(pkgfile)) { - try { - var body = readFileSync(pkgfile, 'UTF8'); - var pkg = JSON.parse(body); - } catch (e) {} +var protocolToRepresentationMap = { + 'git+ssh': 'sshurl', + 'git+https': 'https', + 'ssh': 'sshurl', + 'git': 'git' +} - if (opts.packageFilter) { - pkg = opts.packageFilter(pkg, x); - } +function protocolToRepresentation (protocol) { + if (protocol.substr(-1) === ':') protocol = protocol.slice(0, -1) + return protocolToRepresentationMap[protocol] || protocol +} - if (pkg.main) { - if (typeof pkg.main !== 'string') { - var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string'); - mainError.code = 'INVALID_PACKAGE_MAIN'; - throw mainError; - } - if (pkg.main === '.' || pkg.main === './') { - pkg.main = 'index'; - } - try { - var m = loadAsFileSync(path.resolve(x, pkg.main)); - if (m) return m; - var n = loadAsDirectorySync(path.resolve(x, pkg.main)); - if (n) return n; - } catch (e) {} - } - } +var authProtocols = { + 'git:': true, + 'https:': true, + 'git+https:': true, + 'http:': true, + 'git+http:': true +} - return loadAsFileSync(path.join(x, '/index')); - } +var cache = {} - function loadNodeModulesSync(x, start) { - var dirs = nodeModulesPaths(start, opts, x); - for (var i = 0; i < dirs.length; i++) { - var dir = dirs[i]; - var m = loadAsFileSync(path.join(dir, '/', x)); - if (m) return m; - var n = loadAsDirectorySync(path.join(dir, '/', x)); - if (n) return n; - } - } -}; +module.exports.fromUrl = function (giturl, opts) { + var key = giturl + JSON.stringify(opts || {}) + if (!(key in cache)) { + cache[key] = fromUrl(giturl, opts) + } -/***/ }), -/* 541 */ -/***/ (function(module, exports) { + return cache[key] +} -module.exports = extractDescription +function fromUrl (giturl, opts) { + if (giturl == null || giturl === '') return + var url = fixupUnqualifiedGist( + isGitHubShorthand(giturl) ? 'github:' + giturl : giturl + ) + var parsed = parseGitUrl(url) + var shortcutMatch = url.match(new RegExp('^([^:]+):(?:(?:[^@:]+(?:[^@]+)?@)?([^/]*))[/](.+?)(?:[.]git)?($|#)')) + var matches = Object.keys(gitHosts).map(function (gitHostName) { + try { + var gitHostInfo = gitHosts[gitHostName] + var auth = null + if (parsed.auth && authProtocols[parsed.protocol]) { + auth = decodeURIComponent(parsed.auth) + } + var committish = parsed.hash ? decodeURIComponent(parsed.hash.substr(1)) : null + var user = null + var project = null + var defaultRepresentation = null + if (shortcutMatch && shortcutMatch[1] === gitHostName) { + user = shortcutMatch[2] && decodeURIComponent(shortcutMatch[2]) + project = decodeURIComponent(shortcutMatch[3]) + defaultRepresentation = 'shortcut' + } else { + if (parsed.host !== gitHostInfo.domain) return + if (!gitHostInfo.protocols_re.test(parsed.protocol)) return + if (!parsed.path) return + var pathmatch = gitHostInfo.pathmatch + var matched = parsed.path.match(pathmatch) + if (!matched) return + if (matched[1] != null) user = decodeURIComponent(matched[1].replace(/^:/, '')) + if (matched[2] != null) project = decodeURIComponent(matched[2]) + defaultRepresentation = protocolToRepresentation(parsed.protocol) + } + return new GitHost(gitHostName, user, auth, project, committish, defaultRepresentation, opts) + } catch (ex) { + if (!(ex instanceof URIError)) throw ex + } + }).filter(function (gitHostInfo) { return gitHostInfo }) + if (matches.length !== 1) return + return matches[0] +} -// Extracts description from contents of a readme file in markdown format -function extractDescription (d) { - if (!d) return; - if (d === "ERROR: No README data found!") return; - // the first block of text before the first heading - // that isn't the first line heading - d = d.trim().split('\n') - for (var s = 0; d[s] && d[s].trim().match(/^(#|$)/); s ++); - var l = d.length - for (var e = s + 1; e < l && d[e].trim(); e ++); - return d.slice(s, e).join(' ').trim() +function isGitHubShorthand (arg) { + // Note: This does not fully test the git ref format. + // See https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html + // + // The only way to do this properly would be to shell out to + // git-check-ref-format, and as this is a fast sync function, + // we don't want to do that. Just let git fail if it turns + // out that the commit-ish is invalid. + // GH usernames cannot start with . or - + return /^[^:@%/\s.-][^:@%/\s]*[/][^:@\s/%]+(?:#.*)?$/.test(arg) } +function fixupUnqualifiedGist (giturl) { + // necessary for round-tripping gists + var parsed = url.parse(giturl) + if (parsed.protocol === 'gist:' && parsed.host && !parsed.path) { + return parsed.protocol + '/' + parsed.host + } else { + return giturl + } +} -/***/ }), -/* 542 */ -/***/ (function(module) { +function parseGitUrl (giturl) { + if (typeof giturl !== 'string') giturl = '' + giturl + var matched = giturl.match(/^([^@]+)@([^:/]+):[/]?((?:[^/]+[/])?[^/]+?)(?:[.]git)?(#.*)?$/) + if (!matched) return url.parse(giturl) + return { + protocol: 'git+ssh:', + slashes: true, + auth: matched[1], + host: matched[2], + port: null, + hostname: matched[2], + hash: matched[4], + search: null, + query: null, + pathname: '/' + matched[3], + path: '/' + matched[3], + href: 'git+ssh://' + matched[1] + '@' + matched[2] + + '/' + matched[3] + (matched[4] || '') + } +} -module.exports = JSON.parse("{\"topLevel\":{\"dependancies\":\"dependencies\",\"dependecies\":\"dependencies\",\"depdenencies\":\"dependencies\",\"devEependencies\":\"devDependencies\",\"depends\":\"dependencies\",\"dev-dependencies\":\"devDependencies\",\"devDependences\":\"devDependencies\",\"devDepenencies\":\"devDependencies\",\"devdependencies\":\"devDependencies\",\"repostitory\":\"repository\",\"repo\":\"repository\",\"prefereGlobal\":\"preferGlobal\",\"hompage\":\"homepage\",\"hampage\":\"homepage\",\"autohr\":\"author\",\"autor\":\"author\",\"contributers\":\"contributors\",\"publicationConfig\":\"publishConfig\",\"script\":\"scripts\"},\"bugs\":{\"web\":\"url\",\"name\":\"url\"},\"script\":{\"server\":\"start\",\"tests\":\"test\"}}"); /***/ }), -/* 543 */ +/* 530 */ /***/ (function(module, exports, __webpack_require__) { -var util = __webpack_require__(29) -var messages = __webpack_require__(544) +"use strict"; -module.exports = function() { - var args = Array.prototype.slice.call(arguments, 0) - var warningName = args.shift() - if (warningName == "typo") { - return makeTypoWarning.apply(null,args) - } - else { - var msgTemplate = messages[warningName] ? messages[warningName] : warningName + ": '%s'" - args.unshift(msgTemplate) - return util.format.apply(null, args) - } -} -function makeTypoWarning (providedName, probableName, field) { - if (field) { - providedName = field + "['" + providedName + "']" - probableName = field + "['" + probableName + "']" +var gitHosts = module.exports = { + github: { + // First two are insecure and generally shouldn't be used any more, but + // they are still supported. + 'protocols': [ 'git', 'http', 'git+ssh', 'git+https', 'ssh', 'https' ], + 'domain': 'github.com', + 'treepath': 'tree', + 'filetemplate': 'https://{auth@}raw.githubusercontent.com/{user}/{project}/{committish}/{path}', + 'bugstemplate': 'https://{domain}/{user}/{project}/issues', + 'gittemplate': 'git://{auth@}{domain}/{user}/{project}.git{#committish}', + 'tarballtemplate': 'https://{domain}/{user}/{project}/archive/{committish}.tar.gz' + }, + bitbucket: { + 'protocols': [ 'git+ssh', 'git+https', 'ssh', 'https' ], + 'domain': 'bitbucket.org', + 'treepath': 'src', + 'tarballtemplate': 'https://{domain}/{user}/{project}/get/{committish}.tar.gz' + }, + gitlab: { + 'protocols': [ 'git+ssh', 'git+https', 'ssh', 'https' ], + 'domain': 'gitlab.com', + 'treepath': 'tree', + 'docstemplate': 'https://{domain}/{user}/{project}{/tree/committish}#README', + 'bugstemplate': 'https://{domain}/{user}/{project}/issues', + 'tarballtemplate': 'https://{domain}/{user}/{project}/repository/archive.tar.gz?ref={committish}' + }, + gist: { + 'protocols': [ 'git', 'git+ssh', 'git+https', 'ssh', 'https' ], + 'domain': 'gist.github.com', + 'pathmatch': /^[/](?:([^/]+)[/])?([a-z0-9]+)(?:[.]git)?$/, + 'filetemplate': 'https://gist.githubusercontent.com/{user}/{project}/raw{/committish}/{path}', + 'bugstemplate': 'https://{domain}/{project}', + 'gittemplate': 'git://{domain}/{project}.git{#committish}', + 'sshtemplate': 'git@{domain}:/{project}.git{#committish}', + 'sshurltemplate': 'git+ssh://git@{domain}/{project}.git{#committish}', + 'browsetemplate': 'https://{domain}/{project}{/committish}', + 'docstemplate': 'https://{domain}/{project}{/committish}', + 'httpstemplate': 'git+https://{domain}/{project}.git{#committish}', + 'shortcuttemplate': '{type}:{project}{#committish}', + 'pathtemplate': '{project}{#committish}', + 'tarballtemplate': 'https://{domain}/{user}/{project}/archive/{committish}.tar.gz' } - return util.format(messages.typo, providedName, probableName) } +var gitHostDefaults = { + 'sshtemplate': 'git@{domain}:{user}/{project}.git{#committish}', + 'sshurltemplate': 'git+ssh://git@{domain}/{user}/{project}.git{#committish}', + 'browsetemplate': 'https://{domain}/{user}/{project}{/tree/committish}', + 'docstemplate': 'https://{domain}/{user}/{project}{/tree/committish}#readme', + 'httpstemplate': 'git+https://{auth@}{domain}/{user}/{project}.git{#committish}', + 'filetemplate': 'https://{domain}/{user}/{project}/raw/{committish}/{path}', + 'shortcuttemplate': '{type}:{user}/{project}{#committish}', + 'pathtemplate': '{user}/{project}{#committish}', + 'pathmatch': /^[/]([^/]+)[/]([^/]+?)(?:[.]git|[/])?$/ +} -/***/ }), -/* 544 */ -/***/ (function(module) { +Object.keys(gitHosts).forEach(function (name) { + Object.keys(gitHostDefaults).forEach(function (key) { + if (gitHosts[name][key]) return + gitHosts[name][key] = gitHostDefaults[key] + }) + gitHosts[name].protocols_re = RegExp('^(' + + gitHosts[name].protocols.map(function (protocol) { + return protocol.replace(/([\\+*{}()[\]$^|])/g, '\\$1') + }).join('|') + '):$') +}) -module.exports = JSON.parse("{\"repositories\":\"'repositories' (plural) Not supported. Please pick one as the 'repository' field\",\"missingRepository\":\"No repository field.\",\"brokenGitUrl\":\"Probably broken git url: %s\",\"nonObjectScripts\":\"scripts must be an object\",\"nonStringScript\":\"script values must be string commands\",\"nonArrayFiles\":\"Invalid 'files' member\",\"invalidFilename\":\"Invalid filename in 'files' list: %s\",\"nonArrayBundleDependencies\":\"Invalid 'bundleDependencies' list. Must be array of package names\",\"nonStringBundleDependency\":\"Invalid bundleDependencies member: %s\",\"nonDependencyBundleDependency\":\"Non-dependency in bundleDependencies: %s\",\"nonObjectDependencies\":\"%s field must be an object\",\"nonStringDependency\":\"Invalid dependency: %s %s\",\"deprecatedArrayDependencies\":\"specifying %s as array is deprecated\",\"deprecatedModules\":\"modules field is deprecated\",\"nonArrayKeywords\":\"keywords should be an array of strings\",\"nonStringKeyword\":\"keywords should be an array of strings\",\"conflictingName\":\"%s is also the name of a node core module.\",\"nonStringDescription\":\"'description' field should be a string\",\"missingDescription\":\"No description\",\"missingReadme\":\"No README data\",\"missingLicense\":\"No license field.\",\"nonEmailUrlBugsString\":\"Bug string field must be url, email, or {email,url}\",\"nonUrlBugsUrlField\":\"bugs.url field must be a string url. Deleted.\",\"nonEmailBugsEmailField\":\"bugs.email field must be a string email. Deleted.\",\"emptyNormalizedBugs\":\"Normalized value of bugs field is an empty object. Deleted.\",\"nonUrlHomepage\":\"homepage field must be a string url. Deleted.\",\"invalidLicense\":\"license should be a valid SPDX license expression\",\"typo\":\"%s should probably be %s.\"}"); /***/ }), -/* 545 */ +/* 531 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const path = __webpack_require__(16); -const writeJsonFile = __webpack_require__(546); -const sortKeys = __webpack_require__(558); - -const dependencyKeys = new Set([ - 'dependencies', - 'devDependencies', - 'optionalDependencies', - 'peerDependencies' -]); - -function normalize(packageJson) { - const result = {}; - - for (const key of Object.keys(packageJson)) { - if (!dependencyKeys.has(key)) { - result[key] = packageJson[key]; - } else if (Object.keys(packageJson[key]).length !== 0) { - result[key] = sortKeys(packageJson[key]); - } - } +var gitHosts = __webpack_require__(530) +var extend = Object.assign || __webpack_require__(397)._extend - return result; +var GitHost = module.exports = function (type, user, auth, project, committish, defaultRepresentation, opts) { + var gitHostInfo = this + gitHostInfo.type = type + Object.keys(gitHosts[type]).forEach(function (key) { + gitHostInfo[key] = gitHosts[type][key] + }) + gitHostInfo.user = user + gitHostInfo.auth = auth + gitHostInfo.project = project + gitHostInfo.committish = committish + gitHostInfo.default = defaultRepresentation + gitHostInfo.opts = opts || {} } +GitHost.prototype = {} -module.exports = async (filePath, data, options) => { - if (typeof filePath !== 'string') { - options = data; - data = filePath; - filePath = '.'; - } +GitHost.prototype.hash = function () { + return this.committish ? '#' + this.committish : '' +} - options = { - normalize: true, - ...options, - detectIndent: true - }; +GitHost.prototype._fill = function (template, opts) { + if (!template) return + var vars = extend({}, opts) + opts = extend(extend({}, this.opts), opts) + var self = this + Object.keys(this).forEach(function (key) { + if (self[key] != null && vars[key] == null) vars[key] = self[key] + }) + var rawAuth = vars.auth + var rawComittish = vars.committish + Object.keys(vars).forEach(function (key) { + vars[key] = encodeURIComponent(vars[key]) + }) + vars['auth@'] = rawAuth ? rawAuth + '@' : '' + if (opts.noCommittish) { + vars['#committish'] = '' + vars['/tree/committish'] = '' + vars['/comittish'] = '' + vars.comittish = '' + } else { + vars['#committish'] = rawComittish ? '#' + rawComittish : '' + vars['/tree/committish'] = vars.committish + ? '/' + vars.treepath + '/' + vars.committish + : '' + vars['/committish'] = vars.committish ? '/' + vars.committish : '' + vars.committish = vars.committish || 'master' + } + var res = template + Object.keys(vars).forEach(function (key) { + res = res.replace(new RegExp('[{]' + key + '[}]', 'g'), vars[key]) + }) + if (opts.noGitPlus) { + return res.replace(/^git[+]/, '') + } else { + return res + } +} - filePath = path.basename(filePath) === 'package.json' ? filePath : path.join(filePath, 'package.json'); +GitHost.prototype.ssh = function (opts) { + return this._fill(this.sshtemplate, opts) +} - data = options.normalize ? normalize(data) : data; +GitHost.prototype.sshurl = function (opts) { + return this._fill(this.sshurltemplate, opts) +} - return writeJsonFile(filePath, data, options); -}; +GitHost.prototype.browse = function (opts) { + return this._fill(this.browsetemplate, opts) +} -module.exports.sync = (filePath, data, options) => { - if (typeof filePath !== 'string') { - options = data; - data = filePath; - filePath = '.'; - } +GitHost.prototype.docs = function (opts) { + return this._fill(this.docstemplate, opts) +} - options = { - normalize: true, - ...options, - detectIndent: true - }; +GitHost.prototype.bugs = function (opts) { + return this._fill(this.bugstemplate, opts) +} - filePath = path.basename(filePath) === 'package.json' ? filePath : path.join(filePath, 'package.json'); +GitHost.prototype.https = function (opts) { + return this._fill(this.httpstemplate, opts) +} - data = options.normalize ? normalize(data) : data; +GitHost.prototype.git = function (opts) { + return this._fill(this.gittemplate, opts) +} - writeJsonFile.sync(filePath, data, options); -}; +GitHost.prototype.shortcut = function (opts) { + return this._fill(this.shortcuttemplate, opts) +} +GitHost.prototype.path = function (opts) { + return this._fill(this.pathtemplate, opts) +} -/***/ }), -/* 546 */ -/***/ (function(module, exports, __webpack_require__) { +GitHost.prototype.tarball = function (opts) { + return this._fill(this.tarballtemplate, opts) +} -"use strict"; +GitHost.prototype.file = function (P, opts) { + return this._fill(this.filetemplate, extend({ + path: P.replace(/^[/]+/g, '') + }, opts)) +} -const path = __webpack_require__(16); -const fs = __webpack_require__(547); -const writeFileAtomic = __webpack_require__(551); -const sortKeys = __webpack_require__(558); -const makeDir = __webpack_require__(560); -const pify = __webpack_require__(561); -const detectIndent = __webpack_require__(562); +GitHost.prototype.getDefaultRepresentation = function () { + return this.default +} -const init = (fn, filePath, data, options) => { - if (!filePath) { - throw new TypeError('Expected a filepath'); - } +GitHost.prototype.toString = function (opts) { + return (this[this.default] || this.sshurl).call(this, opts) +} - if (data === undefined) { - throw new TypeError('Expected data to stringify'); - } - options = Object.assign({ - indent: '\t', - sortKeys: false - }, options); +/***/ }), +/* 532 */ +/***/ (function(module, exports, __webpack_require__) { - if (options.sortKeys) { - data = sortKeys(data, { - deep: true, - compare: typeof options.sortKeys === 'function' ? options.sortKeys : undefined - }); - } +var core = __webpack_require__(533); +var async = __webpack_require__(535); +async.core = core; +async.isCore = function isCore(x) { return core[x]; }; +async.sync = __webpack_require__(540); - return fn(filePath, data, options); -}; +exports = async; +module.exports = async; -const readFile = filePath => pify(fs.readFile)(filePath, 'utf8').catch(() => {}); -const main = (filePath, data, options) => { - return (options.detectIndent ? readFile(filePath) : Promise.resolve()) - .then(string => { - const indent = string ? detectIndent(string).indent : options.indent; - const json = JSON.stringify(data, options.replacer, indent); +/***/ }), +/* 533 */ +/***/ (function(module, exports, __webpack_require__) { - return pify(writeFileAtomic)(filePath, `${json}\n`, {mode: options.mode}); - }); -}; +var current = (process.versions && process.versions.node && process.versions.node.split('.')) || []; -const mainSync = (filePath, data, options) => { - let {indent} = options; +function specifierIncluded(specifier) { + var parts = specifier.split(' '); + var op = parts.length > 1 ? parts[0] : '='; + var versionParts = (parts.length > 1 ? parts[1] : parts[0]).split('.'); - if (options.detectIndent) { - try { - const file = fs.readFileSync(filePath, 'utf8'); - indent = detectIndent(file).indent; - } catch (error) { - if (error.code !== 'ENOENT') { - throw error; - } - } - } + for (var i = 0; i < 3; ++i) { + var cur = Number(current[i] || 0); + var ver = Number(versionParts[i] || 0); + if (cur === ver) { + continue; // eslint-disable-line no-restricted-syntax, no-continue + } + if (op === '<') { + return cur < ver; + } else if (op === '>=') { + return cur >= ver; + } else { + return false; + } + } + return op === '>='; +} - const json = JSON.stringify(data, options.replacer, indent); +function matchesRange(range) { + var specifiers = range.split(/ ?&& ?/); + if (specifiers.length === 0) { return false; } + for (var i = 0; i < specifiers.length; ++i) { + if (!specifierIncluded(specifiers[i])) { return false; } + } + return true; +} - return writeFileAtomic.sync(filePath, `${json}\n`, {mode: options.mode}); -}; +function versionIncluded(specifierValue) { + if (typeof specifierValue === 'boolean') { return specifierValue; } + if (specifierValue && typeof specifierValue === 'object') { + for (var i = 0; i < specifierValue.length; ++i) { + if (matchesRange(specifierValue[i])) { return true; } + } + return false; + } + return matchesRange(specifierValue); +} -const writeJsonFile = (filePath, data, options) => { - return makeDir(path.dirname(filePath), {fs}) - .then(() => init(main, filePath, data, options)); -}; +var data = __webpack_require__(534); -module.exports = writeJsonFile; -// TODO: Remove this for the next major release -module.exports.default = writeJsonFile; -module.exports.sync = (filePath, data, options) => { - makeDir.sync(path.dirname(filePath), {fs}); - init(mainSync, filePath, data, options); -}; +var core = {}; +for (var mod in data) { // eslint-disable-line no-restricted-syntax + if (Object.prototype.hasOwnProperty.call(data, mod)) { + core[mod] = versionIncluded(data[mod]); + } +} +module.exports = core; /***/ }), -/* 547 */ -/***/ (function(module, exports, __webpack_require__) { +/* 534 */ +/***/ (function(module) { -var fs = __webpack_require__(23) -var polyfills = __webpack_require__(548) -var legacy = __webpack_require__(549) -var clone = __webpack_require__(550) +module.exports = JSON.parse("{\"assert\":true,\"async_hooks\":\">= 8\",\"buffer_ieee754\":\"< 0.9.7\",\"buffer\":true,\"child_process\":true,\"cluster\":true,\"console\":true,\"constants\":true,\"crypto\":true,\"_debugger\":\"< 8\",\"dgram\":true,\"dns\":true,\"domain\":true,\"events\":true,\"freelist\":\"< 6\",\"fs\":true,\"fs/promises\":\">= 10 && < 10.1\",\"_http_agent\":\">= 0.11.1\",\"_http_client\":\">= 0.11.1\",\"_http_common\":\">= 0.11.1\",\"_http_incoming\":\">= 0.11.1\",\"_http_outgoing\":\">= 0.11.1\",\"_http_server\":\">= 0.11.1\",\"http\":true,\"http2\":\">= 8.8\",\"https\":true,\"inspector\":\">= 8.0.0\",\"_linklist\":\"< 8\",\"module\":true,\"net\":true,\"node-inspect/lib/_inspect\":\">= 7.6.0\",\"node-inspect/lib/internal/inspect_client\":\">= 7.6.0\",\"node-inspect/lib/internal/inspect_repl\":\">= 7.6.0\",\"os\":true,\"path\":true,\"perf_hooks\":\">= 8.5\",\"process\":\">= 1\",\"punycode\":true,\"querystring\":true,\"readline\":true,\"repl\":true,\"smalloc\":\">= 0.11.5 && < 3\",\"_stream_duplex\":\">= 0.9.4\",\"_stream_transform\":\">= 0.9.4\",\"_stream_wrap\":\">= 1.4.1\",\"_stream_passthrough\":\">= 0.9.4\",\"_stream_readable\":\">= 0.9.4\",\"_stream_writable\":\">= 0.9.4\",\"stream\":true,\"string_decoder\":true,\"sys\":true,\"timers\":true,\"_tls_common\":\">= 0.11.13\",\"_tls_legacy\":\">= 0.11.3 && < 10\",\"_tls_wrap\":\">= 0.11.3\",\"tls\":true,\"trace_events\":\">= 10\",\"tty\":true,\"url\":true,\"util\":true,\"v8/tools/arguments\":\">= 10\",\"v8/tools/codemap\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8/tools/consarray\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8/tools/csvparser\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8/tools/logreader\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8/tools/profile_view\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8/tools/splaytree\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8\":\">= 1\",\"vm\":true,\"worker_threads\":\">= 11.7\",\"zlib\":true}"); -var queue = [] +/***/ }), +/* 535 */ +/***/ (function(module, exports, __webpack_require__) { -var util = __webpack_require__(29) +var core = __webpack_require__(533); +var fs = __webpack_require__(349); +var path = __webpack_require__(4); +var caller = __webpack_require__(536); +var nodeModulesPaths = __webpack_require__(537); +var normalizeOptions = __webpack_require__(539); -function noop () {} +var defaultIsFile = function isFile(file, cb) { + fs.stat(file, function (err, stat) { + if (!err) { + return cb(null, stat.isFile() || stat.isFIFO()); + } + if (err.code === 'ENOENT' || err.code === 'ENOTDIR') return cb(null, false); + return cb(err); + }); +}; -var debug = noop -if (util.debuglog) - debug = util.debuglog('gfs4') -else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) - debug = function() { - var m = util.format.apply(util, arguments) - m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') - console.error(m) - } +module.exports = function resolve(x, options, callback) { + var cb = callback; + var opts = options; + if (typeof options === 'function') { + cb = opts; + opts = {}; + } + if (typeof x !== 'string') { + var err = new TypeError('Path must be a string.'); + return process.nextTick(function () { + cb(err); + }); + } -if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { - process.on('exit', function() { - debug(queue) - __webpack_require__(30).equal(queue.length, 0) - }) -} + opts = normalizeOptions(x, opts); -module.exports = patch(clone(fs)) -if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) { - module.exports = patch(fs) - fs.__patched = true; -} + var isFile = opts.isFile || defaultIsFile; + var readFile = opts.readFile || fs.readFile; -// Always patch fs.close/closeSync, because we want to -// retry() whenever a close happens *anywhere* in the program. -// This is essential when multiple graceful-fs instances are -// in play at the same time. -module.exports.close = (function (fs$close) { return function (fd, cb) { - return fs$close.call(fs, fd, function (err) { - if (!err) - retry() + var extensions = opts.extensions || ['.js']; + var basedir = opts.basedir || path.dirname(caller()); + var parent = opts.filename || basedir; - if (typeof cb === 'function') - cb.apply(this, arguments) - }) -}})(fs.close) + opts.paths = opts.paths || []; -module.exports.closeSync = (function (fs$closeSync) { return function (fd) { - // Note that graceful-fs also retries when fs.closeSync() fails. - // Looks like a bug to me, although it's probably a harmless one. - var rval = fs$closeSync.apply(fs, arguments) - retry() - return rval -}})(fs.closeSync) + // ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory + var absoluteStart = path.resolve(basedir); -// Only patch fs once, otherwise we'll run into a memory leak if -// graceful-fs is loaded multiple times, such as in test environments that -// reset the loaded modules between tests. -// We look for the string `graceful-fs` from the comment above. This -// way we are not adding any extra properties and it will detect if older -// versions of graceful-fs are installed. -if (!/\bgraceful-fs\b/.test(fs.closeSync.toString())) { - fs.closeSync = module.exports.closeSync; - fs.close = module.exports.close; -} + if (opts.preserveSymlinks === false) { + fs.realpath(absoluteStart, function (realPathErr, realStart) { + if (realPathErr && realPathErr.code !== 'ENOENT') cb(err); + else init(realPathErr ? absoluteStart : realStart); + }); + } else { + init(absoluteStart); + } -function patch (fs) { - // Everything that references the open() function needs to be in here - polyfills(fs) - fs.gracefulify = patch - fs.FileReadStream = ReadStream; // Legacy name. - fs.FileWriteStream = WriteStream; // Legacy name. - fs.createReadStream = createReadStream - fs.createWriteStream = createWriteStream - var fs$readFile = fs.readFile - fs.readFile = readFile - function readFile (path, options, cb) { - if (typeof options === 'function') - cb = options, options = null + var res; + function init(basedir) { + if ((/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/).test(x)) { + res = path.resolve(basedir, x); + if (x === '..' || x.slice(-1) === '/') res += '/'; + if ((/\/$/).test(x) && res === basedir) { + loadAsDirectory(res, opts.package, onfile); + } else loadAsFile(res, opts.package, onfile); + } else loadNodeModules(x, basedir, function (err, n, pkg) { + if (err) cb(err); + else if (n) cb(null, n, pkg); + else if (core[x]) return cb(null, x); + else { + var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'"); + moduleError.code = 'MODULE_NOT_FOUND'; + cb(moduleError); + } + }); + } - return go$readFile(path, options, cb) + function onfile(err, m, pkg) { + if (err) cb(err); + else if (m) cb(null, m, pkg); + else loadAsDirectory(res, function (err, d, pkg) { + if (err) cb(err); + else if (d) cb(null, d, pkg); + else { + var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'"); + moduleError.code = 'MODULE_NOT_FOUND'; + cb(moduleError); + } + }); + } - function go$readFile (path, options, cb) { - return fs$readFile(path, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$readFile, [path, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() + function loadAsFile(x, thePackage, callback) { + var loadAsFilePackage = thePackage; + var cb = callback; + if (typeof loadAsFilePackage === 'function') { + cb = loadAsFilePackage; + loadAsFilePackage = undefined; } - }) - } - } - var fs$writeFile = fs.writeFile - fs.writeFile = writeFile - function writeFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null + var exts = [''].concat(extensions); + load(exts, x, loadAsFilePackage); - return go$writeFile(path, data, options, cb) + function load(exts, x, loadPackage) { + if (exts.length === 0) return cb(null, undefined, loadPackage); + var file = x + exts[0]; - function go$writeFile (path, data, options, cb) { - return fs$writeFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$writeFile, [path, data, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() + var pkg = loadPackage; + if (pkg) onpkg(null, pkg); + else loadpkg(path.dirname(file), onpkg); + + function onpkg(err, pkg_, dir) { + pkg = pkg_; + if (err) return cb(err); + if (dir && pkg && opts.pathFilter) { + var rfile = path.relative(dir, file); + var rel = rfile.slice(0, rfile.length - exts[0].length); + var r = opts.pathFilter(pkg, x, rel); + if (r) return load( + [''].concat(extensions.slice()), + path.resolve(dir, r), + pkg + ); + } + isFile(file, onex); + } + function onex(err, ex) { + if (err) return cb(err); + if (ex) return cb(null, file, pkg); + load(exts.slice(1), x, pkg); + } } - }) } - } - var fs$appendFile = fs.appendFile - if (fs$appendFile) - fs.appendFile = appendFile - function appendFile (path, data, options, cb) { - if (typeof options === 'function') - cb = options, options = null + function loadpkg(dir, cb) { + if (dir === '' || dir === '/') return cb(null); + if (process.platform === 'win32' && (/^\w:[/\\]*$/).test(dir)) { + return cb(null); + } + if ((/[/\\]node_modules[/\\]*$/).test(dir)) return cb(null); - return go$appendFile(path, data, options, cb) + var pkgfile = path.join(dir, 'package.json'); + isFile(pkgfile, function (err, ex) { + // on err, ex is false + if (!ex) return loadpkg(path.dirname(dir), cb); - function go$appendFile (path, data, options, cb) { - return fs$appendFile(path, data, options, function (err) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$appendFile, [path, data, options, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) - } - } + readFile(pkgfile, function (err, body) { + if (err) cb(err); + try { var pkg = JSON.parse(body); } catch (jsonErr) {} - var fs$readdir = fs.readdir - fs.readdir = readdir - function readdir (path, options, cb) { - var args = [path] - if (typeof options !== 'function') { - args.push(options) - } else { - cb = options + if (pkg && opts.packageFilter) { + pkg = opts.packageFilter(pkg, pkgfile); + } + cb(null, pkg, dir); + }); + }); } - args.push(go$readdir$cb) - return go$readdir(args) + function loadAsDirectory(x, loadAsDirectoryPackage, callback) { + var cb = callback; + var fpkg = loadAsDirectoryPackage; + if (typeof fpkg === 'function') { + cb = fpkg; + fpkg = opts.package; + } - function go$readdir$cb (err, files) { - if (files && files.sort) - files.sort() + var pkgfile = path.join(x, 'package.json'); + isFile(pkgfile, function (err, ex) { + if (err) return cb(err); + if (!ex) return loadAsFile(path.join(x, 'index'), fpkg, cb); - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$readdir, [args]]) + readFile(pkgfile, function (err, body) { + if (err) return cb(err); + try { + var pkg = JSON.parse(body); + } catch (jsonErr) {} - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - } - } + if (opts.packageFilter) { + pkg = opts.packageFilter(pkg, pkgfile); + } - function go$readdir (args) { - return fs$readdir.apply(fs, args) - } + if (pkg.main) { + if (typeof pkg.main !== 'string') { + var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string'); + mainError.code = 'INVALID_PACKAGE_MAIN'; + return cb(mainError); + } + if (pkg.main === '.' || pkg.main === './') { + pkg.main = 'index'; + } + loadAsFile(path.resolve(x, pkg.main), pkg, function (err, m, pkg) { + if (err) return cb(err); + if (m) return cb(null, m, pkg); + if (!pkg) return loadAsFile(path.join(x, 'index'), pkg, cb); - if (process.version.substr(0, 4) === 'v0.8') { - var legStreams = legacy(fs) - ReadStream = legStreams.ReadStream - WriteStream = legStreams.WriteStream - } + var dir = path.resolve(x, pkg.main); + loadAsDirectory(dir, pkg, function (err, n, pkg) { + if (err) return cb(err); + if (n) return cb(null, n, pkg); + loadAsFile(path.join(x, 'index'), pkg, cb); + }); + }); + return; + } - var fs$ReadStream = fs.ReadStream - if (fs$ReadStream) { - ReadStream.prototype = Object.create(fs$ReadStream.prototype) - ReadStream.prototype.open = ReadStream$open - } + loadAsFile(path.join(x, '/index'), pkg, cb); + }); + }); + } - var fs$WriteStream = fs.WriteStream - if (fs$WriteStream) { - WriteStream.prototype = Object.create(fs$WriteStream.prototype) - WriteStream.prototype.open = WriteStream$open - } + function processDirs(cb, dirs) { + if (dirs.length === 0) return cb(null, undefined); + var dir = dirs[0]; - fs.ReadStream = ReadStream - fs.WriteStream = WriteStream + var file = path.join(dir, x); + loadAsFile(file, opts.package, onfile); - function ReadStream (path, options) { - if (this instanceof ReadStream) - return fs$ReadStream.apply(this, arguments), this - else - return ReadStream.apply(Object.create(ReadStream.prototype), arguments) - } + function onfile(err, m, pkg) { + if (err) return cb(err); + if (m) return cb(null, m, pkg); + loadAsDirectory(path.join(dir, x), opts.package, ondir); + } - function ReadStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - if (that.autoClose) - that.destroy() + function ondir(err, n, pkg) { + if (err) return cb(err); + if (n) return cb(null, n, pkg); + processDirs(cb, dirs.slice(1)); + } + } + function loadNodeModules(x, start, cb) { + processDirs(cb, nodeModulesPaths(start, opts, x)); + } +}; - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - that.read() - } - }) - } - function WriteStream (path, options) { - if (this instanceof WriteStream) - return fs$WriteStream.apply(this, arguments), this - else - return WriteStream.apply(Object.create(WriteStream.prototype), arguments) - } +/***/ }), +/* 536 */ +/***/ (function(module, exports) { - function WriteStream$open () { - var that = this - open(that.path, that.flags, that.mode, function (err, fd) { - if (err) { - that.destroy() - that.emit('error', err) - } else { - that.fd = fd - that.emit('open', fd) - } - }) - } +module.exports = function () { + // see https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi + var origPrepareStackTrace = Error.prepareStackTrace; + Error.prepareStackTrace = function (_, stack) { return stack; }; + var stack = (new Error()).stack; + Error.prepareStackTrace = origPrepareStackTrace; + return stack[2].getFileName(); +}; - function createReadStream (path, options) { - return new ReadStream(path, options) - } - function createWriteStream (path, options) { - return new WriteStream(path, options) - } +/***/ }), +/* 537 */ +/***/ (function(module, exports, __webpack_require__) { - var fs$open = fs.open - fs.open = open - function open (path, flags, mode, cb) { - if (typeof mode === 'function') - cb = mode, mode = null +var path = __webpack_require__(4); +var parse = path.parse || __webpack_require__(538); - return go$open(path, flags, mode, cb) +var getNodeModulesDirs = function getNodeModulesDirs(absoluteStart, modules) { + var prefix = '/'; + if ((/^([A-Za-z]:)/).test(absoluteStart)) { + prefix = ''; + } else if ((/^\\\\/).test(absoluteStart)) { + prefix = '\\\\'; + } - function go$open (path, flags, mode, cb) { - return fs$open(path, flags, mode, function (err, fd) { - if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) - enqueue([go$open, [path, flags, mode, cb]]) - else { - if (typeof cb === 'function') - cb.apply(this, arguments) - retry() - } - }) + var paths = [absoluteStart]; + var parsed = parse(absoluteStart); + while (parsed.dir !== paths[paths.length - 1]) { + paths.push(parsed.dir); + parsed = parse(parsed.dir); } - } - return fs -} + return paths.reduce(function (dirs, aPath) { + return dirs.concat(modules.map(function (moduleDir) { + return path.join(prefix, aPath, moduleDir); + })); + }, []); +}; -function enqueue (elem) { - debug('ENQUEUE', elem[0].name, elem[1]) - queue.push(elem) -} +module.exports = function nodeModulesPaths(start, opts, request) { + var modules = opts && opts.moduleDirectory + ? [].concat(opts.moduleDirectory) + : ['node_modules']; -function retry () { - var elem = queue.shift() - if (elem) { - debug('RETRY', elem[0].name, elem[1]) - elem[0].apply(null, elem[1]) - } -} + if (opts && typeof opts.paths === 'function') { + return opts.paths( + request, + start, + function () { return getNodeModulesDirs(start, modules); }, + opts + ); + } + + var dirs = getNodeModulesDirs(start, modules); + return opts && opts.paths ? dirs.concat(opts.paths) : dirs; +}; /***/ }), -/* 548 */ +/* 538 */ /***/ (function(module, exports, __webpack_require__) { -var constants = __webpack_require__(25) +"use strict"; -var origCwd = process.cwd -var cwd = null -var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform +var isWindows = process.platform === 'win32'; -process.cwd = function() { - if (!cwd) - cwd = origCwd.call(process) - return cwd -} -try { - process.cwd() -} catch (er) {} +// Regex to split a windows path into three parts: [*, device, slash, +// tail] windows-only +var splitDeviceRe = + /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; -var chdir = process.chdir -process.chdir = function(d) { - cwd = null - chdir.call(process, d) -} +// Regex to split the tail part of the above into [*, dir, basename, ext] +var splitTailRe = + /^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/; -module.exports = patch +var win32 = {}; -function patch (fs) { - // (re-)implement some things that are known busted or missing. +// Function to split a filename into [root, dir, basename, ext] +function win32SplitPath(filename) { + // Separate device+slash from tail + var result = splitDeviceRe.exec(filename), + device = (result[1] || '') + (result[2] || ''), + tail = result[3] || ''; + // Split the tail into dir, basename and extension + var result2 = splitTailRe.exec(tail), + dir = result2[1], + basename = result2[2], + ext = result2[3]; + return [device, dir, basename, ext]; +} - // lchmod, broken prior to 0.6.2 - // back-port the fix here. - if (constants.hasOwnProperty('O_SYMLINK') && - process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { - patchLchmod(fs) +win32.parse = function(pathString) { + if (typeof pathString !== 'string') { + throw new TypeError( + "Parameter 'pathString' must be a string, not " + typeof pathString + ); } - - // lutimes implementation, or no-op - if (!fs.lutimes) { - patchLutimes(fs) + var allParts = win32SplitPath(pathString); + if (!allParts || allParts.length !== 4) { + throw new TypeError("Invalid path '" + pathString + "'"); } + return { + root: allParts[0], + dir: allParts[0] + allParts[1].slice(0, -1), + base: allParts[2], + ext: allParts[3], + name: allParts[2].slice(0, allParts[2].length - allParts[3].length) + }; +}; - // https://github.com/isaacs/node-graceful-fs/issues/4 - // Chown should not fail on einval or eperm if non-root. - // It should not fail on enosys ever, as this just indicates - // that a fs doesn't support the intended operation. - - fs.chown = chownFix(fs.chown) - fs.fchown = chownFix(fs.fchown) - fs.lchown = chownFix(fs.lchown) - fs.chmod = chmodFix(fs.chmod) - fs.fchmod = chmodFix(fs.fchmod) - fs.lchmod = chmodFix(fs.lchmod) - fs.chownSync = chownFixSync(fs.chownSync) - fs.fchownSync = chownFixSync(fs.fchownSync) - fs.lchownSync = chownFixSync(fs.lchownSync) +// Split a filename into [root, dir, basename, ext], unix version +// 'root' is just a slash, or nothing. +var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +var posix = {}; - fs.chmodSync = chmodFixSync(fs.chmodSync) - fs.fchmodSync = chmodFixSync(fs.fchmodSync) - fs.lchmodSync = chmodFixSync(fs.lchmodSync) - fs.stat = statFix(fs.stat) - fs.fstat = statFix(fs.fstat) - fs.lstat = statFix(fs.lstat) +function posixSplitPath(filename) { + return splitPathRe.exec(filename).slice(1); +} - fs.statSync = statFixSync(fs.statSync) - fs.fstatSync = statFixSync(fs.fstatSync) - fs.lstatSync = statFixSync(fs.lstatSync) - // if lchmod/lchown do not exist, then make them no-ops - if (!fs.lchmod) { - fs.lchmod = function (path, mode, cb) { - if (cb) process.nextTick(cb) - } - fs.lchmodSync = function () {} +posix.parse = function(pathString) { + if (typeof pathString !== 'string') { + throw new TypeError( + "Parameter 'pathString' must be a string, not " + typeof pathString + ); } - if (!fs.lchown) { - fs.lchown = function (path, uid, gid, cb) { - if (cb) process.nextTick(cb) - } - fs.lchownSync = function () {} + var allParts = posixSplitPath(pathString); + if (!allParts || allParts.length !== 4) { + throw new TypeError("Invalid path '" + pathString + "'"); } + allParts[1] = allParts[1] || ''; + allParts[2] = allParts[2] || ''; + allParts[3] = allParts[3] || ''; - // on Windows, A/V software can lock the directory, causing this - // to fail with an EACCES or EPERM if the directory contains newly - // created files. Try again on failure, for up to 60 seconds. + return { + root: allParts[0], + dir: allParts[0] + allParts[1].slice(0, -1), + base: allParts[2], + ext: allParts[3], + name: allParts[2].slice(0, allParts[2].length - allParts[3].length) + }; +}; - // Set the timeout this long because some Windows Anti-Virus, such as Parity - // bit9, may lock files for up to a minute, causing npm package install - // failures. Also, take care to yield the scheduler. Windows scheduling gives - // CPU to a busy looping process, which can cause the program causing the lock - // contention to be starved of CPU by node, so the contention doesn't resolve. - if (platform === "win32") { - fs.rename = (function (fs$rename) { return function (from, to, cb) { - var start = Date.now() - var backoff = 0; - fs$rename(from, to, function CB (er) { - if (er - && (er.code === "EACCES" || er.code === "EPERM") - && Date.now() - start < 60000) { - setTimeout(function() { - fs.stat(to, function (stater, st) { - if (stater && stater.code === "ENOENT") - fs$rename(from, to, CB); - else - cb(er) - }) - }, backoff) - if (backoff < 100) - backoff += 10; - return; - } - if (cb) cb(er) - }) - }})(fs.rename) - } - // if read() returns EAGAIN, then just try it again. - fs.read = (function (fs$read) { return function (fd, buffer, offset, length, position, callback_) { - var callback - if (callback_ && typeof callback_ === 'function') { - var eagCounter = 0 - callback = function (er, _, __) { - if (er && er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - return fs$read.call(fs, fd, buffer, offset, length, position, callback) - } - callback_.apply(this, arguments) - } - } - return fs$read.call(fs, fd, buffer, offset, length, position, callback) - }})(fs.read) +if (isWindows) + module.exports = win32.parse; +else /* posix */ + module.exports = posix.parse; - fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { - var eagCounter = 0 - while (true) { - try { - return fs$readSync.call(fs, fd, buffer, offset, length, position) - } catch (er) { - if (er.code === 'EAGAIN' && eagCounter < 10) { - eagCounter ++ - continue - } - throw er - } - } - }})(fs.readSync) +module.exports.posix = posix.parse; +module.exports.win32 = win32.parse; - function patchLchmod (fs) { - fs.lchmod = function (path, mode, callback) { - fs.open( path - , constants.O_WRONLY | constants.O_SYMLINK - , mode - , function (err, fd) { - if (err) { - if (callback) callback(err) - return - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function (err) { - fs.close(fd, function(err2) { - if (callback) callback(err || err2) - }) - }) - }) - } - fs.lchmodSync = function (path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) +/***/ }), +/* 539 */ +/***/ (function(module, exports) { - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var threw = true - var ret - try { - ret = fs.fchmodSync(fd, mode) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) - } - } - return ret - } - } +module.exports = function (x, opts) { + /** + * This file is purposefully a passthrough. It's expected that third-party + * environments will override it at runtime in order to inject special logic + * into `resolve` (by manipulating the options). One such example is the PnP + * code path in Yarn. + */ - function patchLutimes (fs) { - if (constants.hasOwnProperty("O_SYMLINK")) { - fs.lutimes = function (path, at, mt, cb) { - fs.open(path, constants.O_SYMLINK, function (er, fd) { - if (er) { - if (cb) cb(er) - return - } - fs.futimes(fd, at, mt, function (er) { - fs.close(fd, function (er2) { - if (cb) cb(er || er2) - }) - }) - }) - } + return opts || {}; +}; - fs.lutimesSync = function (path, at, mt) { - var fd = fs.openSync(path, constants.O_SYMLINK) - var ret - var threw = true - try { - ret = fs.futimesSync(fd, at, mt) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) - } - } - return ret - } - } else { - fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } - fs.lutimesSync = function () {} - } - } +/***/ }), +/* 540 */ +/***/ (function(module, exports, __webpack_require__) { - function chmodFix (orig) { - if (!orig) return orig - return function (target, mode, cb) { - return orig.call(fs, target, mode, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) +var core = __webpack_require__(533); +var fs = __webpack_require__(349); +var path = __webpack_require__(4); +var caller = __webpack_require__(536); +var nodeModulesPaths = __webpack_require__(537); +var normalizeOptions = __webpack_require__(539); + +var defaultIsFile = function isFile(file) { + try { + var stat = fs.statSync(file); + } catch (e) { + if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false; + throw e; } - } + return stat.isFile() || stat.isFIFO(); +}; - function chmodFixSync (orig) { - if (!orig) return orig - return function (target, mode) { - try { - return orig.call(fs, target, mode) - } catch (er) { - if (!chownErOk(er)) throw er - } +module.exports = function (x, options) { + if (typeof x !== 'string') { + throw new TypeError('Path must be a string.'); } - } + var opts = normalizeOptions(x, options); + var isFile = opts.isFile || defaultIsFile; + var readFileSync = opts.readFileSync || fs.readFileSync; - function chownFix (orig) { - if (!orig) return orig - return function (target, uid, gid, cb) { - return orig.call(fs, target, uid, gid, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) + var extensions = opts.extensions || ['.js']; + var basedir = opts.basedir || path.dirname(caller()); + var parent = opts.filename || basedir; + + opts.paths = opts.paths || []; + + // ensure that `basedir` is an absolute path at this point, resolving against the process' current working directory + var absoluteStart = path.resolve(basedir); + + if (opts.preserveSymlinks === false) { + try { + absoluteStart = fs.realpathSync(absoluteStart); + } catch (realPathErr) { + if (realPathErr.code !== 'ENOENT') { + throw realPathErr; + } + } } - } - function chownFixSync (orig) { - if (!orig) return orig - return function (target, uid, gid) { - try { - return orig.call(fs, target, uid, gid) - } catch (er) { - if (!chownErOk(er)) throw er - } + if ((/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/).test(x)) { + var res = path.resolve(absoluteStart, x); + if (x === '..' || x.slice(-1) === '/') res += '/'; + var m = loadAsFileSync(res) || loadAsDirectorySync(res); + if (m) return m; + } else { + var n = loadNodeModulesSync(x, absoluteStart); + if (n) return n; } - } + if (core[x]) return x; - function statFix (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target, cb) { - return orig.call(fs, target, function (er, stats) { - if (!stats) return cb.apply(this, arguments) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - if (cb) cb.apply(this, arguments) - }) - } - } + var err = new Error("Cannot find module '" + x + "' from '" + parent + "'"); + err.code = 'MODULE_NOT_FOUND'; + throw err; - function statFixSync (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target) { - var stats = orig.call(fs, target) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - return stats; + function loadAsFileSync(x) { + var pkg = loadpkg(path.dirname(x)); + + if (pkg && pkg.dir && pkg.pkg && opts.pathFilter) { + var rfile = path.relative(pkg.dir, x); + var r = opts.pathFilter(pkg.pkg, x, rfile); + if (r) { + x = path.resolve(pkg.dir, r); // eslint-disable-line no-param-reassign + } + } + + if (isFile(x)) { + return x; + } + + for (var i = 0; i < extensions.length; i++) { + var file = x + extensions[i]; + if (isFile(file)) { + return file; + } + } } - } - // ENOSYS means that the fs doesn't support the op. Just ignore - // that, because it doesn't matter. - // - // if there's no getuid, or if getuid() is something other - // than 0, and the error is EINVAL or EPERM, then just ignore - // it. - // - // This specific case is a silent failure in cp, install, tar, - // and most other unix tools that manage permissions. - // - // When running as root, or if other types of errors are - // encountered, then it's strict. - function chownErOk (er) { - if (!er) - return true + function loadpkg(dir) { + if (dir === '' || dir === '/') return; + if (process.platform === 'win32' && (/^\w:[/\\]*$/).test(dir)) { + return; + } + if ((/[/\\]node_modules[/\\]*$/).test(dir)) return; - if (er.code === "ENOSYS") - return true + var pkgfile = path.join(dir, 'package.json'); - var nonroot = !process.getuid || process.getuid() !== 0 - if (nonroot) { - if (er.code === "EINVAL" || er.code === "EPERM") - return true - } + if (!isFile(pkgfile)) { + return loadpkg(path.dirname(dir)); + } - return false - } -} + var body = readFileSync(pkgfile); + try { + var pkg = JSON.parse(body); + } catch (jsonErr) {} -/***/ }), -/* 549 */ -/***/ (function(module, exports, __webpack_require__) { + if (pkg && opts.packageFilter) { + pkg = opts.packageFilter(pkg, dir); + } -var Stream = __webpack_require__(27).Stream + return { pkg: pkg, dir: dir }; + } -module.exports = legacy + function loadAsDirectorySync(x) { + var pkgfile = path.join(x, '/package.json'); + if (isFile(pkgfile)) { + try { + var body = readFileSync(pkgfile, 'UTF8'); + var pkg = JSON.parse(body); + } catch (e) {} -function legacy (fs) { - return { - ReadStream: ReadStream, - WriteStream: WriteStream - } + if (opts.packageFilter) { + pkg = opts.packageFilter(pkg, x); + } - function ReadStream (path, options) { - if (!(this instanceof ReadStream)) return new ReadStream(path, options); + if (pkg.main) { + if (typeof pkg.main !== 'string') { + var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string'); + mainError.code = 'INVALID_PACKAGE_MAIN'; + throw mainError; + } + if (pkg.main === '.' || pkg.main === './') { + pkg.main = 'index'; + } + try { + var m = loadAsFileSync(path.resolve(x, pkg.main)); + if (m) return m; + var n = loadAsDirectorySync(path.resolve(x, pkg.main)); + if (n) return n; + } catch (e) {} + } + } - Stream.call(this); + return loadAsFileSync(path.join(x, '/index')); + } - var self = this; + function loadNodeModulesSync(x, start) { + var dirs = nodeModulesPaths(start, opts, x); + for (var i = 0; i < dirs.length; i++) { + var dir = dirs[i]; + var m = loadAsFileSync(path.join(dir, '/', x)); + if (m) return m; + var n = loadAsDirectorySync(path.join(dir, '/', x)); + if (n) return n; + } + } +}; - this.path = path; - this.fd = null; - this.readable = true; - this.paused = false; - this.flags = 'r'; - this.mode = 438; /*=0666*/ - this.bufferSize = 64 * 1024; +/***/ }), +/* 541 */ +/***/ (function(module, exports) { - options = options || {}; +module.exports = extractDescription - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; - } +// Extracts description from contents of a readme file in markdown format +function extractDescription (d) { + if (!d) return; + if (d === "ERROR: No README data found!") return; + // the first block of text before the first heading + // that isn't the first line heading + d = d.trim().split('\n') + for (var s = 0; d[s] && d[s].trim().match(/^(#|$)/); s ++); + var l = d.length + for (var e = s + 1; e < l && d[e].trim(); e ++); + return d.slice(s, e).join(' ').trim() +} - if (this.encoding) this.setEncoding(this.encoding); - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.end === undefined) { - this.end = Infinity; - } else if ('number' !== typeof this.end) { - throw TypeError('end must be a Number'); - } +/***/ }), +/* 542 */ +/***/ (function(module) { - if (this.start > this.end) { - throw new Error('start must be <= end'); - } +module.exports = JSON.parse("{\"topLevel\":{\"dependancies\":\"dependencies\",\"dependecies\":\"dependencies\",\"depdenencies\":\"dependencies\",\"devEependencies\":\"devDependencies\",\"depends\":\"dependencies\",\"dev-dependencies\":\"devDependencies\",\"devDependences\":\"devDependencies\",\"devDepenencies\":\"devDependencies\",\"devdependencies\":\"devDependencies\",\"repostitory\":\"repository\",\"repo\":\"repository\",\"prefereGlobal\":\"preferGlobal\",\"hompage\":\"homepage\",\"hampage\":\"homepage\",\"autohr\":\"author\",\"autor\":\"author\",\"contributers\":\"contributors\",\"publicationConfig\":\"publishConfig\",\"script\":\"scripts\"},\"bugs\":{\"web\":\"url\",\"name\":\"url\"},\"script\":{\"server\":\"start\",\"tests\":\"test\"}}"); - this.pos = this.start; - } +/***/ }), +/* 543 */ +/***/ (function(module, exports, __webpack_require__) { - if (this.fd !== null) { - process.nextTick(function() { - self._read(); - }); - return; - } +var util = __webpack_require__(397) +var messages = __webpack_require__(544) - fs.open(this.path, this.flags, this.mode, function (err, fd) { - if (err) { - self.emit('error', err); - self.readable = false; - return; - } +module.exports = function() { + var args = Array.prototype.slice.call(arguments, 0) + var warningName = args.shift() + if (warningName == "typo") { + return makeTypoWarning.apply(null,args) + } + else { + var msgTemplate = messages[warningName] ? messages[warningName] : warningName + ": '%s'" + args.unshift(msgTemplate) + return util.format.apply(null, args) + } +} - self.fd = fd; - self.emit('open', fd); - self._read(); - }) +function makeTypoWarning (providedName, probableName, field) { + if (field) { + providedName = field + "['" + providedName + "']" + probableName = field + "['" + probableName + "']" } + return util.format(messages.typo, providedName, probableName) +} - function WriteStream (path, options) { - if (!(this instanceof WriteStream)) return new WriteStream(path, options); - Stream.call(this); +/***/ }), +/* 544 */ +/***/ (function(module) { - this.path = path; - this.fd = null; - this.writable = true; +module.exports = JSON.parse("{\"repositories\":\"'repositories' (plural) Not supported. Please pick one as the 'repository' field\",\"missingRepository\":\"No repository field.\",\"brokenGitUrl\":\"Probably broken git url: %s\",\"nonObjectScripts\":\"scripts must be an object\",\"nonStringScript\":\"script values must be string commands\",\"nonArrayFiles\":\"Invalid 'files' member\",\"invalidFilename\":\"Invalid filename in 'files' list: %s\",\"nonArrayBundleDependencies\":\"Invalid 'bundleDependencies' list. Must be array of package names\",\"nonStringBundleDependency\":\"Invalid bundleDependencies member: %s\",\"nonDependencyBundleDependency\":\"Non-dependency in bundleDependencies: %s\",\"nonObjectDependencies\":\"%s field must be an object\",\"nonStringDependency\":\"Invalid dependency: %s %s\",\"deprecatedArrayDependencies\":\"specifying %s as array is deprecated\",\"deprecatedModules\":\"modules field is deprecated\",\"nonArrayKeywords\":\"keywords should be an array of strings\",\"nonStringKeyword\":\"keywords should be an array of strings\",\"conflictingName\":\"%s is also the name of a node core module.\",\"nonStringDescription\":\"'description' field should be a string\",\"missingDescription\":\"No description\",\"missingReadme\":\"No README data\",\"missingLicense\":\"No license field.\",\"nonEmailUrlBugsString\":\"Bug string field must be url, email, or {email,url}\",\"nonUrlBugsUrlField\":\"bugs.url field must be a string url. Deleted.\",\"nonEmailBugsEmailField\":\"bugs.email field must be a string email. Deleted.\",\"emptyNormalizedBugs\":\"Normalized value of bugs field is an empty object. Deleted.\",\"nonUrlHomepage\":\"homepage field must be a string url. Deleted.\",\"invalidLicense\":\"license should be a valid SPDX license expression\",\"typo\":\"%s should probably be %s.\"}"); - this.flags = 'w'; - this.encoding = 'binary'; - this.mode = 438; /*=0666*/ - this.bytesWritten = 0; +/***/ }), +/* 545 */ +/***/ (function(module, exports, __webpack_require__) { - options = options || {}; +"use strict"; - // Mixin options into this - var keys = Object.keys(options); - for (var index = 0, length = keys.length; index < length; index++) { - var key = keys[index]; - this[key] = options[key]; - } +const path = __webpack_require__(4); +const writeJsonFile = __webpack_require__(546); +const sortKeys = __webpack_require__(558); - if (this.start !== undefined) { - if ('number' !== typeof this.start) { - throw TypeError('start must be a Number'); - } - if (this.start < 0) { - throw new Error('start must be >= zero'); - } +const dependencyKeys = new Set([ + 'dependencies', + 'devDependencies', + 'optionalDependencies', + 'peerDependencies' +]); - this.pos = this.start; - } +function normalize(packageJson) { + const result = {}; - this.busy = false; - this._queue = []; + for (const key of Object.keys(packageJson)) { + if (!dependencyKeys.has(key)) { + result[key] = packageJson[key]; + } else if (Object.keys(packageJson[key]).length !== 0) { + result[key] = sortKeys(packageJson[key]); + } + } - if (this.fd === null) { - this._open = fs.open; - this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); - this.flush(); - } - } + return result; } +module.exports = async (filePath, data, options) => { + if (typeof filePath !== 'string') { + options = data; + data = filePath; + filePath = '.'; + } -/***/ }), -/* 550 */ -/***/ (function(module, exports, __webpack_require__) { + options = { + normalize: true, + ...options, + detectIndent: true + }; -"use strict"; + filePath = path.basename(filePath) === 'package.json' ? filePath : path.join(filePath, 'package.json'); + data = options.normalize ? normalize(data) : data; -module.exports = clone + return writeJsonFile(filePath, data, options); +}; -function clone (obj) { - if (obj === null || typeof obj !== 'object') - return obj +module.exports.sync = (filePath, data, options) => { + if (typeof filePath !== 'string') { + options = data; + data = filePath; + filePath = '.'; + } - if (obj instanceof Object) - var copy = { __proto__: obj.__proto__ } - else - var copy = Object.create(null) + options = { + normalize: true, + ...options, + detectIndent: true + }; - Object.getOwnPropertyNames(obj).forEach(function (key) { - Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) - }) + filePath = path.basename(filePath) === 'package.json' ? filePath : path.join(filePath, 'package.json'); - return copy -} + data = options.normalize ? normalize(data) : data; + + writeJsonFile.sync(filePath, data, options); +}; /***/ }), -/* 551 */ +/* 546 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = writeFile -module.exports.sync = writeFileSync -module.exports._getTmpname = getTmpname // for testing -module.exports._cleanupOnExit = cleanupOnExit - -var fs = __webpack_require__(552) -var MurmurHash3 = __webpack_require__(556) -var onExit = __webpack_require__(397) -var path = __webpack_require__(16) -var activeFiles = {} - -// if we run inside of a worker_thread, `process.pid` is not unique -/* istanbul ignore next */ -var threadId = (function getId () { - try { - var workerThreads = __webpack_require__(557) +const path = __webpack_require__(4); +const fs = __webpack_require__(547); +const writeFileAtomic = __webpack_require__(551); +const sortKeys = __webpack_require__(558); +const makeDir = __webpack_require__(560); +const pify = __webpack_require__(561); +const detectIndent = __webpack_require__(562); - /// if we are in main thread, this is set to `0` - return workerThreads.threadId - } catch (e) { - // worker_threads are not available, fallback to 0 - return 0 - } -})() +const init = (fn, filePath, data, options) => { + if (!filePath) { + throw new TypeError('Expected a filepath'); + } -var invocations = 0 -function getTmpname (filename) { - return filename + '.' + - MurmurHash3(__filename) - .hash(String(process.pid)) - .hash(String(threadId)) - .hash(String(++invocations)) - .result() -} + if (data === undefined) { + throw new TypeError('Expected data to stringify'); + } -function cleanupOnExit (tmpfile) { - return function () { - try { - fs.unlinkSync(typeof tmpfile === 'function' ? tmpfile() : tmpfile) - } catch (_) {} - } -} + options = Object.assign({ + indent: '\t', + sortKeys: false + }, options); -function writeFile (filename, data, options, callback) { - if (options) { - if (options instanceof Function) { - callback = options - options = {} - } else if (typeof options === 'string') { - options = { encoding: options } - } - } else { - options = {} - } + if (options.sortKeys) { + data = sortKeys(data, { + deep: true, + compare: typeof options.sortKeys === 'function' ? options.sortKeys : undefined + }); + } - var Promise = options.Promise || global.Promise - var truename - var fd - var tmpfile - /* istanbul ignore next -- The closure only gets called when onExit triggers */ - var removeOnExitHandler = onExit(cleanupOnExit(() => tmpfile)) - var absoluteName = path.resolve(filename) + return fn(filePath, data, options); +}; - new Promise(function serializeSameFile (resolve) { - // make a queue if it doesn't already exist - if (!activeFiles[absoluteName]) activeFiles[absoluteName] = [] +const readFile = filePath => pify(fs.readFile)(filePath, 'utf8').catch(() => {}); - activeFiles[absoluteName].push(resolve) // add this job to the queue - if (activeFiles[absoluteName].length === 1) resolve() // kick off the first one - }).then(function getRealPath () { - return new Promise(function (resolve) { - fs.realpath(filename, function (_, realname) { - truename = realname || filename - tmpfile = getTmpname(truename) - resolve() - }) - }) - }).then(function stat () { - return new Promise(function stat (resolve) { - if (options.mode && options.chown) resolve() - else { - // Either mode or chown is not explicitly set - // Default behavior is to copy it from original file - fs.stat(truename, function (err, stats) { - if (err || !stats) resolve() - else { - options = Object.assign({}, options) +const main = (filePath, data, options) => { + return (options.detectIndent ? readFile(filePath) : Promise.resolve()) + .then(string => { + const indent = string ? detectIndent(string).indent : options.indent; + const json = JSON.stringify(data, options.replacer, indent); - if (options.mode == null) { - options.mode = stats.mode - } - if (options.chown == null && process.getuid) { - options.chown = { uid: stats.uid, gid: stats.gid } - } - resolve() - } - }) - } - }) - }).then(function thenWriteFile () { - return new Promise(function (resolve, reject) { - fs.open(tmpfile, 'w', options.mode, function (err, _fd) { - fd = _fd - if (err) reject(err) - else resolve() - }) - }) - }).then(function write () { - return new Promise(function (resolve, reject) { - if (Buffer.isBuffer(data)) { - fs.write(fd, data, 0, data.length, 0, function (err) { - if (err) reject(err) - else resolve() - }) - } else if (data != null) { - fs.write(fd, String(data), 0, String(options.encoding || 'utf8'), function (err) { - if (err) reject(err) - else resolve() - }) - } else resolve() - }) - }).then(function syncAndClose () { - return new Promise(function (resolve, reject) { - if (options.fsync !== false) { - fs.fsync(fd, function (err) { - if (err) fs.close(fd, () => reject(err)) - else fs.close(fd, resolve) - }) - } else { - fs.close(fd, resolve) - } - }) - }).then(function chown () { - fd = null - if (options.chown) { - return new Promise(function (resolve, reject) { - fs.chown(tmpfile, options.chown.uid, options.chown.gid, function (err) { - if (err) reject(err) - else resolve() - }) - }) - } - }).then(function chmod () { - if (options.mode) { - return new Promise(function (resolve, reject) { - fs.chmod(tmpfile, options.mode, function (err) { - if (err) reject(err) - else resolve() - }) - }) - } - }).then(function rename () { - return new Promise(function (resolve, reject) { - fs.rename(tmpfile, truename, function (err) { - if (err) reject(err) - else resolve() - }) - }) - }).then(function success () { - removeOnExitHandler() - callback() - }, function fail (err) { - return new Promise(resolve => { - return fd ? fs.close(fd, resolve) : resolve() - }).then(() => { - removeOnExitHandler() - fs.unlink(tmpfile, function () { - callback(err) - }) - }) - }).then(function checkQueue () { - activeFiles[absoluteName].shift() // remove the element added by serializeSameFile - if (activeFiles[absoluteName].length > 0) { - activeFiles[absoluteName][0]() // start next job if one is pending - } else delete activeFiles[absoluteName] - }) -} + return pify(writeFileAtomic)(filePath, `${json}\n`, {mode: options.mode}); + }); +}; -function writeFileSync (filename, data, options) { - if (typeof options === 'string') options = { encoding: options } - else if (!options) options = {} - try { - filename = fs.realpathSync(filename) - } catch (ex) { - // it's ok, it'll happen on a not yet existing file - } - var tmpfile = getTmpname(filename) +const mainSync = (filePath, data, options) => { + let {indent} = options; - if (!options.mode || !options.chown) { - // Either mode or chown is not explicitly set - // Default behavior is to copy it from original file - try { - var stats = fs.statSync(filename) - options = Object.assign({}, options) - if (!options.mode) { - options.mode = stats.mode - } - if (!options.chown && process.getuid) { - options.chown = { uid: stats.uid, gid: stats.gid } - } - } catch (ex) { - // ignore stat errors - } - } + if (options.detectIndent) { + try { + const file = fs.readFileSync(filePath, 'utf8'); + indent = detectIndent(file).indent; + } catch (error) { + if (error.code !== 'ENOENT') { + throw error; + } + } + } - var fd - var cleanup = cleanupOnExit(tmpfile) - var removeOnExitHandler = onExit(cleanup) + const json = JSON.stringify(data, options.replacer, indent); - try { - fd = fs.openSync(tmpfile, 'w', options.mode) - if (Buffer.isBuffer(data)) { - fs.writeSync(fd, data, 0, data.length, 0) - } else if (data != null) { - fs.writeSync(fd, String(data), 0, String(options.encoding || 'utf8')) - } - if (options.fsync !== false) { - fs.fsyncSync(fd) - } - fs.closeSync(fd) - if (options.chown) fs.chownSync(tmpfile, options.chown.uid, options.chown.gid) - if (options.mode) fs.chmodSync(tmpfile, options.mode) - fs.renameSync(tmpfile, filename) - removeOnExitHandler() - } catch (err) { - if (fd) { - try { - fs.closeSync(fd) - } catch (ex) { - // ignore close errors at this stage, error may have closed fd already. - } - } - removeOnExitHandler() - cleanup() - throw err - } -} + return writeFileAtomic.sync(filePath, `${json}\n`, {mode: options.mode}); +}; + +const writeJsonFile = (filePath, data, options) => { + return makeDir(path.dirname(filePath), {fs}) + .then(() => init(main, filePath, data, options)); +}; + +module.exports = writeJsonFile; +// TODO: Remove this for the next major release +module.exports.default = writeJsonFile; +module.exports.sync = (filePath, data, options) => { + makeDir.sync(path.dirname(filePath), {fs}); + init(mainSync, filePath, data, options); +}; /***/ }), -/* 552 */ +/* 547 */ /***/ (function(module, exports, __webpack_require__) { -var fs = __webpack_require__(23) -var polyfills = __webpack_require__(553) -var legacy = __webpack_require__(555) +var fs = __webpack_require__(349) +var polyfills = __webpack_require__(548) +var legacy = __webpack_require__(549) +var clone = __webpack_require__(550) + var queue = [] -var util = __webpack_require__(29) +var util = __webpack_require__(397) function noop () {} @@ -53880,21 +52895,21 @@ else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { process.on('exit', function() { debug(queue) - __webpack_require__(30).equal(queue.length, 0) + __webpack_require__(371).equal(queue.length, 0) }) } -module.exports = patch(__webpack_require__(554)) -if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH) { - module.exports = patch(fs) +module.exports = patch(clone(fs)) +if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) { + module.exports = patch(fs) + fs.__patched = true; } // Always patch fs.close/closeSync, because we want to // retry() whenever a close happens *anywhere* in the program. // This is essential when multiple graceful-fs instances are // in play at the same time. -module.exports.close = -fs.close = (function (fs$close) { return function (fd, cb) { +module.exports.close = (function (fs$close) { return function (fd, cb) { return fs$close.call(fs, fd, function (err) { if (!err) retry() @@ -53904,8 +52919,7 @@ fs.close = (function (fs$close) { return function (fd, cb) { }) }})(fs.close) -module.exports.closeSync = -fs.closeSync = (function (fs$closeSync) { return function (fd) { +module.exports.closeSync = (function (fs$closeSync) { return function (fd) { // Note that graceful-fs also retries when fs.closeSync() fails. // Looks like a bug to me, although it's probably a harmless one. var rval = fs$closeSync.apply(fs, arguments) @@ -53913,6 +52927,17 @@ fs.closeSync = (function (fs$closeSync) { return function (fd) { return rval }})(fs.closeSync) +// Only patch fs once, otherwise we'll run into a memory leak if +// graceful-fs is loaded multiple times, such as in test environments that +// reset the loaded modules between tests. +// We look for the string `graceful-fs` from the comment above. This +// way we are not adding any extra properties and it will detect if older +// versions of graceful-fs are installed. +if (!/\bgraceful-fs\b/.test(fs.closeSync.toString())) { + fs.closeSync = module.exports.closeSync; + fs.close = module.exports.close; +} + function patch (fs) { // Everything that references the open() function needs to be in here polyfills(fs) @@ -54004,6 +53029,7 @@ function patch (fs) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$readdir, [args]]) + else { if (typeof cb === 'function') cb.apply(this, arguments) @@ -54023,12 +53049,16 @@ function patch (fs) { } var fs$ReadStream = fs.ReadStream - ReadStream.prototype = Object.create(fs$ReadStream.prototype) - ReadStream.prototype.open = ReadStream$open + if (fs$ReadStream) { + ReadStream.prototype = Object.create(fs$ReadStream.prototype) + ReadStream.prototype.open = ReadStream$open + } var fs$WriteStream = fs.WriteStream - WriteStream.prototype = Object.create(fs$WriteStream.prototype) - WriteStream.prototype.open = WriteStream$open + if (fs$WriteStream) { + WriteStream.prototype = Object.create(fs$WriteStream.prototype) + WriteStream.prototype.open = WriteStream$open + } fs.ReadStream = ReadStream fs.WriteStream = WriteStream @@ -54123,11 +53153,10 @@ function retry () { /***/ }), -/* 553 */ +/* 548 */ /***/ (function(module, exports, __webpack_require__) { -var fs = __webpack_require__(554) -var constants = __webpack_require__(25) +var constants = __webpack_require__(411) var origCwd = process.cwd var cwd = null @@ -54273,73 +53302,36 @@ function patch (fs) { } } }})(fs.readSync) -} - -function patchLchmod (fs) { - fs.lchmod = function (path, mode, callback) { - fs.open( path - , constants.O_WRONLY | constants.O_SYMLINK - , mode - , function (err, fd) { - if (err) { - if (callback) callback(err) - return - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function (err) { - fs.close(fd, function(err2) { - if (callback) callback(err || err2) - }) - }) - }) - } - - fs.lchmodSync = function (path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var threw = true - var ret - try { - ret = fs.fchmodSync(fd, mode) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) - } - } - return ret - } -} -function patchLutimes (fs) { - if (constants.hasOwnProperty("O_SYMLINK")) { - fs.lutimes = function (path, at, mt, cb) { - fs.open(path, constants.O_SYMLINK, function (er, fd) { - if (er) { - if (cb) cb(er) + function patchLchmod (fs) { + fs.lchmod = function (path, mode, callback) { + fs.open( path + , constants.O_WRONLY | constants.O_SYMLINK + , mode + , function (err, fd) { + if (err) { + if (callback) callback(err) return } - fs.futimes(fd, at, mt, function (er) { - fs.close(fd, function (er2) { - if (cb) cb(er || er2) + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + fs.fchmod(fd, mode, function (err) { + fs.close(fd, function(err2) { + if (callback) callback(err || err2) }) }) }) } - fs.lutimesSync = function (path, at, mt) { - var fd = fs.openSync(path, constants.O_SYMLINK) - var ret + fs.lchmodSync = function (path, mode) { + var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) + + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. var threw = true + var ret try { - ret = fs.futimesSync(fd, at, mt) + ret = fs.fchmodSync(fd, mode) threw = false } finally { if (threw) { @@ -54352,145 +53344,154 @@ function patchLutimes (fs) { } return ret } - - } else { - fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } - fs.lutimesSync = function () {} } -} -function chmodFix (orig) { - if (!orig) return orig - return function (target, mode, cb) { - return orig.call(fs, target, mode, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) - } -} + function patchLutimes (fs) { + if (constants.hasOwnProperty("O_SYMLINK")) { + fs.lutimes = function (path, at, mt, cb) { + fs.open(path, constants.O_SYMLINK, function (er, fd) { + if (er) { + if (cb) cb(er) + return + } + fs.futimes(fd, at, mt, function (er) { + fs.close(fd, function (er2) { + if (cb) cb(er || er2) + }) + }) + }) + } -function chmodFixSync (orig) { - if (!orig) return orig - return function (target, mode) { - try { - return orig.call(fs, target, mode) - } catch (er) { - if (!chownErOk(er)) throw er + fs.lutimesSync = function (path, at, mt) { + var fd = fs.openSync(path, constants.O_SYMLINK) + var ret + var threw = true + try { + ret = fs.futimesSync(fd, at, mt) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } + } + return ret + } + + } else { + fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } + fs.lutimesSync = function () {} } } -} - -function chownFix (orig) { - if (!orig) return orig - return function (target, uid, gid, cb) { - return orig.call(fs, target, uid, gid, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) + function chmodFix (orig) { + if (!orig) return orig + return function (target, mode, cb) { + return orig.call(fs, target, mode, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } } -} -function chownFixSync (orig) { - if (!orig) return orig - return function (target, uid, gid) { - try { - return orig.call(fs, target, uid, gid) - } catch (er) { - if (!chownErOk(er)) throw er + function chmodFixSync (orig) { + if (!orig) return orig + return function (target, mode) { + try { + return orig.call(fs, target, mode) + } catch (er) { + if (!chownErOk(er)) throw er + } } } -} -function statFix (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target, cb) { - return orig.call(fs, target, function (er, stats) { - if (!stats) return cb.apply(this, arguments) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - if (cb) cb.apply(this, arguments) - }) + function chownFix (orig) { + if (!orig) return orig + return function (target, uid, gid, cb) { + return orig.call(fs, target, uid, gid, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } } -} -function statFixSync (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target) { - var stats = orig.call(fs, target) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - return stats; + function chownFixSync (orig) { + if (!orig) return orig + return function (target, uid, gid) { + try { + return orig.call(fs, target, uid, gid) + } catch (er) { + if (!chownErOk(er)) throw er + } + } } -} - -// ENOSYS means that the fs doesn't support the op. Just ignore -// that, because it doesn't matter. -// -// if there's no getuid, or if getuid() is something other -// than 0, and the error is EINVAL or EPERM, then just ignore -// it. -// -// This specific case is a silent failure in cp, install, tar, -// and most other unix tools that manage permissions. -// -// When running as root, or if other types of errors are -// encountered, then it's strict. -function chownErOk (er) { - if (!er) - return true - if (er.code === "ENOSYS") - return true - var nonroot = !process.getuid || process.getuid() !== 0 - if (nonroot) { - if (er.code === "EINVAL" || er.code === "EPERM") - return true + function statFix (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target, cb) { + return orig.call(fs, target, function (er, stats) { + if (!stats) return cb.apply(this, arguments) + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + if (cb) cb.apply(this, arguments) + }) + } } - return false -} - - -/***/ }), -/* 554 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var fs = __webpack_require__(23) - -module.exports = clone(fs) + function statFixSync (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target) { + var stats = orig.call(fs, target) + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + return stats; + } + } -function clone (obj) { - if (obj === null || typeof obj !== 'object') - return obj + // ENOSYS means that the fs doesn't support the op. Just ignore + // that, because it doesn't matter. + // + // if there's no getuid, or if getuid() is something other + // than 0, and the error is EINVAL or EPERM, then just ignore + // it. + // + // This specific case is a silent failure in cp, install, tar, + // and most other unix tools that manage permissions. + // + // When running as root, or if other types of errors are + // encountered, then it's strict. + function chownErOk (er) { + if (!er) + return true - if (obj instanceof Object) - var copy = { __proto__: obj.__proto__ } - else - var copy = Object.create(null) + if (er.code === "ENOSYS") + return true - Object.getOwnPropertyNames(obj).forEach(function (key) { - Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) - }) + var nonroot = !process.getuid || process.getuid() !== 0 + if (nonroot) { + if (er.code === "EINVAL" || er.code === "EPERM") + return true + } - return copy + return false + } } /***/ }), -/* 555 */ +/* 549 */ /***/ (function(module, exports, __webpack_require__) { -var Stream = __webpack_require__(27).Stream +var Stream = __webpack_require__(382).Stream module.exports = legacy @@ -54610,1452 +53611,1793 @@ function legacy (fs) { } -/***/ }), -/* 556 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * @preserve - * JS Implementation of incremental MurmurHash3 (r150) (as of May 10, 2013) - * - * @author Jens Taylor - * @see http://github.com/homebrewing/brauhaus-diff - * @author Gary Court - * @see http://github.com/garycourt/murmurhash-js - * @author Austin Appleby - * @see http://sites.google.com/site/murmurhash/ - */ -(function(){ - var cache; - - // Call this function without `new` to use the cached object (good for - // single-threaded environments), or with `new` to create a new object. - // - // @param {string} key A UTF-16 or ASCII string - // @param {number} seed An optional positive integer - // @return {object} A MurmurHash3 object for incremental hashing - function MurmurHash3(key, seed) { - var m = this instanceof MurmurHash3 ? this : cache; - m.reset(seed) - if (typeof key === 'string' && key.length > 0) { - m.hash(key); - } - - if (m !== this) { - return m; - } - }; - - // Incrementally add a string to this hash - // - // @param {string} key A UTF-16 or ASCII string - // @return {object} this - MurmurHash3.prototype.hash = function(key) { - var h1, k1, i, top, len; - - len = key.length; - this.len += len; - - k1 = this.k1; - i = 0; - switch (this.rem) { - case 0: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) : 0; - case 1: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 8 : 0; - case 2: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 16 : 0; - case 3: - k1 ^= len > i ? (key.charCodeAt(i) & 0xff) << 24 : 0; - k1 ^= len > i ? (key.charCodeAt(i++) & 0xff00) >> 8 : 0; - } - - this.rem = (len + this.rem) & 3; // & 3 is same as % 4 - len -= this.rem; - if (len > 0) { - h1 = this.h1; - while (1) { - k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff; - k1 = (k1 << 15) | (k1 >>> 17); - k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff; - - h1 ^= k1; - h1 = (h1 << 13) | (h1 >>> 19); - h1 = (h1 * 5 + 0xe6546b64) & 0xffffffff; - - if (i >= len) { - break; - } - - k1 = ((key.charCodeAt(i++) & 0xffff)) ^ - ((key.charCodeAt(i++) & 0xffff) << 8) ^ - ((key.charCodeAt(i++) & 0xffff) << 16); - top = key.charCodeAt(i++); - k1 ^= ((top & 0xff) << 24) ^ - ((top & 0xff00) >> 8); - } - - k1 = 0; - switch (this.rem) { - case 3: k1 ^= (key.charCodeAt(i + 2) & 0xffff) << 16; - case 2: k1 ^= (key.charCodeAt(i + 1) & 0xffff) << 8; - case 1: k1 ^= (key.charCodeAt(i) & 0xffff); - } - - this.h1 = h1; - } - - this.k1 = k1; - return this; - }; - - // Get the result of this hash - // - // @return {number} The 32-bit hash - MurmurHash3.prototype.result = function() { - var k1, h1; - - k1 = this.k1; - h1 = this.h1; - - if (k1 > 0) { - k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff; - k1 = (k1 << 15) | (k1 >>> 17); - k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff; - h1 ^= k1; - } - - h1 ^= this.len; +/***/ }), +/* 550 */ +/***/ (function(module, exports, __webpack_require__) { - h1 ^= h1 >>> 16; - h1 = (h1 * 0xca6b + (h1 & 0xffff) * 0x85eb0000) & 0xffffffff; - h1 ^= h1 >>> 13; - h1 = (h1 * 0xae35 + (h1 & 0xffff) * 0xc2b20000) & 0xffffffff; - h1 ^= h1 >>> 16; +"use strict"; - return h1 >>> 0; - }; - // Reset the hash object for reuse - // - // @param {number} seed An optional positive integer - MurmurHash3.prototype.reset = function(seed) { - this.h1 = typeof seed === 'number' ? seed : 0; - this.rem = this.k1 = this.len = 0; - return this; - }; +module.exports = clone - // A cached object to use. This can be safely used if you're in a single- - // threaded environment, otherwise you need to create new hashes to use. - cache = new MurmurHash3(); +function clone (obj) { + if (obj === null || typeof obj !== 'object') + return obj - if (true) { - module.exports = MurmurHash3; - } else {} -}()); + if (obj instanceof Object) + var copy = { __proto__: obj.__proto__ } + else + var copy = Object.create(null) + Object.getOwnPropertyNames(obj).forEach(function (key) { + Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) + }) -/***/ }), -/* 557 */ -/***/ (function(module, exports) { + return copy +} -module.exports = require(undefined); /***/ }), -/* 558 */ +/* 551 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const isPlainObj = __webpack_require__(559); - -module.exports = (obj, opts) => { - if (!isPlainObj(obj)) { - throw new TypeError('Expected a plain object'); - } +module.exports = writeFile +module.exports.sync = writeFileSync +module.exports._getTmpname = getTmpname // for testing +module.exports._cleanupOnExit = cleanupOnExit - opts = opts || {}; +var fs = __webpack_require__(552) +var MurmurHash3 = __webpack_require__(556) +var onExit = __webpack_require__(370) +var path = __webpack_require__(4) +var activeFiles = {} - // DEPRECATED - if (typeof opts === 'function') { - throw new TypeError('Specify the compare function as an option instead'); - } +// if we run inside of a worker_thread, `process.pid` is not unique +/* istanbul ignore next */ +var threadId = (function getId () { + try { + var workerThreads = __webpack_require__(557) - const deep = opts.deep; - const seenInput = []; - const seenOutput = []; + /// if we are in main thread, this is set to `0` + return workerThreads.threadId + } catch (e) { + // worker_threads are not available, fallback to 0 + return 0 + } +})() - const sortKeys = x => { - const seenIndex = seenInput.indexOf(x); +var invocations = 0 +function getTmpname (filename) { + return filename + '.' + + MurmurHash3(__filename) + .hash(String(process.pid)) + .hash(String(threadId)) + .hash(String(++invocations)) + .result() +} - if (seenIndex !== -1) { - return seenOutput[seenIndex]; - } +function cleanupOnExit (tmpfile) { + return function () { + try { + fs.unlinkSync(typeof tmpfile === 'function' ? tmpfile() : tmpfile) + } catch (_) {} + } +} - const ret = {}; - const keys = Object.keys(x).sort(opts.compare); +function writeFile (filename, data, options, callback) { + if (options) { + if (options instanceof Function) { + callback = options + options = {} + } else if (typeof options === 'string') { + options = { encoding: options } + } + } else { + options = {} + } - seenInput.push(x); - seenOutput.push(ret); + var Promise = options.Promise || global.Promise + var truename + var fd + var tmpfile + /* istanbul ignore next -- The closure only gets called when onExit triggers */ + var removeOnExitHandler = onExit(cleanupOnExit(() => tmpfile)) + var absoluteName = path.resolve(filename) - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; - const val = x[key]; + new Promise(function serializeSameFile (resolve) { + // make a queue if it doesn't already exist + if (!activeFiles[absoluteName]) activeFiles[absoluteName] = [] - if (deep && Array.isArray(val)) { - const retArr = []; + activeFiles[absoluteName].push(resolve) // add this job to the queue + if (activeFiles[absoluteName].length === 1) resolve() // kick off the first one + }).then(function getRealPath () { + return new Promise(function (resolve) { + fs.realpath(filename, function (_, realname) { + truename = realname || filename + tmpfile = getTmpname(truename) + resolve() + }) + }) + }).then(function stat () { + return new Promise(function stat (resolve) { + if (options.mode && options.chown) resolve() + else { + // Either mode or chown is not explicitly set + // Default behavior is to copy it from original file + fs.stat(truename, function (err, stats) { + if (err || !stats) resolve() + else { + options = Object.assign({}, options) - for (let j = 0; j < val.length; j++) { - retArr[j] = isPlainObj(val[j]) ? sortKeys(val[j]) : val[j]; - } + if (options.mode == null) { + options.mode = stats.mode + } + if (options.chown == null && process.getuid) { + options.chown = { uid: stats.uid, gid: stats.gid } + } + resolve() + } + }) + } + }) + }).then(function thenWriteFile () { + return new Promise(function (resolve, reject) { + fs.open(tmpfile, 'w', options.mode, function (err, _fd) { + fd = _fd + if (err) reject(err) + else resolve() + }) + }) + }).then(function write () { + return new Promise(function (resolve, reject) { + if (Buffer.isBuffer(data)) { + fs.write(fd, data, 0, data.length, 0, function (err) { + if (err) reject(err) + else resolve() + }) + } else if (data != null) { + fs.write(fd, String(data), 0, String(options.encoding || 'utf8'), function (err) { + if (err) reject(err) + else resolve() + }) + } else resolve() + }) + }).then(function syncAndClose () { + return new Promise(function (resolve, reject) { + if (options.fsync !== false) { + fs.fsync(fd, function (err) { + if (err) fs.close(fd, () => reject(err)) + else fs.close(fd, resolve) + }) + } else { + fs.close(fd, resolve) + } + }) + }).then(function chown () { + fd = null + if (options.chown) { + return new Promise(function (resolve, reject) { + fs.chown(tmpfile, options.chown.uid, options.chown.gid, function (err) { + if (err) reject(err) + else resolve() + }) + }) + } + }).then(function chmod () { + if (options.mode) { + return new Promise(function (resolve, reject) { + fs.chmod(tmpfile, options.mode, function (err) { + if (err) reject(err) + else resolve() + }) + }) + } + }).then(function rename () { + return new Promise(function (resolve, reject) { + fs.rename(tmpfile, truename, function (err) { + if (err) reject(err) + else resolve() + }) + }) + }).then(function success () { + removeOnExitHandler() + callback() + }, function fail (err) { + return new Promise(resolve => { + return fd ? fs.close(fd, resolve) : resolve() + }).then(() => { + removeOnExitHandler() + fs.unlink(tmpfile, function () { + callback(err) + }) + }) + }).then(function checkQueue () { + activeFiles[absoluteName].shift() // remove the element added by serializeSameFile + if (activeFiles[absoluteName].length > 0) { + activeFiles[absoluteName][0]() // start next job if one is pending + } else delete activeFiles[absoluteName] + }) +} - ret[key] = retArr; - continue; - } +function writeFileSync (filename, data, options) { + if (typeof options === 'string') options = { encoding: options } + else if (!options) options = {} + try { + filename = fs.realpathSync(filename) + } catch (ex) { + // it's ok, it'll happen on a not yet existing file + } + var tmpfile = getTmpname(filename) - ret[key] = deep && isPlainObj(val) ? sortKeys(val) : val; - } + if (!options.mode || !options.chown) { + // Either mode or chown is not explicitly set + // Default behavior is to copy it from original file + try { + var stats = fs.statSync(filename) + options = Object.assign({}, options) + if (!options.mode) { + options.mode = stats.mode + } + if (!options.chown && process.getuid) { + options.chown = { uid: stats.uid, gid: stats.gid } + } + } catch (ex) { + // ignore stat errors + } + } - return ret; - }; + var fd + var cleanup = cleanupOnExit(tmpfile) + var removeOnExitHandler = onExit(cleanup) - return sortKeys(obj); -}; + try { + fd = fs.openSync(tmpfile, 'w', options.mode) + if (Buffer.isBuffer(data)) { + fs.writeSync(fd, data, 0, data.length, 0) + } else if (data != null) { + fs.writeSync(fd, String(data), 0, String(options.encoding || 'utf8')) + } + if (options.fsync !== false) { + fs.fsyncSync(fd) + } + fs.closeSync(fd) + if (options.chown) fs.chownSync(tmpfile, options.chown.uid, options.chown.gid) + if (options.mode) fs.chmodSync(tmpfile, options.mode) + fs.renameSync(tmpfile, filename) + removeOnExitHandler() + } catch (err) { + if (fd) { + try { + fs.closeSync(fd) + } catch (ex) { + // ignore close errors at this stage, error may have closed fd already. + } + } + removeOnExitHandler() + cleanup() + throw err + } +} /***/ }), -/* 559 */ +/* 552 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var fs = __webpack_require__(349) +var polyfills = __webpack_require__(553) +var legacy = __webpack_require__(555) +var queue = [] -var toString = Object.prototype.toString; +var util = __webpack_require__(397) -module.exports = function (x) { - var prototype; - return toString.call(x) === '[object Object]' && (prototype = Object.getPrototypeOf(x), prototype === null || prototype === Object.getPrototypeOf({})); -}; +function noop () {} +var debug = noop +if (util.debuglog) + debug = util.debuglog('gfs4') +else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) + debug = function() { + var m = util.format.apply(util, arguments) + m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ') + console.error(m) + } -/***/ }), -/* 560 */ -/***/ (function(module, exports, __webpack_require__) { +if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { + process.on('exit', function() { + debug(queue) + __webpack_require__(371).equal(queue.length, 0) + }) +} -"use strict"; +module.exports = patch(__webpack_require__(554)) +if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH) { + module.exports = patch(fs) +} -const fs = __webpack_require__(23); -const path = __webpack_require__(16); -const pify = __webpack_require__(561); -const semver = __webpack_require__(523); +// Always patch fs.close/closeSync, because we want to +// retry() whenever a close happens *anywhere* in the program. +// This is essential when multiple graceful-fs instances are +// in play at the same time. +module.exports.close = +fs.close = (function (fs$close) { return function (fd, cb) { + return fs$close.call(fs, fd, function (err) { + if (!err) + retry() -const defaults = { - mode: 0o777 & (~process.umask()), - fs -}; + if (typeof cb === 'function') + cb.apply(this, arguments) + }) +}})(fs.close) -const useNativeRecursiveOption = semver.satisfies(process.version, '>=10.12.0'); +module.exports.closeSync = +fs.closeSync = (function (fs$closeSync) { return function (fd) { + // Note that graceful-fs also retries when fs.closeSync() fails. + // Looks like a bug to me, although it's probably a harmless one. + var rval = fs$closeSync.apply(fs, arguments) + retry() + return rval +}})(fs.closeSync) -// https://github.com/nodejs/node/issues/8987 -// https://github.com/libuv/libuv/pull/1088 -const checkPath = pth => { - if (process.platform === 'win32') { - const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path.parse(pth).root, '')); +function patch (fs) { + // Everything that references the open() function needs to be in here + polyfills(fs) + fs.gracefulify = patch + fs.FileReadStream = ReadStream; // Legacy name. + fs.FileWriteStream = WriteStream; // Legacy name. + fs.createReadStream = createReadStream + fs.createWriteStream = createWriteStream + var fs$readFile = fs.readFile + fs.readFile = readFile + function readFile (path, options, cb) { + if (typeof options === 'function') + cb = options, options = null - if (pathHasInvalidWinCharacters) { - const error = new Error(`Path contains invalid characters: ${pth}`); - error.code = 'EINVAL'; - throw error; - } - } -}; + return go$readFile(path, options, cb) -const permissionError = pth => { - // This replicates the exception of `fs.mkdir` with native the - // `recusive` option when run on an invalid drive under Windows. - const error = new Error(`operation not permitted, mkdir '${pth}'`); - error.code = 'EPERM'; - error.errno = -4048; - error.path = pth; - error.syscall = 'mkdir'; - return error; -}; + function go$readFile (path, options, cb) { + return fs$readFile(path, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readFile, [path, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } -const makeDir = (input, options) => Promise.resolve().then(() => { - checkPath(input); - options = Object.assign({}, defaults, options); + var fs$writeFile = fs.writeFile + fs.writeFile = writeFile + function writeFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null - // TODO: Use util.promisify when targeting Node.js 8 - const mkdir = pify(options.fs.mkdir); - const stat = pify(options.fs.stat); + return go$writeFile(path, data, options, cb) - if (useNativeRecursiveOption && options.fs.mkdir === fs.mkdir) { - const pth = path.resolve(input); + function go$writeFile (path, data, options, cb) { + return fs$writeFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$writeFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } + + var fs$appendFile = fs.appendFile + if (fs$appendFile) + fs.appendFile = appendFile + function appendFile (path, data, options, cb) { + if (typeof options === 'function') + cb = options, options = null + + return go$appendFile(path, data, options, cb) + + function go$appendFile (path, data, options, cb) { + return fs$appendFile(path, data, options, function (err) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$appendFile, [path, data, options, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } + + var fs$readdir = fs.readdir + fs.readdir = readdir + function readdir (path, options, cb) { + var args = [path] + if (typeof options !== 'function') { + args.push(options) + } else { + cb = options + } + args.push(go$readdir$cb) + + return go$readdir(args) + + function go$readdir$cb (err, files) { + if (files && files.sort) + files.sort() + + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$readdir, [args]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + } + } + + function go$readdir (args) { + return fs$readdir.apply(fs, args) + } + + if (process.version.substr(0, 4) === 'v0.8') { + var legStreams = legacy(fs) + ReadStream = legStreams.ReadStream + WriteStream = legStreams.WriteStream + } + + var fs$ReadStream = fs.ReadStream + ReadStream.prototype = Object.create(fs$ReadStream.prototype) + ReadStream.prototype.open = ReadStream$open + + var fs$WriteStream = fs.WriteStream + WriteStream.prototype = Object.create(fs$WriteStream.prototype) + WriteStream.prototype.open = WriteStream$open + + fs.ReadStream = ReadStream + fs.WriteStream = WriteStream - return mkdir(pth, { - mode: options.mode, - recursive: true - }).then(() => pth); - } + function ReadStream (path, options) { + if (this instanceof ReadStream) + return fs$ReadStream.apply(this, arguments), this + else + return ReadStream.apply(Object.create(ReadStream.prototype), arguments) + } - const make = pth => { - return mkdir(pth, options.mode) - .then(() => pth) - .catch(error => { - if (error.code === 'EPERM') { - throw error; - } + function ReadStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + if (that.autoClose) + that.destroy() - if (error.code === 'ENOENT') { - if (path.dirname(pth) === pth) { - throw permissionError(pth); - } + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) + that.read() + } + }) + } - if (error.message.includes('null bytes')) { - throw error; - } + function WriteStream (path, options) { + if (this instanceof WriteStream) + return fs$WriteStream.apply(this, arguments), this + else + return WriteStream.apply(Object.create(WriteStream.prototype), arguments) + } - return make(path.dirname(pth)).then(() => make(pth)); - } + function WriteStream$open () { + var that = this + open(that.path, that.flags, that.mode, function (err, fd) { + if (err) { + that.destroy() + that.emit('error', err) + } else { + that.fd = fd + that.emit('open', fd) + } + }) + } - return stat(pth) - .then(stats => stats.isDirectory() ? pth : Promise.reject()) - .catch(() => { - throw error; - }); - }); - }; + function createReadStream (path, options) { + return new ReadStream(path, options) + } - return make(path.resolve(input)); -}); + function createWriteStream (path, options) { + return new WriteStream(path, options) + } -module.exports = makeDir; -module.exports.default = makeDir; + var fs$open = fs.open + fs.open = open + function open (path, flags, mode, cb) { + if (typeof mode === 'function') + cb = mode, mode = null -module.exports.sync = (input, options) => { - checkPath(input); - options = Object.assign({}, defaults, options); + return go$open(path, flags, mode, cb) - if (useNativeRecursiveOption && options.fs.mkdirSync === fs.mkdirSync) { - const pth = path.resolve(input); + function go$open (path, flags, mode, cb) { + return fs$open(path, flags, mode, function (err, fd) { + if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) + enqueue([go$open, [path, flags, mode, cb]]) + else { + if (typeof cb === 'function') + cb.apply(this, arguments) + retry() + } + }) + } + } - fs.mkdirSync(pth, { - mode: options.mode, - recursive: true - }); + return fs +} - return pth; - } +function enqueue (elem) { + debug('ENQUEUE', elem[0].name, elem[1]) + queue.push(elem) +} - const make = pth => { - try { - options.fs.mkdirSync(pth, options.mode); - } catch (error) { - if (error.code === 'EPERM') { - throw error; - } +function retry () { + var elem = queue.shift() + if (elem) { + debug('RETRY', elem[0].name, elem[1]) + elem[0].apply(null, elem[1]) + } +} - if (error.code === 'ENOENT') { - if (path.dirname(pth) === pth) { - throw permissionError(pth); - } - if (error.message.includes('null bytes')) { - throw error; - } +/***/ }), +/* 553 */ +/***/ (function(module, exports, __webpack_require__) { - make(path.dirname(pth)); - return make(pth); - } +var fs = __webpack_require__(554) +var constants = __webpack_require__(411) - try { - if (!options.fs.statSync(pth).isDirectory()) { - throw new Error('The path is not a directory'); - } - } catch (_) { - throw error; - } - } +var origCwd = process.cwd +var cwd = null - return pth; - }; +var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform - return make(path.resolve(input)); -}; +process.cwd = function() { + if (!cwd) + cwd = origCwd.call(process) + return cwd +} +try { + process.cwd() +} catch (er) {} +var chdir = process.chdir +process.chdir = function(d) { + cwd = null + chdir.call(process, d) +} -/***/ }), -/* 561 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports = patch -"use strict"; +function patch (fs) { + // (re-)implement some things that are known busted or missing. + // lchmod, broken prior to 0.6.2 + // back-port the fix here. + if (constants.hasOwnProperty('O_SYMLINK') && + process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { + patchLchmod(fs) + } -const processFn = (fn, options) => function (...args) { - const P = options.promiseModule; + // lutimes implementation, or no-op + if (!fs.lutimes) { + patchLutimes(fs) + } - return new P((resolve, reject) => { - if (options.multiArgs) { - args.push((...result) => { - if (options.errorFirst) { - if (result[0]) { - reject(result); - } else { - result.shift(); - resolve(result); - } - } else { - resolve(result); - } - }); - } else if (options.errorFirst) { - args.push((error, result) => { - if (error) { - reject(error); - } else { - resolve(result); - } - }); - } else { - args.push(resolve); - } + // https://github.com/isaacs/node-graceful-fs/issues/4 + // Chown should not fail on einval or eperm if non-root. + // It should not fail on enosys ever, as this just indicates + // that a fs doesn't support the intended operation. - fn.apply(this, args); - }); -}; + fs.chown = chownFix(fs.chown) + fs.fchown = chownFix(fs.fchown) + fs.lchown = chownFix(fs.lchown) -module.exports = (input, options) => { - options = Object.assign({ - exclude: [/.+(Sync|Stream)$/], - errorFirst: true, - promiseModule: Promise - }, options); + fs.chmod = chmodFix(fs.chmod) + fs.fchmod = chmodFix(fs.fchmod) + fs.lchmod = chmodFix(fs.lchmod) - const objType = typeof input; - if (!(input !== null && (objType === 'object' || objType === 'function'))) { - throw new TypeError(`Expected \`input\` to be a \`Function\` or \`Object\`, got \`${input === null ? 'null' : objType}\``); - } + fs.chownSync = chownFixSync(fs.chownSync) + fs.fchownSync = chownFixSync(fs.fchownSync) + fs.lchownSync = chownFixSync(fs.lchownSync) - const filter = key => { - const match = pattern => typeof pattern === 'string' ? key === pattern : pattern.test(key); - return options.include ? options.include.some(match) : !options.exclude.some(match); - }; + fs.chmodSync = chmodFixSync(fs.chmodSync) + fs.fchmodSync = chmodFixSync(fs.fchmodSync) + fs.lchmodSync = chmodFixSync(fs.lchmodSync) - let ret; - if (objType === 'function') { - ret = function (...args) { - return options.excludeMain ? input(...args) : processFn(input, options).apply(this, args); - }; - } else { - ret = Object.create(Object.getPrototypeOf(input)); - } + fs.stat = statFix(fs.stat) + fs.fstat = statFix(fs.fstat) + fs.lstat = statFix(fs.lstat) - for (const key in input) { // eslint-disable-line guard-for-in - const property = input[key]; - ret[key] = typeof property === 'function' && filter(key) ? processFn(property, options) : property; - } + fs.statSync = statFixSync(fs.statSync) + fs.fstatSync = statFixSync(fs.fstatSync) + fs.lstatSync = statFixSync(fs.lstatSync) - return ret; -}; + // if lchmod/lchown do not exist, then make them no-ops + if (!fs.lchmod) { + fs.lchmod = function (path, mode, cb) { + if (cb) process.nextTick(cb) + } + fs.lchmodSync = function () {} + } + if (!fs.lchown) { + fs.lchown = function (path, uid, gid, cb) { + if (cb) process.nextTick(cb) + } + fs.lchownSync = function () {} + } + // on Windows, A/V software can lock the directory, causing this + // to fail with an EACCES or EPERM if the directory contains newly + // created files. Try again on failure, for up to 60 seconds. -/***/ }), -/* 562 */ -/***/ (function(module, exports, __webpack_require__) { + // Set the timeout this long because some Windows Anti-Virus, such as Parity + // bit9, may lock files for up to a minute, causing npm package install + // failures. Also, take care to yield the scheduler. Windows scheduling gives + // CPU to a busy looping process, which can cause the program causing the lock + // contention to be starved of CPU by node, so the contention doesn't resolve. + if (platform === "win32") { + fs.rename = (function (fs$rename) { return function (from, to, cb) { + var start = Date.now() + var backoff = 0; + fs$rename(from, to, function CB (er) { + if (er + && (er.code === "EACCES" || er.code === "EPERM") + && Date.now() - start < 60000) { + setTimeout(function() { + fs.stat(to, function (stater, st) { + if (stater && stater.code === "ENOENT") + fs$rename(from, to, CB); + else + cb(er) + }) + }, backoff) + if (backoff < 100) + backoff += 10; + return; + } + if (cb) cb(er) + }) + }})(fs.rename) + } -"use strict"; + // if read() returns EAGAIN, then just try it again. + fs.read = (function (fs$read) { return function (fd, buffer, offset, length, position, callback_) { + var callback + if (callback_ && typeof callback_ === 'function') { + var eagCounter = 0 + callback = function (er, _, __) { + if (er && er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + } + callback_.apply(this, arguments) + } + } + return fs$read.call(fs, fd, buffer, offset, length, position, callback) + }})(fs.read) + fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { + var eagCounter = 0 + while (true) { + try { + return fs$readSync.call(fs, fd, buffer, offset, length, position) + } catch (er) { + if (er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + continue + } + throw er + } + } + }})(fs.readSync) +} -// detect either spaces or tabs but not both to properly handle tabs -// for indentation and spaces for alignment -const INDENT_RE = /^(?:( )+|\t+)/; +function patchLchmod (fs) { + fs.lchmod = function (path, mode, callback) { + fs.open( path + , constants.O_WRONLY | constants.O_SYMLINK + , mode + , function (err, fd) { + if (err) { + if (callback) callback(err) + return + } + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + fs.fchmod(fd, mode, function (err) { + fs.close(fd, function(err2) { + if (callback) callback(err || err2) + }) + }) + }) + } -function getMostUsed(indents) { - let result = 0; - let maxUsed = 0; - let maxWeight = 0; + fs.lchmodSync = function (path, mode) { + var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) - for (const entry of indents) { - // TODO: use destructuring when targeting Node.js 6 - const key = entry[0]; - const val = entry[1]; + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + var threw = true + var ret + try { + ret = fs.fchmodSync(fd, mode) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } + } + return ret + } +} - const u = val[0]; - const w = val[1]; +function patchLutimes (fs) { + if (constants.hasOwnProperty("O_SYMLINK")) { + fs.lutimes = function (path, at, mt, cb) { + fs.open(path, constants.O_SYMLINK, function (er, fd) { + if (er) { + if (cb) cb(er) + return + } + fs.futimes(fd, at, mt, function (er) { + fs.close(fd, function (er2) { + if (cb) cb(er || er2) + }) + }) + }) + } - if (u > maxUsed || (u === maxUsed && w > maxWeight)) { - maxUsed = u; - maxWeight = w; - result = Number(key); - } - } + fs.lutimesSync = function (path, at, mt) { + var fd = fs.openSync(path, constants.O_SYMLINK) + var ret + var threw = true + try { + ret = fs.futimesSync(fd, at, mt) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } + } + return ret + } - return result; + } else { + fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } + fs.lutimesSync = function () {} + } } -module.exports = str => { - if (typeof str !== 'string') { - throw new TypeError('Expected a string'); - } +function chmodFix (orig) { + if (!orig) return orig + return function (target, mode, cb) { + return orig.call(fs, target, mode, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } +} - // used to see if tabs or spaces are the most used - let tabs = 0; - let spaces = 0; +function chmodFixSync (orig) { + if (!orig) return orig + return function (target, mode) { + try { + return orig.call(fs, target, mode) + } catch (er) { + if (!chownErOk(er)) throw er + } + } +} - // remember the size of previous line's indentation - let prev = 0; - // remember how many indents/unindents as occurred for a given size - // and how much lines follow a given indentation - // - // indents = { - // 3: [1, 0], - // 4: [1, 5], - // 5: [1, 0], - // 12: [1, 0], - // } - const indents = new Map(); +function chownFix (orig) { + if (!orig) return orig + return function (target, uid, gid, cb) { + return orig.call(fs, target, uid, gid, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } +} - // pointer to the array of last used indent - let current; +function chownFixSync (orig) { + if (!orig) return orig + return function (target, uid, gid) { + try { + return orig.call(fs, target, uid, gid) + } catch (er) { + if (!chownErOk(er)) throw er + } + } +} - // whether the last action was an indent (opposed to an unindent) - let isIndent; - for (const line of str.split(/\n/g)) { - if (!line) { - // ignore empty lines - continue; - } +function statFix (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target, cb) { + return orig.call(fs, target, function (er, stats) { + if (!stats) return cb.apply(this, arguments) + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + if (cb) cb.apply(this, arguments) + }) + } +} - let indent; - const matches = line.match(INDENT_RE); +function statFixSync (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target) { + var stats = orig.call(fs, target) + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + return stats; + } +} - if (matches) { - indent = matches[0].length; +// ENOSYS means that the fs doesn't support the op. Just ignore +// that, because it doesn't matter. +// +// if there's no getuid, or if getuid() is something other +// than 0, and the error is EINVAL or EPERM, then just ignore +// it. +// +// This specific case is a silent failure in cp, install, tar, +// and most other unix tools that manage permissions. +// +// When running as root, or if other types of errors are +// encountered, then it's strict. +function chownErOk (er) { + if (!er) + return true - if (matches[1]) { - spaces++; - } else { - tabs++; - } - } else { - indent = 0; - } + if (er.code === "ENOSYS") + return true - const diff = indent - prev; - prev = indent; + var nonroot = !process.getuid || process.getuid() !== 0 + if (nonroot) { + if (er.code === "EINVAL" || er.code === "EPERM") + return true + } - if (diff) { - // an indent or unindent has been detected + return false +} - isIndent = diff > 0; - current = indents.get(isIndent ? diff : -diff); +/***/ }), +/* 554 */ +/***/ (function(module, exports, __webpack_require__) { - if (current) { - current[0]++; - } else { - current = [1, 0]; - indents.set(diff, current); - } - } else if (current) { - // if the last action was an indent, increment the weight - current[1] += Number(isIndent); - } - } +"use strict"; - const amount = getMostUsed(indents); - let type; - let indent; - if (!amount) { - type = null; - indent = ''; - } else if (spaces >= tabs) { - type = 'space'; - indent = ' '.repeat(amount); - } else { - type = 'tab'; - indent = '\t'.repeat(amount); - } +var fs = __webpack_require__(349) - return { - amount, - type, - indent - }; -}; +module.exports = clone(fs) +function clone (obj) { + if (obj === null || typeof obj !== 'object') + return obj -/***/ }), -/* 563 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + if (obj instanceof Object) + var copy = { __proto__: obj.__proto__ } + else + var copy = Object.create(null) -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "installInDir", function() { return installInDir; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackage", function() { return runScriptInPackage; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackageStreaming", function() { return runScriptInPackageStreaming; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yarnWorkspacesInfo", function() { return yarnWorkspacesInfo; }); -/* harmony import */ var _child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(564); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + Object.getOwnPropertyNames(obj).forEach(function (key) { + Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) + }) + return copy +} -/** - * Install all dependencies in the given directory - */ -async function installInDir(directory, extraArgs = []) { - const options = ['install', '--non-interactive', ...extraArgs]; // We pass the mutex flag to ensure only one instance of yarn runs at any - // given time (e.g. to avoid conflicts). - await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])('yarn', options, { - cwd: directory - }); -} -/** - * Run script in the given directory - */ +/***/ }), +/* 555 */ +/***/ (function(module, exports, __webpack_require__) { -async function runScriptInPackage(script, args, pkg) { - const execOpts = { - cwd: pkg.path - }; - await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])('yarn', ['run', script, ...args], execOpts); -} -/** - * Run script in the given directory - */ +var Stream = __webpack_require__(382).Stream -function runScriptInPackageStreaming(script, args, pkg) { - const execOpts = { - cwd: pkg.path - }; - return Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawnStreaming"])('yarn', ['run', script, ...args], execOpts, { - prefix: pkg.name - }); -} -async function yarnWorkspacesInfo(directory) { - const { - stdout - } = await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])('yarn', ['--json', 'workspaces', 'info'], { - cwd: directory, - stdio: 'pipe' - }); +module.exports = legacy - try { - return JSON.parse(JSON.parse(stdout).data); - } catch (error) { - throw new Error(`'yarn workspaces info --json' produced unexpected output: \n${stdout}`); +function legacy (fs) { + return { + ReadStream: ReadStream, + WriteStream: WriteStream } -} -/***/ }), -/* 564 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + function ReadStream (path, options) { + if (!(this instanceof ReadStream)) return new ReadStream(path, options); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spawn", function() { return spawn; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spawnStreaming", function() { return spawnStreaming; }); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(371); -/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var log_symbols__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(565); -/* harmony import */ var log_symbols__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(log_symbols__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(570); -/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__); -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; } + Stream.call(this); -function _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; } + var self = this; -function _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; } + this.path = path; + this.fd = null; + this.readable = true; + this.paused = false; -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + this.flags = 'r'; + this.mode = 438; /*=0666*/ + this.bufferSize = 64 * 1024; + options = options || {}; + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } + if (this.encoding) this.setEncoding(this.encoding); + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.end === undefined) { + this.end = Infinity; + } else if ('number' !== typeof this.end) { + throw TypeError('end must be a Number'); + } -function generateColors() { - const colorWheel = [chalk__WEBPACK_IMPORTED_MODULE_0___default.a.cyan, chalk__WEBPACK_IMPORTED_MODULE_0___default.a.magenta, chalk__WEBPACK_IMPORTED_MODULE_0___default.a.blue, chalk__WEBPACK_IMPORTED_MODULE_0___default.a.yellow, chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green]; - const count = colorWheel.length; - let children = 0; - return () => colorWheel[children++ % count]; -} + if (this.start > this.end) { + throw new Error('start must be <= end'); + } -function spawn(command, args, opts) { - return execa__WEBPACK_IMPORTED_MODULE_1___default()(command, args, _objectSpread({ - stdio: 'inherit', - preferLocal: true - }, opts)); -} -const nextColor = generateColors(); -function spawnStreaming(command, args, opts, { - prefix -}) { - const spawned = execa__WEBPACK_IMPORTED_MODULE_1___default()(command, args, _objectSpread({ - stdio: ['ignore', 'pipe', 'pipe'], - preferLocal: true - }, opts)); - const color = nextColor(); - const prefixedStdout = strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default()({ - tag: `${color.bold(prefix)}:` - }); - const prefixedStderr = strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default()({ - mergeMultiline: true, - tag: `${log_symbols__WEBPACK_IMPORTED_MODULE_2___default.a.error} ${color.bold(prefix)}:` - }); - spawned.stdout.pipe(prefixedStdout).pipe(process.stdout); - spawned.stderr.pipe(prefixedStderr).pipe(process.stderr); - return spawned; -} + this.pos = this.start; + } -/***/ }), -/* 565 */ -/***/ (function(module, exports, __webpack_require__) { + if (this.fd !== null) { + process.nextTick(function() { + self._read(); + }); + return; + } -"use strict"; + fs.open(this.path, this.flags, this.mode, function (err, fd) { + if (err) { + self.emit('error', err); + self.readable = false; + return; + } -const chalk = __webpack_require__(566); + self.fd = fd; + self.emit('open', fd); + self._read(); + }) + } -const isSupported = process.platform !== 'win32' || process.env.CI || process.env.TERM === 'xterm-256color'; + function WriteStream (path, options) { + if (!(this instanceof WriteStream)) return new WriteStream(path, options); -const main = { - info: chalk.blue('ℹ'), - success: chalk.green('✔'), - warning: chalk.yellow('⚠'), - error: chalk.red('✖') -}; + Stream.call(this); -const fallbacks = { - info: chalk.blue('i'), - success: chalk.green('√'), - warning: chalk.yellow('‼'), - error: chalk.red('×') -}; + this.path = path; + this.fd = null; + this.writable = true; -module.exports = isSupported ? main : fallbacks; + this.flags = 'w'; + this.encoding = 'binary'; + this.mode = 438; /*=0666*/ + this.bytesWritten = 0; + options = options || {}; -/***/ }), -/* 566 */ -/***/ (function(module, exports, __webpack_require__) { + // Mixin options into this + var keys = Object.keys(options); + for (var index = 0, length = keys.length; index < length; index++) { + var key = keys[index]; + this[key] = options[key]; + } -"use strict"; + if (this.start !== undefined) { + if ('number' !== typeof this.start) { + throw TypeError('start must be a Number'); + } + if (this.start < 0) { + throw new Error('start must be >= zero'); + } -const escapeStringRegexp = __webpack_require__(3); -const ansiStyles = __webpack_require__(567); -const stdoutColor = __webpack_require__(568).stdout; + this.pos = this.start; + } -const template = __webpack_require__(569); + this.busy = false; + this._queue = []; -const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); + if (this.fd === null) { + this._open = fs.open; + this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); + this.flush(); + } + } +} -// `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; -// `color-convert` models to exclude from the Chalk API due to conflicts and such -const skipModels = new Set(['gray']); +/***/ }), +/* 556 */ +/***/ (function(module, exports, __webpack_require__) { -const styles = Object.create(null); +/** + * @preserve + * JS Implementation of incremental MurmurHash3 (r150) (as of May 10, 2013) + * + * @author Jens Taylor + * @see http://github.com/homebrewing/brauhaus-diff + * @author Gary Court + * @see http://github.com/garycourt/murmurhash-js + * @author Austin Appleby + * @see http://sites.google.com/site/murmurhash/ + */ +(function(){ + var cache; -function applyOptions(obj, options) { - options = options || {}; + // Call this function without `new` to use the cached object (good for + // single-threaded environments), or with `new` to create a new object. + // + // @param {string} key A UTF-16 or ASCII string + // @param {number} seed An optional positive integer + // @return {object} A MurmurHash3 object for incremental hashing + function MurmurHash3(key, seed) { + var m = this instanceof MurmurHash3 ? this : cache; + m.reset(seed) + if (typeof key === 'string' && key.length > 0) { + m.hash(key); + } - // Detect level if not set manually - const scLevel = stdoutColor ? stdoutColor.level : 0; - obj.level = options.level === undefined ? scLevel : options.level; - obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; -} + if (m !== this) { + return m; + } + }; -function Chalk(options) { - // We check for this.template here since calling `chalk.constructor()` - // by itself will have a `this` of a previously constructed chalk object - if (!this || !(this instanceof Chalk) || this.template) { - const chalk = {}; - applyOptions(chalk, options); + // Incrementally add a string to this hash + // + // @param {string} key A UTF-16 or ASCII string + // @return {object} this + MurmurHash3.prototype.hash = function(key) { + var h1, k1, i, top, len; - chalk.template = function () { - const args = [].slice.call(arguments); - return chalkTag.apply(null, [chalk.template].concat(args)); - }; + len = key.length; + this.len += len; - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); + k1 = this.k1; + i = 0; + switch (this.rem) { + case 0: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) : 0; + case 1: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 8 : 0; + case 2: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 16 : 0; + case 3: + k1 ^= len > i ? (key.charCodeAt(i) & 0xff) << 24 : 0; + k1 ^= len > i ? (key.charCodeAt(i++) & 0xff00) >> 8 : 0; + } - chalk.template.constructor = Chalk; + this.rem = (len + this.rem) & 3; // & 3 is same as % 4 + len -= this.rem; + if (len > 0) { + h1 = this.h1; + while (1) { + k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff; - return chalk.template; - } + h1 ^= k1; + h1 = (h1 << 13) | (h1 >>> 19); + h1 = (h1 * 5 + 0xe6546b64) & 0xffffffff; - applyOptions(this, options); -} + if (i >= len) { + break; + } -// Use bright blue on Windows as the normal blue color is illegible -if (isSimpleWindowsTerm) { - ansiStyles.blue.open = '\u001B[94m'; -} + k1 = ((key.charCodeAt(i++) & 0xffff)) ^ + ((key.charCodeAt(i++) & 0xffff) << 8) ^ + ((key.charCodeAt(i++) & 0xffff) << 16); + top = key.charCodeAt(i++); + k1 ^= ((top & 0xff) << 24) ^ + ((top & 0xff00) >> 8); + } -for (const key of Object.keys(ansiStyles)) { - ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); + k1 = 0; + switch (this.rem) { + case 3: k1 ^= (key.charCodeAt(i + 2) & 0xffff) << 16; + case 2: k1 ^= (key.charCodeAt(i + 1) & 0xffff) << 8; + case 1: k1 ^= (key.charCodeAt(i) & 0xffff); + } - styles[key] = { - get() { - const codes = ansiStyles[key]; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); - } - }; -} + this.h1 = h1; + } -styles.visible = { - get() { - return build.call(this, this._styles || [], true, 'visible'); - } -}; + this.k1 = k1; + return this; + }; -ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); -for (const model of Object.keys(ansiStyles.color.ansi)) { - if (skipModels.has(model)) { - continue; - } + // Get the result of this hash + // + // @return {number} The 32-bit hash + MurmurHash3.prototype.result = function() { + var k1, h1; + + k1 = this.k1; + h1 = this.h1; - styles[model] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.color.close, - closeRe: ansiStyles.color.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} + if (k1 > 0) { + k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff; + h1 ^= k1; + } -ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); -for (const model of Object.keys(ansiStyles.bgColor.ansi)) { - if (skipModels.has(model)) { - continue; - } + h1 ^= this.len; + + h1 ^= h1 >>> 16; + h1 = (h1 * 0xca6b + (h1 & 0xffff) * 0x85eb0000) & 0xffffffff; + h1 ^= h1 >>> 13; + h1 = (h1 * 0xae35 + (h1 & 0xffff) * 0xc2b20000) & 0xffffffff; + h1 ^= h1 >>> 16; - const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); - styles[bgModel] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.bgColor.close, - closeRe: ansiStyles.bgColor.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} + return h1 >>> 0; + }; -const proto = Object.defineProperties(() => {}, styles); + // Reset the hash object for reuse + // + // @param {number} seed An optional positive integer + MurmurHash3.prototype.reset = function(seed) { + this.h1 = typeof seed === 'number' ? seed : 0; + this.rem = this.k1 = this.len = 0; + return this; + }; -function build(_styles, _empty, key) { - const builder = function () { - return applyStyle.apply(builder, arguments); - }; + // A cached object to use. This can be safely used if you're in a single- + // threaded environment, otherwise you need to create new hashes to use. + cache = new MurmurHash3(); - builder._styles = _styles; - builder._empty = _empty; + if (true) { + module.exports = MurmurHash3; + } else {} +}()); - const self = this; - Object.defineProperty(builder, 'level', { - enumerable: true, - get() { - return self.level; - }, - set(level) { - self.level = level; - } - }); +/***/ }), +/* 557 */ +/***/ (function(module, exports) { - Object.defineProperty(builder, 'enabled', { - enumerable: true, - get() { - return self.enabled; - }, - set(enabled) { - self.enabled = enabled; - } - }); +module.exports = require(undefined); - // See below for fix regarding invisible grey/dim combination on Windows - builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; +/***/ }), +/* 558 */ +/***/ (function(module, exports, __webpack_require__) { - // `__proto__` is used because we must return a function, but there is - // no way to create a function with a different prototype - builder.__proto__ = proto; // eslint-disable-line no-proto +"use strict"; - return builder; -} +const isPlainObj = __webpack_require__(559); -function applyStyle() { - // Support varags, but simply cast to string in case there's only one arg - const args = arguments; - const argsLen = args.length; - let str = String(arguments[0]); +module.exports = (obj, opts) => { + if (!isPlainObj(obj)) { + throw new TypeError('Expected a plain object'); + } - if (argsLen === 0) { - return ''; + opts = opts || {}; + + // DEPRECATED + if (typeof opts === 'function') { + throw new TypeError('Specify the compare function as an option instead'); } - if (argsLen > 1) { - // Don't slice `arguments`, it prevents V8 optimizations - for (let a = 1; a < argsLen; a++) { - str += ' ' + args[a]; + const deep = opts.deep; + const seenInput = []; + const seenOutput = []; + + const sortKeys = x => { + const seenIndex = seenInput.indexOf(x); + + if (seenIndex !== -1) { + return seenOutput[seenIndex]; } - } - if (!this.enabled || this.level <= 0 || !str) { - return this._empty ? '' : str; - } + const ret = {}; + const keys = Object.keys(x).sort(opts.compare); - // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, - // see https://github.com/chalk/chalk/issues/58 - // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. - const originalDim = ansiStyles.dim.open; - if (isSimpleWindowsTerm && this.hasGrey) { - ansiStyles.dim.open = ''; - } + seenInput.push(x); + seenOutput.push(ret); - for (const code of this._styles.slice().reverse()) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - str = code.open + str.replace(code.closeRe, code.open) + code.close; + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + const val = x[key]; - // Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS - // https://github.com/chalk/chalk/pull/92 - str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); - } + if (deep && Array.isArray(val)) { + const retArr = []; - // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue - ansiStyles.dim.open = originalDim; + for (let j = 0; j < val.length; j++) { + retArr[j] = isPlainObj(val[j]) ? sortKeys(val[j]) : val[j]; + } - return str; -} + ret[key] = retArr; + continue; + } -function chalkTag(chalk, strings) { - if (!Array.isArray(strings)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return [].slice.call(arguments, 1).join(' '); - } + ret[key] = deep && isPlainObj(val) ? sortKeys(val) : val; + } - const args = [].slice.call(arguments, 2); - const parts = [strings.raw[0]]; + return ret; + }; - for (let i = 1; i < strings.length; i++) { - parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); - parts.push(String(strings.raw[i])); - } + return sortKeys(obj); +}; - return template(chalk, parts.join('')); -} -Object.defineProperties(Chalk.prototype, styles); +/***/ }), +/* 559 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = Chalk(); // eslint-disable-line new-cap -module.exports.supportsColor = stdoutColor; -module.exports.default = module.exports; // For TypeScript +"use strict"; + +var toString = Object.prototype.toString; + +module.exports = function (x) { + var prototype; + return toString.call(x) === '[object Object]' && (prototype = Object.getPrototypeOf(x), prototype === null || prototype === Object.getPrototypeOf({})); +}; /***/ }), -/* 567 */ +/* 560 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(6); -const wrapAnsi16 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${code + offset}m`; +const fs = __webpack_require__(349); +const path = __webpack_require__(4); +const pify = __webpack_require__(561); +const semver = __webpack_require__(523); + +const defaults = { + mode: 0o777 & (~process.umask()), + fs }; -const wrapAnsi256 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};5;${code}m`; +const useNativeRecursiveOption = semver.satisfies(process.version, '>=10.12.0'); + +// https://github.com/nodejs/node/issues/8987 +// https://github.com/libuv/libuv/pull/1088 +const checkPath = pth => { + if (process.platform === 'win32') { + const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path.parse(pth).root, '')); + + if (pathHasInvalidWinCharacters) { + const error = new Error(`Path contains invalid characters: ${pth}`); + error.code = 'EINVAL'; + throw error; + } + } }; -const wrapAnsi16m = (fn, offset) => function () { - const rgb = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; +const permissionError = pth => { + // This replicates the exception of `fs.mkdir` with native the + // `recusive` option when run on an invalid drive under Windows. + const error = new Error(`operation not permitted, mkdir '${pth}'`); + error.code = 'EPERM'; + error.errno = -4048; + error.path = pth; + error.syscall = 'mkdir'; + return error; }; -function assembleStyles() { - const codes = new Map(); - const styles = { - modifier: { - reset: [0, 0], - // 21 isn't widely supported and 22 does the same thing - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - gray: [90, 39], +const makeDir = (input, options) => Promise.resolve().then(() => { + checkPath(input); + options = Object.assign({}, defaults, options); - // Bright color - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39] - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], + // TODO: Use util.promisify when targeting Node.js 8 + const mkdir = pify(options.fs.mkdir); + const stat = pify(options.fs.stat); - // Bright color - bgBlackBright: [100, 49], - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49] - } - }; + if (useNativeRecursiveOption && options.fs.mkdir === fs.mkdir) { + const pth = path.resolve(input); - // Fix humans - styles.color.grey = styles.color.gray; + return mkdir(pth, { + mode: options.mode, + recursive: true + }).then(() => pth); + } - for (const groupName of Object.keys(styles)) { - const group = styles[groupName]; + const make = pth => { + return mkdir(pth, options.mode) + .then(() => pth) + .catch(error => { + if (error.code === 'EPERM') { + throw error; + } - for (const styleName of Object.keys(group)) { - const style = group[styleName]; + if (error.code === 'ENOENT') { + if (path.dirname(pth) === pth) { + throw permissionError(pth); + } - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m` - }; + if (error.message.includes('null bytes')) { + throw error; + } - group[styleName] = styles[styleName]; + return make(path.dirname(pth)).then(() => make(pth)); + } - codes.set(style[0], style[1]); - } + return stat(pth) + .then(stats => stats.isDirectory() ? pth : Promise.reject()) + .catch(() => { + throw error; + }); + }); + }; - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); + return make(path.resolve(input)); +}); - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false +module.exports = makeDir; +module.exports.default = makeDir; + +module.exports.sync = (input, options) => { + checkPath(input); + options = Object.assign({}, defaults, options); + + if (useNativeRecursiveOption && options.fs.mkdirSync === fs.mkdirSync) { + const pth = path.resolve(input); + + fs.mkdirSync(pth, { + mode: options.mode, + recursive: true }); + + return pth; } - const ansi2ansi = n => n; - const rgb2rgb = (r, g, b) => [r, g, b]; + const make = pth => { + try { + options.fs.mkdirSync(pth, options.mode); + } catch (error) { + if (error.code === 'EPERM') { + throw error; + } - styles.color.close = '\u001B[39m'; - styles.bgColor.close = '\u001B[49m'; + if (error.code === 'ENOENT') { + if (path.dirname(pth) === pth) { + throw permissionError(pth); + } - styles.color.ansi = { - ansi: wrapAnsi16(ansi2ansi, 0) - }; - styles.color.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 0) - }; - styles.color.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 0) - }; + if (error.message.includes('null bytes')) { + throw error; + } - styles.bgColor.ansi = { - ansi: wrapAnsi16(ansi2ansi, 10) - }; - styles.bgColor.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 10) - }; - styles.bgColor.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 10) - }; + make(path.dirname(pth)); + return make(pth); + } - for (let key of Object.keys(colorConvert)) { - if (typeof colorConvert[key] !== 'object') { - continue; + try { + if (!options.fs.statSync(pth).isDirectory()) { + throw new Error('The path is not a directory'); + } + } catch (_) { + throw error; + } } - const suite = colorConvert[key]; + return pth; + }; - if (key === 'ansi16') { - key = 'ansi'; - } + return make(path.resolve(input)); +}; - if ('ansi16' in suite) { - styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); - styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); - } - if ('ansi256' in suite) { - styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); - styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); - } +/***/ }), +/* 561 */ +/***/ (function(module, exports, __webpack_require__) { - if ('rgb' in suite) { - styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); - styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); +"use strict"; + + +const processFn = (fn, options) => function (...args) { + const P = options.promiseModule; + + return new P((resolve, reject) => { + if (options.multiArgs) { + args.push((...result) => { + if (options.errorFirst) { + if (result[0]) { + reject(result); + } else { + result.shift(); + resolve(result); + } + } else { + resolve(result); + } + }); + } else if (options.errorFirst) { + args.push((error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); + } else { + args.push(resolve); } + + fn.apply(this, args); + }); +}; + +module.exports = (input, options) => { + options = Object.assign({ + exclude: [/.+(Sync|Stream)$/], + errorFirst: true, + promiseModule: Promise + }, options); + + const objType = typeof input; + if (!(input !== null && (objType === 'object' || objType === 'function'))) { + throw new TypeError(`Expected \`input\` to be a \`Function\` or \`Object\`, got \`${input === null ? 'null' : objType}\``); } - return styles; -} + const filter = key => { + const match = pattern => typeof pattern === 'string' ? key === pattern : pattern.test(key); + return options.include ? options.include.some(match) : !options.exclude.some(match); + }; -// Make the export immutable -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); + let ret; + if (objType === 'function') { + ret = function (...args) { + return options.excludeMain ? input(...args) : processFn(input, options).apply(this, args); + }; + } else { + ret = Object.create(Object.getPrototypeOf(input)); + } + + for (const key in input) { // eslint-disable-line guard-for-in + const property = input[key]; + ret[key] = typeof property === 'function' && filter(key) ? processFn(property, options) : property; + } + + return ret; +}; -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(5)(module))) /***/ }), -/* 568 */ +/* 562 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const os = __webpack_require__(11); -const hasFlag = __webpack_require__(12); -const env = process.env; +// detect either spaces or tabs but not both to properly handle tabs +// for indentation and spaces for alignment +const INDENT_RE = /^(?:( )+|\t+)/; -let forceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false')) { - forceColor = false; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - forceColor = true; -} -if ('FORCE_COLOR' in env) { - forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; -} +function getMostUsed(indents) { + let result = 0; + let maxUsed = 0; + let maxWeight = 0; -function translateLevel(level) { - if (level === 0) { - return false; + for (const entry of indents) { + // TODO: use destructuring when targeting Node.js 6 + const key = entry[0]; + const val = entry[1]; + + const u = val[0]; + const w = val[1]; + + if (u > maxUsed || (u === maxUsed && w > maxWeight)) { + maxUsed = u; + maxWeight = w; + result = Number(key); + } } - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; + return result; } -function supportsColor(stream) { - if (forceColor === false) { - return 0; +module.exports = str => { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); } - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } + // used to see if tabs or spaces are the most used + let tabs = 0; + let spaces = 0; - if (hasFlag('color=256')) { - return 2; - } + // remember the size of previous line's indentation + let prev = 0; - if (stream && !stream.isTTY && forceColor !== true) { - // VS code debugger doesn't have isTTY set - if (env.VSCODE_PID) { - return 1; - } - return 0; - } + // remember how many indents/unindents as occurred for a given size + // and how much lines follow a given indentation + // + // indents = { + // 3: [1, 0], + // 4: [1, 5], + // 5: [1, 0], + // 12: [1, 0], + // } + const indents = new Map(); - const min = forceColor ? 1 : 0; + // pointer to the array of last used indent + let current; - if (process.platform === 'win32') { - // Node.js 7.5.0 is the first version of Node.js to include a patch to - // libuv that enables 256 color output on Windows. Anything earlier and it - // won't work. However, here we target Node.js 8 at minimum as it is an LTS - // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows - // release that supports 256 colors. Windows 10 build 14931 is the first release - // that supports 16m/TrueColor. - const osRelease = os.release().split('.'); - if ( - Number(process.versions.node.split('.')[0]) >= 8 && - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; + // whether the last action was an indent (opposed to an unindent) + let isIndent; + + for (const line of str.split(/\n/g)) { + if (!line) { + // ignore empty lines + continue; } - return 1; - } + let indent; + const matches = line.match(INDENT_RE); - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; + if (matches) { + indent = matches[0].length; + + if (matches[1]) { + spaces++; + } else { + tabs++; + } + } else { + indent = 0; } - return min; - } + const diff = indent - prev; + prev = indent; - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } + if (diff) { + // an indent or unindent has been detected - if (env.COLORTERM === 'truecolor') { - return 3; - } + isIndent = diff > 0; - if ('TERM_PROGRAM' in env) { - const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + current = indents.get(isIndent ? diff : -diff); - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default + if (current) { + current[0]++; + } else { + current = [1, 0]; + indents.set(diff, current); + } + } else if (current) { + // if the last action was an indent, increment the weight + current[1] += Number(isIndent); } } - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } - - if (/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } - - if ('COLORTERM' in env) { - return 1; - } + const amount = getMostUsed(indents); - if (env.TERM === 'dumb') { - return min; + let type; + let indent; + if (!amount) { + type = null; + indent = ''; + } else if (spaces >= tabs) { + type = 'space'; + indent = ' '.repeat(amount); + } else { + type = 'tab'; + indent = '\t'.repeat(amount); } - return min; -} - -function getSupportLevel(stream) { - const level = supportsColor(stream); - return translateLevel(level); -} - -module.exports = { - supportsColor: getSupportLevel, - stdout: getSupportLevel(process.stdout), - stderr: getSupportLevel(process.stderr) + return { + amount, + type, + indent + }; }; /***/ }), -/* 569 */ -/***/ (function(module, exports, __webpack_require__) { +/* 563 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "installInDir", function() { return installInDir; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackage", function() { return runScriptInPackage; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackageStreaming", function() { return runScriptInPackageStreaming; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yarnWorkspacesInfo", function() { return yarnWorkspacesInfo; }); +/* harmony import */ var _child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(564); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; -const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; -const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; - -const ESCAPES = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); -function unescape(c) { - if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); - } +/** + * Install all dependencies in the given directory + */ +async function installInDir(directory, extraArgs = []) { + const options = ['install', '--non-interactive', ...extraArgs]; // We pass the mutex flag to ensure only one instance of yarn runs at any + // given time (e.g. to avoid conflicts). - return ESCAPES.get(c) || c; + await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])('yarn', options, { + cwd: directory + }); } +/** + * Run script in the given directory + */ -function parseArguments(name, args) { - const results = []; - const chunks = args.trim().split(/\s*,\s*/g); - let matches; +async function runScriptInPackage(script, args, pkg) { + const execOpts = { + cwd: pkg.path + }; + await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])('yarn', ['run', script, ...args], execOpts); +} +/** + * Run script in the given directory + */ - for (const chunk of chunks) { - if (!isNaN(chunk)) { - results.push(Number(chunk)); - } else if ((matches = chunk.match(STRING_REGEX))) { - results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); - } else { - throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); - } - } +function runScriptInPackageStreaming({ + script, + args, + pkg, + debug +}) { + const execOpts = { + cwd: pkg.path + }; + return Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawnStreaming"])('yarn', ['run', script, ...args], execOpts, { + prefix: pkg.name, + debug + }); +} +async function yarnWorkspacesInfo(directory) { + const { + stdout + } = await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])('yarn', ['--json', 'workspaces', 'info'], { + cwd: directory, + stdio: 'pipe' + }); - return results; + try { + return JSON.parse(JSON.parse(stdout).data); + } catch (error) { + throw new Error(`'yarn workspaces info --json' produced unexpected output: \n${stdout}`); + } } -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; +/***/ }), +/* 564 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - const results = []; - let matches; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spawn", function() { return spawn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spawnStreaming", function() { return spawnStreaming; }); +/* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(382); +/* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(stream__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(386); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(342); +/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(565); +/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(500); +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; } - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; +function _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; } - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } - } +function _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; } - return results; -} +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -function buildStyle(chalk, styles) { - const enabled = {}; - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } - } - let current = chalk; - for (const styleName of Object.keys(enabled)) { - if (Array.isArray(enabled[styleName])) { - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } - if (enabled[styleName].length > 0) { - current = current[styleName].apply(current, enabled[styleName]); - } else { - current = current[styleName]; - } - } - } - return current; -} +const colorWheel = [chalk__WEBPACK_IMPORTED_MODULE_1___default.a.cyan, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.magenta, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.blue, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.yellow, chalk__WEBPACK_IMPORTED_MODULE_1___default.a.green]; -module.exports = (chalk, tmp) => { - const styles = []; - const chunks = []; - let chunk = []; +const getColor = () => { + const color = colorWheel.shift(); + colorWheel.push(color); + return color; +}; - // eslint-disable-next-line max-params - tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { - if (escapeChar) { - chunk.push(unescape(escapeChar)); - } else if (style) { - const str = chunk.join(''); - chunk = []; - chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); - styles.push({inverse, styles: parseStyle(style)}); - } else if (close) { - if (styles.length === 0) { - throw new Error('Found extraneous } in Chalk template literal'); - } +function spawn(command, args, opts) { + return execa__WEBPACK_IMPORTED_MODULE_2___default()(command, args, _objectSpread({ + stdio: 'inherit', + preferLocal: true + }, opts)); +} - chunks.push(buildStyle(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(chr); - } - }); +function streamToLog(debug = true) { + return new stream__WEBPACK_IMPORTED_MODULE_0__["Writable"]({ + objectMode: true, - chunks.push(chunk.join('')); + write(line, _, cb) { + if (line.endsWith('\n')) { + _log__WEBPACK_IMPORTED_MODULE_4__["log"][debug ? 'debug' : 'write'](line.slice(0, -1)); + } else { + _log__WEBPACK_IMPORTED_MODULE_4__["log"][debug ? 'debug' : 'write'](line); + } - if (styles.length > 0) { - const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMsg); - } + cb(); + } - return chunks.join(''); -}; + }); +} +function spawnStreaming(command, args, opts, { + prefix, + debug +}) { + const spawned = execa__WEBPACK_IMPORTED_MODULE_2___default()(command, args, _objectSpread({ + stdio: ['ignore', 'pipe', 'pipe'], + preferLocal: true + }, opts)); + const color = getColor(); + const prefixedStdout = strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default()({ + tag: color.bold(prefix) + }); + const prefixedStderr = strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default()({ + mergeMultiline: true, + tag: color.bold(prefix) + }); + spawned.stdout.pipe(prefixedStdout).pipe(streamToLog(debug)); + spawned.stderr.pipe(prefixedStderr).pipe(streamToLog(debug)); + return spawned; +} /***/ }), -/* 570 */ +/* 565 */ /***/ (function(module, exports, __webpack_require__) { // Copyright IBM Corp. 2014,2018. All Rights Reserved. @@ -56063,12 +55405,12 @@ module.exports = (chalk, tmp) => { // This file is licensed under the Apache License 2.0. // License text available at https://opensource.org/licenses/Apache-2.0 -module.exports = __webpack_require__(571); -module.exports.cli = __webpack_require__(575); +module.exports = __webpack_require__(566); +module.exports.cli = __webpack_require__(570); /***/ }), -/* 571 */ +/* 566 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -56079,13 +55421,13 @@ module.exports.cli = __webpack_require__(575); -var stream = __webpack_require__(27); -var util = __webpack_require__(29); -var fs = __webpack_require__(23); +var stream = __webpack_require__(382); +var util = __webpack_require__(397); +var fs = __webpack_require__(349); -var through = __webpack_require__(572); -var duplexer = __webpack_require__(573); -var StringDecoder = __webpack_require__(574).StringDecoder; +var through = __webpack_require__(567); +var duplexer = __webpack_require__(568); +var StringDecoder = __webpack_require__(569).StringDecoder; module.exports = Logger; @@ -56274,10 +55616,10 @@ function lineMerger(host) { /***/ }), -/* 572 */ +/* 567 */ /***/ (function(module, exports, __webpack_require__) { -var Stream = __webpack_require__(27) +var Stream = __webpack_require__(382) // through // @@ -56388,10 +55730,10 @@ function through (write, end, opts) { /***/ }), -/* 573 */ +/* 568 */ /***/ (function(module, exports, __webpack_require__) { -var Stream = __webpack_require__(27) +var Stream = __webpack_require__(382) var writeMethods = ["write", "end", "destroy"] var readMethods = ["resume", "pause"] var readEvents = ["data", "close"] @@ -56481,13 +55823,13 @@ function duplex(writer, reader) { /***/ }), -/* 574 */ +/* 569 */ /***/ (function(module, exports) { module.exports = require("string_decoder"); /***/ }), -/* 575 */ +/* 570 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -56498,11 +55840,11 @@ module.exports = require("string_decoder"); -var minimist = __webpack_require__(576); -var path = __webpack_require__(16); +var minimist = __webpack_require__(571); +var path = __webpack_require__(4); -var Logger = __webpack_require__(571); -var pkg = __webpack_require__(577); +var Logger = __webpack_require__(566); +var pkg = __webpack_require__(572); module.exports = cli; @@ -56556,7 +55898,7 @@ function usage($0, p) { /***/ }), -/* 576 */ +/* 571 */ /***/ (function(module, exports) { module.exports = function (args, opts) { @@ -56798,13 +56140,13 @@ function isNumber (x) { /***/ }), -/* 577 */ +/* 572 */ /***/ (function(module) { module.exports = JSON.parse("{\"name\":\"strong-log-transformer\",\"version\":\"2.1.0\",\"description\":\"Stream transformer that prefixes lines with timestamps and other things.\",\"author\":\"Ryan Graham \",\"license\":\"Apache-2.0\",\"repository\":{\"type\":\"git\",\"url\":\"git://github.com/strongloop/strong-log-transformer\"},\"keywords\":[\"logging\",\"streams\"],\"bugs\":{\"url\":\"https://github.com/strongloop/strong-log-transformer/issues\"},\"homepage\":\"https://github.com/strongloop/strong-log-transformer\",\"directories\":{\"test\":\"test\"},\"bin\":{\"sl-log-transformer\":\"bin/sl-log-transformer.js\"},\"main\":\"index.js\",\"scripts\":{\"test\":\"tap --100 test/test-*\"},\"dependencies\":{\"duplexer\":\"^0.1.1\",\"minimist\":\"^1.2.0\",\"through\":\"^2.3.4\"},\"devDependencies\":{\"tap\":\"^12.0.1\"},\"engines\":{\"node\":\">=4\"}}"); /***/ }), -/* 578 */ +/* 573 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56813,12 +56155,12 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "copyWorkspacePackages", function() { return copyWorkspacePackages; }); /* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(503); /* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(glob__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(29); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(397); /* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(579); -/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(20); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(574); +/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(491); /* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(518); /* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(502); /* @@ -56912,13 +56254,13 @@ function packagesFromGlobPattern({ } /***/ }), -/* 579 */ +/* 574 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getProjectPaths", function() { return getProjectPaths; }); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); /* * Licensed to Elasticsearch B.V. under one or more contributor @@ -56982,21 +56324,21 @@ function getProjectPaths({ } /***/ }), -/* 580 */ +/* 575 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getAllChecksums", function() { return getAllChecksums; }); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(23); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(349); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(581); +/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(576); /* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(crypto__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(29); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(397); /* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(371); +/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(342); /* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(582); +/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(577); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -57225,21 +56567,21 @@ async function getAllChecksums(kbn, log) { } /***/ }), -/* 581 */ +/* 576 */ /***/ (function(module, exports) { module.exports = require("crypto"); /***/ }), -/* 582 */ +/* 577 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readYarnLock", function() { return readYarnLock; }); -/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(583); +/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(578); /* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(20); +/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(491); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -57281,7 +56623,7 @@ async function readYarnLock(kbn) { } /***/ }), -/* 583 */ +/* 578 */ /***/ (function(module, exports, __webpack_require__) { module.exports = @@ -57357,7 +56699,7 @@ module.exports = /* 0 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(16); +module.exports = __webpack_require__(4); /***/ }), /* 1 */ @@ -57407,13 +56749,13 @@ exports.default = function (fn) { /* 2 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(29); +module.exports = __webpack_require__(397); /***/ }), /* 3 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(23); +module.exports = __webpack_require__(349); /***/ }), /* 4 */ @@ -58840,7 +58182,7 @@ module.exports = invariant; /* 9 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(581); +module.exports = __webpack_require__(576); /***/ }), /* 10 */, @@ -59266,7 +58608,7 @@ exports.default = Lockfile; /* 17 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(27); +module.exports = __webpack_require__(382); /***/ }), /* 18 */, @@ -59318,7 +58660,7 @@ function nullify(obj = {}) { /* 22 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(30); +module.exports = __webpack_require__(371); /***/ }), /* 23 */ @@ -59505,7 +58847,7 @@ module.exports = {}; /* 36 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(11); +module.exports = __webpack_require__(364); /***/ }), /* 37 */, @@ -59790,7 +59132,7 @@ exports.f = __webpack_require__(33) ? Object.defineProperty : function definePro /* 54 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(399); +module.exports = __webpack_require__(373); /***/ }), /* 55 */ @@ -61164,7 +60506,7 @@ function onceStrict (fn) { /* 63 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(584); +module.exports = __webpack_require__(579); /***/ }), /* 64 */, @@ -62102,7 +61444,7 @@ module.exports.win32 = win32; /* 79 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(484); +module.exports = __webpack_require__(471); /***/ }), /* 80 */, @@ -67559,21 +66901,21 @@ module.exports = process && support(supportLevel); /******/ ]); /***/ }), -/* 584 */ +/* 579 */ /***/ (function(module, exports) { module.exports = require("buffer"); /***/ }), -/* 585 */ +/* 580 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BootstrapCacheFile", function() { return BootstrapCacheFile; }); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(23); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(349); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); function _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; } @@ -67662,22 +67004,20 @@ class BootstrapCacheFile { } /***/ }), -/* 586 */ +/* 581 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CleanCommand", function() { return CleanCommand; }); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(587); -/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(675); -/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(ora__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(20); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(34); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(582); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(670); +/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ora__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(491); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(500); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -67701,7 +67041,6 @@ __webpack_require__.r(__webpack_exports__); - const CleanCommand = { description: 'Remove the node_modules and target directories from all projects.', name: 'clean', @@ -67710,17 +67049,17 @@ const CleanCommand = { const toDelete = []; for (const project of projects.values()) { - if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_4__["isDirectory"])(project.nodeModulesLocation)) { + if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_3__["isDirectory"])(project.nodeModulesLocation)) { toDelete.push({ cwd: project.path, - pattern: Object(path__WEBPACK_IMPORTED_MODULE_3__["relative"])(project.path, project.nodeModulesLocation) + pattern: Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(project.path, project.nodeModulesLocation) }); } - if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_4__["isDirectory"])(project.targetLocation)) { + if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_3__["isDirectory"])(project.targetLocation)) { toDelete.push({ cwd: project.path, - pattern: Object(path__WEBPACK_IMPORTED_MODULE_3__["relative"])(project.path, project.targetLocation) + pattern: Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(project.path, project.targetLocation) }); } @@ -67737,9 +67076,8 @@ const CleanCommand = { } if (toDelete.length === 0) { - _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold.green('\n\nNothing to delete')); + _utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].success('Nothing to delete'); } else { - _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold.red('\n\nDeleting:\n')); /** * In order to avoid patterns like `/build` in packages from accidentally * impacting files outside the package we use `process.chdir()` to change @@ -67749,7 +67087,6 @@ const CleanCommand = { * `del()` does support a `cwd` option, but it's only for resolving the * patterns and does not impact the cwd check. */ - const originalCwd = process.cwd(); try { @@ -67758,8 +67095,12 @@ const CleanCommand = { cwd } of toDelete) { process.chdir(cwd); - const promise = del__WEBPACK_IMPORTED_MODULE_1___default()(pattern); - ora__WEBPACK_IMPORTED_MODULE_2___default.a.promise(promise, Object(path__WEBPACK_IMPORTED_MODULE_3__["relative"])(originalCwd, Object(path__WEBPACK_IMPORTED_MODULE_3__["join"])(cwd, String(pattern)))); + const promise = del__WEBPACK_IMPORTED_MODULE_0___default()(pattern); + + if (_utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].wouldLogLevel('info')) { + ora__WEBPACK_IMPORTED_MODULE_1___default.a.promise(promise, Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(originalCwd, Object(path__WEBPACK_IMPORTED_MODULE_2__["join"])(cwd, String(pattern)))); + } + await promise; } } finally { @@ -67771,21 +67112,21 @@ const CleanCommand = { }; /***/ }), -/* 587 */ +/* 582 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const {promisify} = __webpack_require__(29); -const path = __webpack_require__(16); -const globby = __webpack_require__(588); -const isGlob = __webpack_require__(605); -const slash = __webpack_require__(666); -const gracefulFs = __webpack_require__(22); -const isPathCwd = __webpack_require__(668); -const isPathInside = __webpack_require__(669); -const rimraf = __webpack_require__(670); -const pMap = __webpack_require__(671); +const {promisify} = __webpack_require__(397); +const path = __webpack_require__(4); +const globby = __webpack_require__(583); +const isGlob = __webpack_require__(600); +const slash = __webpack_require__(661); +const gracefulFs = __webpack_require__(493); +const isPathCwd = __webpack_require__(663); +const isPathInside = __webpack_require__(664); +const rimraf = __webpack_require__(665); +const pMap = __webpack_require__(666); const rimrafP = promisify(rimraf); @@ -67899,19 +67240,19 @@ module.exports.sync = (patterns, {force, dryRun, cwd = process.cwd(), ...options /***/ }), -/* 588 */ +/* 583 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(23); -const arrayUnion = __webpack_require__(589); -const merge2 = __webpack_require__(590); -const glob = __webpack_require__(591); -const fastGlob = __webpack_require__(596); -const dirGlob = __webpack_require__(662); -const gitignore = __webpack_require__(664); -const {FilterStream, UniqueStream} = __webpack_require__(667); +const fs = __webpack_require__(349); +const arrayUnion = __webpack_require__(584); +const merge2 = __webpack_require__(585); +const glob = __webpack_require__(586); +const fastGlob = __webpack_require__(591); +const dirGlob = __webpack_require__(657); +const gitignore = __webpack_require__(659); +const {FilterStream, UniqueStream} = __webpack_require__(662); const DEFAULT_FILTER = () => false; @@ -68084,7 +67425,7 @@ module.exports.gitignore = gitignore; /***/ }), -/* 589 */ +/* 584 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68096,7 +67437,7 @@ module.exports = (...arguments_) => { /***/ }), -/* 590 */ +/* 585 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68108,7 +67449,7 @@ module.exports = (...arguments_) => { * Copyright (c) 2014-2016 Teambition * Licensed under the MIT license. */ -const Stream = __webpack_require__(27) +const Stream = __webpack_require__(382) const PassThrough = Stream.PassThrough const slice = Array.prototype.slice @@ -68210,7 +67551,7 @@ function pauseStreams (streams, options) { /***/ }), -/* 591 */ +/* 586 */ /***/ (function(module, exports, __webpack_require__) { // Approach: @@ -68255,27 +67596,27 @@ function pauseStreams (streams, options) { module.exports = glob -var fs = __webpack_require__(23) +var fs = __webpack_require__(349) var rp = __webpack_require__(504) var minimatch = __webpack_require__(506) var Minimatch = minimatch.Minimatch -var inherits = __webpack_require__(592) -var EE = __webpack_require__(399).EventEmitter -var path = __webpack_require__(16) -var assert = __webpack_require__(30) +var inherits = __webpack_require__(587) +var EE = __webpack_require__(373).EventEmitter +var path = __webpack_require__(4) +var assert = __webpack_require__(371) var isAbsolute = __webpack_require__(512) -var globSync = __webpack_require__(594) -var common = __webpack_require__(595) +var globSync = __webpack_require__(589) +var common = __webpack_require__(590) var alphasort = common.alphasort var alphasorti = common.alphasorti var setopts = common.setopts var ownProp = common.ownProp var inflight = __webpack_require__(515) -var util = __webpack_require__(29) +var util = __webpack_require__(397) var childrenIgnored = common.childrenIgnored var isIgnored = common.isIgnored -var once = __webpack_require__(404) +var once = __webpack_require__(378) function glob (pattern, options, cb) { if (typeof options === 'function') cb = options, options = {} @@ -69006,22 +68347,22 @@ Glob.prototype._stat2 = function (f, abs, er, stat, cb) { /***/ }), -/* 592 */ +/* 587 */ /***/ (function(module, exports, __webpack_require__) { try { - var util = __webpack_require__(29); + var util = __webpack_require__(397); /* istanbul ignore next */ if (typeof util.inherits !== 'function') throw ''; module.exports = util.inherits; } catch (e) { /* istanbul ignore next */ - module.exports = __webpack_require__(593); + module.exports = __webpack_require__(588); } /***/ }), -/* 593 */ +/* 588 */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { @@ -69054,22 +68395,22 @@ if (typeof Object.create === 'function') { /***/ }), -/* 594 */ +/* 589 */ /***/ (function(module, exports, __webpack_require__) { module.exports = globSync globSync.GlobSync = GlobSync -var fs = __webpack_require__(23) +var fs = __webpack_require__(349) var rp = __webpack_require__(504) var minimatch = __webpack_require__(506) var Minimatch = minimatch.Minimatch -var Glob = __webpack_require__(591).Glob -var util = __webpack_require__(29) -var path = __webpack_require__(16) -var assert = __webpack_require__(30) +var Glob = __webpack_require__(586).Glob +var util = __webpack_require__(397) +var path = __webpack_require__(4) +var assert = __webpack_require__(371) var isAbsolute = __webpack_require__(512) -var common = __webpack_require__(595) +var common = __webpack_require__(590) var alphasort = common.alphasort var alphasorti = common.alphasorti var setopts = common.setopts @@ -69546,7 +68887,7 @@ GlobSync.prototype._makeAbs = function (f) { /***/ }), -/* 595 */ +/* 590 */ /***/ (function(module, exports, __webpack_require__) { exports.alphasort = alphasort @@ -69563,7 +68904,7 @@ function ownProp (obj, field) { return Object.prototype.hasOwnProperty.call(obj, field) } -var path = __webpack_require__(16) +var path = __webpack_require__(4) var minimatch = __webpack_require__(506) var isAbsolute = __webpack_require__(512) var Minimatch = minimatch.Minimatch @@ -69792,17 +69133,17 @@ function childrenIgnored (self, path) { /***/ }), -/* 596 */ +/* 591 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const taskManager = __webpack_require__(597); -const async_1 = __webpack_require__(625); -const stream_1 = __webpack_require__(658); -const sync_1 = __webpack_require__(659); -const settings_1 = __webpack_require__(661); -const utils = __webpack_require__(598); +const taskManager = __webpack_require__(592); +const async_1 = __webpack_require__(620); +const stream_1 = __webpack_require__(653); +const sync_1 = __webpack_require__(654); +const settings_1 = __webpack_require__(656); +const utils = __webpack_require__(593); function FastGlob(source, options) { try { assertPatternsInput(source); @@ -69860,13 +69201,13 @@ module.exports = FastGlob; /***/ }), -/* 597 */ +/* 592 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(598); +const utils = __webpack_require__(593); function generate(patterns, settings) { const positivePatterns = getPositivePatterns(patterns); const negativePatterns = getNegativePatternsAsPositive(patterns, settings.ignore); @@ -69934,28 +69275,28 @@ exports.convertPatternGroupToTask = convertPatternGroupToTask; /***/ }), -/* 598 */ +/* 593 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const array = __webpack_require__(599); +const array = __webpack_require__(594); exports.array = array; -const errno = __webpack_require__(600); +const errno = __webpack_require__(595); exports.errno = errno; -const fs = __webpack_require__(601); +const fs = __webpack_require__(596); exports.fs = fs; -const path = __webpack_require__(602); +const path = __webpack_require__(597); exports.path = path; -const pattern = __webpack_require__(603); +const pattern = __webpack_require__(598); exports.pattern = pattern; -const stream = __webpack_require__(624); +const stream = __webpack_require__(619); exports.stream = stream; /***/ }), -/* 599 */ +/* 594 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69968,7 +69309,7 @@ exports.flatten = flatten; /***/ }), -/* 600 */ +/* 595 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69981,7 +69322,7 @@ exports.isEnoentCodeError = isEnoentCodeError; /***/ }), -/* 601 */ +/* 596 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -70006,13 +69347,13 @@ exports.createDirentFromStats = createDirentFromStats; /***/ }), -/* 602 */ +/* 597 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(16); +const path = __webpack_require__(4); /** * Designed to work only with simple paths: `dir\\file`. */ @@ -70027,16 +69368,16 @@ exports.makeAbsolute = makeAbsolute; /***/ }), -/* 603 */ +/* 598 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(16); -const globParent = __webpack_require__(604); -const isGlob = __webpack_require__(605); -const micromatch = __webpack_require__(607); +const path = __webpack_require__(4); +const globParent = __webpack_require__(599); +const isGlob = __webpack_require__(600); +const micromatch = __webpack_require__(602); const GLOBSTAR = '**'; function isStaticPattern(pattern) { return !isDynamicPattern(pattern); @@ -70125,15 +69466,15 @@ exports.matchAny = matchAny; /***/ }), -/* 604 */ +/* 599 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isGlob = __webpack_require__(605); -var pathPosixDirname = __webpack_require__(16).posix.dirname; -var isWin32 = __webpack_require__(11).platform() === 'win32'; +var isGlob = __webpack_require__(600); +var pathPosixDirname = __webpack_require__(4).posix.dirname; +var isWin32 = __webpack_require__(364).platform() === 'win32'; var slash = '/'; var backslash = /\\/g; @@ -70166,7 +69507,7 @@ module.exports = function globParent(str) { /***/ }), -/* 605 */ +/* 600 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -70176,7 +69517,7 @@ module.exports = function globParent(str) { * Released under the MIT License. */ -var isExtglob = __webpack_require__(606); +var isExtglob = __webpack_require__(601); var chars = { '{': '}', '(': ')', '[': ']'}; var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; @@ -70220,7 +69561,7 @@ module.exports = function isGlob(str, options) { /***/ }), -/* 606 */ +/* 601 */ /***/ (function(module, exports) { /*! @@ -70246,16 +69587,16 @@ module.exports = function isExtglob(str) { /***/ }), -/* 607 */ +/* 602 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const util = __webpack_require__(29); -const braces = __webpack_require__(608); -const picomatch = __webpack_require__(618); -const utils = __webpack_require__(621); +const util = __webpack_require__(397); +const braces = __webpack_require__(603); +const picomatch = __webpack_require__(613); +const utils = __webpack_require__(616); const isEmptyString = val => typeof val === 'string' && (val === '' || val === './'); /** @@ -70720,16 +70061,16 @@ module.exports = micromatch; /***/ }), -/* 608 */ +/* 603 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const stringify = __webpack_require__(609); -const compile = __webpack_require__(611); -const expand = __webpack_require__(615); -const parse = __webpack_require__(616); +const stringify = __webpack_require__(604); +const compile = __webpack_require__(606); +const expand = __webpack_require__(610); +const parse = __webpack_require__(611); /** * Expand the given pattern or create a regex-compatible string. @@ -70897,13 +70238,13 @@ module.exports = braces; /***/ }), -/* 609 */ +/* 604 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const utils = __webpack_require__(610); +const utils = __webpack_require__(605); module.exports = (ast, options = {}) => { let stringify = (node, parent = {}) => { @@ -70936,7 +70277,7 @@ module.exports = (ast, options = {}) => { /***/ }), -/* 610 */ +/* 605 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -71055,14 +70396,14 @@ exports.flatten = (...args) => { /***/ }), -/* 611 */ +/* 606 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fill = __webpack_require__(612); -const utils = __webpack_require__(610); +const fill = __webpack_require__(607); +const utils = __webpack_require__(605); const compile = (ast, options = {}) => { let walk = (node, parent = {}) => { @@ -71119,7 +70460,7 @@ module.exports = compile; /***/ }), -/* 612 */ +/* 607 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -71132,8 +70473,8 @@ module.exports = compile; -const util = __webpack_require__(29); -const toRegexRange = __webpack_require__(613); +const util = __webpack_require__(397); +const toRegexRange = __webpack_require__(608); const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); @@ -71375,7 +70716,7 @@ module.exports = fill; /***/ }), -/* 613 */ +/* 608 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -71388,7 +70729,7 @@ module.exports = fill; -const isNumber = __webpack_require__(614); +const isNumber = __webpack_require__(609); const toRegexRange = (min, max, options) => { if (isNumber(min) === false) { @@ -71670,7 +71011,7 @@ module.exports = toRegexRange; /***/ }), -/* 614 */ +/* 609 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -71695,15 +71036,15 @@ module.exports = function(num) { /***/ }), -/* 615 */ +/* 610 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fill = __webpack_require__(612); -const stringify = __webpack_require__(609); -const utils = __webpack_require__(610); +const fill = __webpack_require__(607); +const stringify = __webpack_require__(604); +const utils = __webpack_require__(605); const append = (queue = '', stash = '', enclose = false) => { let result = []; @@ -71815,13 +71156,13 @@ module.exports = expand; /***/ }), -/* 616 */ +/* 611 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const stringify = __webpack_require__(609); +const stringify = __webpack_require__(604); /** * Constants @@ -71843,7 +71184,7 @@ const { CHAR_SINGLE_QUOTE, /* ' */ CHAR_NO_BREAK_SPACE, CHAR_ZERO_WIDTH_NOBREAK_SPACE -} = __webpack_require__(617); +} = __webpack_require__(612); /** * parse @@ -72155,7 +71496,7 @@ module.exports = parse; /***/ }), -/* 617 */ +/* 612 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -72219,26 +71560,26 @@ module.exports = { /***/ }), -/* 618 */ +/* 613 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = __webpack_require__(619); +module.exports = __webpack_require__(614); /***/ }), -/* 619 */ +/* 614 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const path = __webpack_require__(16); -const scan = __webpack_require__(620); -const parse = __webpack_require__(623); -const utils = __webpack_require__(621); +const path = __webpack_require__(4); +const scan = __webpack_require__(615); +const parse = __webpack_require__(618); +const utils = __webpack_require__(616); /** * Creates a matcher function from one or more glob patterns. The @@ -72541,7 +71882,7 @@ picomatch.toRegex = (source, options) => { * @return {Object} */ -picomatch.constants = __webpack_require__(622); +picomatch.constants = __webpack_require__(617); /** * Expose "picomatch" @@ -72551,13 +71892,13 @@ module.exports = picomatch; /***/ }), -/* 620 */ +/* 615 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const utils = __webpack_require__(621); +const utils = __webpack_require__(616); const { CHAR_ASTERISK, /* * */ @@ -72575,7 +71916,7 @@ const { CHAR_RIGHT_CURLY_BRACE, /* } */ CHAR_RIGHT_PARENTHESES, /* ) */ CHAR_RIGHT_SQUARE_BRACKET /* ] */ -} = __webpack_require__(622); +} = __webpack_require__(617); const isPathSeparator = code => { return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; @@ -72777,19 +72118,19 @@ module.exports = (input, options) => { /***/ }), -/* 621 */ +/* 616 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const path = __webpack_require__(16); +const path = __webpack_require__(4); const win32 = process.platform === 'win32'; const { REGEX_SPECIAL_CHARS, REGEX_SPECIAL_CHARS_GLOBAL, REGEX_REMOVE_BACKSLASH -} = __webpack_require__(622); +} = __webpack_require__(617); exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); @@ -72827,13 +72168,13 @@ exports.escapeLast = (input, char, lastIdx) => { /***/ }), -/* 622 */ +/* 617 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const path = __webpack_require__(16); +const path = __webpack_require__(4); const WIN_SLASH = '\\\\/'; const WIN_NO_SLASH = `[^${WIN_SLASH}]`; @@ -73013,14 +72354,14 @@ module.exports = { /***/ }), -/* 623 */ +/* 618 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const utils = __webpack_require__(621); -const constants = __webpack_require__(622); +const utils = __webpack_require__(616); +const constants = __webpack_require__(617); /** * Constants @@ -73175,2463 +72516,3370 @@ const parse = (input, options) => { state.consumed += token.value || ''; }; - const increment = type => { - state[type]++; - stack.push(type); - }; + const increment = type => { + state[type]++; + stack.push(type); + }; + + const decrement = type => { + state[type]--; + stack.pop(); + }; + + /** + * Push tokens onto the tokens array. This helper speeds up + * tokenizing by 1) helping us avoid backtracking as much as possible, + * and 2) helping us avoid creating extra tokens when consecutive + * characters are plain text. This improves performance and simplifies + * lookbehinds. + */ + + const push = tok => { + if (prev.type === 'globstar') { + let isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); + let isExtglob = extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'); + if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { + state.output = state.output.slice(0, -prev.output.length); + prev.type = 'star'; + prev.value = '*'; + prev.output = star; + state.output += prev.output; + } + } + + if (extglobs.length && tok.type !== 'paren' && !EXTGLOB_CHARS[tok.value]) { + extglobs[extglobs.length - 1].inner += tok.value; + } + + if (tok.value || tok.output) append(tok); + if (prev && prev.type === 'text' && tok.type === 'text') { + prev.value += tok.value; + return; + } + + tok.prev = prev; + tokens.push(tok); + prev = tok; + }; + + const extglobOpen = (type, value) => { + let token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; + + token.prev = prev; + token.parens = state.parens; + token.output = state.output; + let output = (opts.capture ? '(' : '') + token.open; + + push({ type, value, output: state.output ? '' : ONE_CHAR }); + push({ type: 'paren', extglob: true, value: advance(), output }); + increment('parens'); + extglobs.push(token); + }; + + const extglobClose = token => { + let output = token.close + (opts.capture ? ')' : ''); + + if (token.type === 'negate') { + let extglobStar = star; + + if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { + extglobStar = globstar(opts); + } + + if (extglobStar !== star || eos() || /^\)+$/.test(input.slice(state.index + 1))) { + output = token.close = ')$))' + extglobStar; + } + + if (token.prev.type === 'bos' && eos()) { + state.negatedExtglob = true; + } + } + + push({ type: 'paren', extglob: true, value, output }); + decrement('parens'); + }; + + if (opts.fastpaths !== false && !/(^[*!]|[/{[()\]}"])/.test(input)) { + let backslashes = false; + + let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { + if (first === '\\') { + backslashes = true; + return m; + } + + if (first === '?') { + if (esc) { + return esc + first + (rest ? QMARK.repeat(rest.length) : ''); + } + if (index === 0) { + return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); + } + return QMARK.repeat(chars.length); + } + + if (first === '.') { + return DOT_LITERAL.repeat(chars.length); + } + + if (first === '*') { + if (esc) { + return esc + first + (rest ? star : ''); + } + return star; + } + return esc ? m : '\\' + m; + }); + + if (backslashes === true) { + if (opts.unescape === true) { + output = output.replace(/\\/g, ''); + } else { + output = output.replace(/\\+/g, m => { + return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); + }); + } + } + + state.output = output; + return state; + } + + /** + * Tokenize input until we reach end-of-string + */ + + while (!eos()) { + value = advance(); + + if (value === '\u0000') { + continue; + } + + /** + * Escaped characters + */ + + if (value === '\\') { + let next = peek(); + + if (next === '/' && opts.bash !== true) { + continue; + } + + if (next === '.' || next === ';') { + continue; + } + + if (!next) { + value += '\\'; + push({ type: 'text', value }); + continue; + } + + // collapse slashes to reduce potential for exploits + let match = /^\\+/.exec(input.slice(state.index + 1)); + let slashes = 0; + + if (match && match[0].length > 2) { + slashes = match[0].length; + state.index += slashes; + if (slashes % 2 !== 0) { + value += '\\'; + } + } + + if (opts.unescape === true) { + value = advance() || ''; + } else { + value += advance() || ''; + } + + if (state.brackets === 0) { + push({ type: 'text', value }); + continue; + } + } + + /** + * If we're inside a regex character class, continue + * until we reach the closing bracket. + */ + + if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { + if (opts.posix !== false && value === ':') { + let inner = prev.value.slice(1); + if (inner.includes('[')) { + prev.posix = true; + + if (inner.includes(':')) { + let idx = prev.value.lastIndexOf('['); + let pre = prev.value.slice(0, idx); + let rest = prev.value.slice(idx + 2); + let posix = POSIX_REGEX_SOURCE[rest]; + if (posix) { + prev.value = pre + posix; + state.backtrack = true; + advance(); + + if (!bos.output && tokens.indexOf(prev) === 1) { + bos.output = ONE_CHAR; + } + continue; + } + } + } + } + + if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { + value = '\\' + value; + } + + if (value === ']' && (prev.value === '[' || prev.value === '[^')) { + value = '\\' + value; + } + + if (opts.posix === true && value === '!' && prev.value === '[') { + value = '^'; + } + + prev.value += value; + append({ value }); + continue; + } + + /** + * If we're inside a quoted string, continue + * until we reach the closing double quote. + */ + + if (state.quotes === 1 && value !== '"') { + value = utils.escapeRegex(value); + prev.value += value; + append({ value }); + continue; + } + + /** + * Double quotes + */ + + if (value === '"') { + state.quotes = state.quotes === 1 ? 0 : 1; + if (opts.keepQuotes === true) { + push({ type: 'text', value }); + } + continue; + } + + /** + * Parentheses + */ + + if (value === '(') { + push({ type: 'paren', value }); + increment('parens'); + continue; + } + + if (value === ')') { + if (state.parens === 0 && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '(')); + } + + let extglob = extglobs[extglobs.length - 1]; + if (extglob && state.parens === extglob.parens + 1) { + extglobClose(extglobs.pop()); + continue; + } + + push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); + decrement('parens'); + continue; + } + + /** + * Brackets + */ + + if (value === '[') { + if (opts.nobracket === true || !input.slice(state.index + 1).includes(']')) { + if (opts.nobracket !== true && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('closing', ']')); + } + + value = '\\' + value; + } else { + increment('brackets'); + } + + push({ type: 'bracket', value }); + continue; + } + + if (value === ']') { + if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { + push({ type: 'text', value, output: '\\' + value }); + continue; + } + + if (state.brackets === 0) { + if (opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '[')); + } + + push({ type: 'text', value, output: '\\' + value }); + continue; + } + + decrement('brackets'); + + let prevValue = prev.value.slice(1); + if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { + value = '/' + value; + } + + prev.value += value; + append({ value }); + + // when literal brackets are explicitly disabled + // assume we should match with a regex character class + if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { + continue; + } + + let escaped = utils.escapeRegex(prev.value); + state.output = state.output.slice(0, -prev.value.length); + + // when literal brackets are explicitly enabled + // assume we should escape the brackets to match literal characters + if (opts.literalBrackets === true) { + state.output += escaped; + prev.value = escaped; + continue; + } + + // when the user specifies nothing, try to match both + prev.value = `(${capture}${escaped}|${prev.value})`; + state.output += prev.value; + continue; + } + + /** + * Braces + */ + + if (value === '{' && opts.nobrace !== true) { + push({ type: 'brace', value, output: '(' }); + increment('braces'); + continue; + } + + if (value === '}') { + if (opts.nobrace === true || state.braces === 0) { + push({ type: 'text', value, output: '\\' + value }); + continue; + } + + let output = ')'; + + if (state.dots === true) { + let arr = tokens.slice(); + let range = []; + + for (let i = arr.length - 1; i >= 0; i--) { + tokens.pop(); + if (arr[i].type === 'brace') { + break; + } + if (arr[i].type !== 'dots') { + range.unshift(arr[i].value); + } + } + + output = expandRange(range, opts); + state.backtrack = true; + } + + push({ type: 'brace', value, output }); + decrement('braces'); + continue; + } + + /** + * Pipes + */ + + if (value === '|') { + if (extglobs.length > 0) { + extglobs[extglobs.length - 1].conditions++; + } + push({ type: 'text', value }); + continue; + } - const decrement = type => { - state[type]--; - stack.pop(); - }; + /** + * Commas + */ - /** - * Push tokens onto the tokens array. This helper speeds up - * tokenizing by 1) helping us avoid backtracking as much as possible, - * and 2) helping us avoid creating extra tokens when consecutive - * characters are plain text. This improves performance and simplifies - * lookbehinds. - */ + if (value === ',') { + let output = value; - const push = tok => { - if (prev.type === 'globstar') { - let isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); - let isExtglob = extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'); - if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { - state.output = state.output.slice(0, -prev.output.length); - prev.type = 'star'; - prev.value = '*'; - prev.output = star; - state.output += prev.output; + if (state.braces > 0 && stack[stack.length - 1] === 'braces') { + output = '|'; } - } - if (extglobs.length && tok.type !== 'paren' && !EXTGLOB_CHARS[tok.value]) { - extglobs[extglobs.length - 1].inner += tok.value; + push({ type: 'comma', value, output }); + continue; } - if (tok.value || tok.output) append(tok); - if (prev && prev.type === 'text' && tok.type === 'text') { - prev.value += tok.value; - return; + /** + * Slashes + */ + + if (value === '/') { + // if the beginning of the glob is "./", advance the start + // to the current index, and don't add the "./" characters + // to the state. This greatly simplifies lookbehinds when + // checking for BOS characters like "!" and "." (not "./") + if (prev.type === 'dot' && state.index === 1) { + state.start = state.index + 1; + state.consumed = ''; + state.output = ''; + tokens.pop(); + prev = bos; // reset "prev" to the first token + continue; + } + + push({ type: 'slash', value, output: SLASH_LITERAL }); + continue; } - tok.prev = prev; - tokens.push(tok); - prev = tok; - }; + /** + * Dots + */ - const extglobOpen = (type, value) => { - let token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; + if (value === '.') { + if (state.braces > 0 && prev.type === 'dot') { + if (prev.value === '.') prev.output = DOT_LITERAL; + prev.type = 'dots'; + prev.output += value; + prev.value += value; + state.dots = true; + continue; + } - token.prev = prev; - token.parens = state.parens; - token.output = state.output; - let output = (opts.capture ? '(' : '') + token.open; + push({ type: 'dot', value, output: DOT_LITERAL }); + continue; + } - push({ type, value, output: state.output ? '' : ONE_CHAR }); - push({ type: 'paren', extglob: true, value: advance(), output }); - increment('parens'); - extglobs.push(token); - }; + /** + * Question marks + */ - const extglobClose = token => { - let output = token.close + (opts.capture ? ')' : ''); + if (value === '?') { + if (prev && prev.type === 'paren') { + let next = peek(); + let output = value; - if (token.type === 'negate') { - let extglobStar = star; + if (next === '<' && !utils.supportsLookbehinds()) { + throw new Error('Node.js v10 or higher is required for regex lookbehinds'); + } - if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { - extglobStar = globstar(opts); + if (prev.value === '(' && !/[!=<:]/.test(next) || (next === '<' && !/[!=]/.test(peek(2)))) { + output = '\\' + value; + } + + push({ type: 'text', value, output }); + continue; } - if (extglobStar !== star || eos() || /^\)+$/.test(input.slice(state.index + 1))) { - output = token.close = ')$))' + extglobStar; + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('qmark', value); + continue; } - if (token.prev.type === 'bos' && eos()) { - state.negatedExtglob = true; + if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { + push({ type: 'qmark', value, output: QMARK_NO_DOT }); + continue; } + + push({ type: 'qmark', value, output: QMARK }); + continue; } - push({ type: 'paren', extglob: true, value, output }); - decrement('parens'); - }; + /** + * Exclamation + */ - if (opts.fastpaths !== false && !/(^[*!]|[/{[()\]}"])/.test(input)) { - let backslashes = false; + if (value === '!') { + if (opts.noextglob !== true && peek() === '(') { + if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { + extglobOpen('negate', value); + continue; + } + } - let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { - if (first === '\\') { - backslashes = true; - return m; + if (opts.nonegate !== true && state.index === 0) { + negate(state); + continue; } + } - if (first === '?') { - if (esc) { - return esc + first + (rest ? QMARK.repeat(rest.length) : ''); - } - if (index === 0) { - return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); - } - return QMARK.repeat(chars.length); + /** + * Plus + */ + + if (value === '+') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('plus', value); + continue; } - if (first === '.') { - return DOT_LITERAL.repeat(chars.length); + if (prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) { + let output = prev.extglob === true ? '\\' + value : value; + push({ type: 'plus', value, output }); + continue; } - if (first === '*') { - if (esc) { - return esc + first + (rest ? star : ''); - } - return star; + // use regex behavior inside parens + if (state.parens > 0 && opts.regex !== false) { + push({ type: 'plus', value }); + continue; } - return esc ? m : '\\' + m; - }); - if (backslashes === true) { - if (opts.unescape === true) { - output = output.replace(/\\/g, ''); - } else { - output = output.replace(/\\+/g, m => { - return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); - }); + push({ type: 'plus', value: PLUS_LITERAL }); + continue; + } + + /** + * Plain text + */ + + if (value === '@') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + push({ type: 'at', value, output: '' }); + continue; } + + push({ type: 'text', value }); + continue; } - state.output = output; - return state; - } + /** + * Plain text + */ - /** - * Tokenize input until we reach end-of-string - */ + if (value !== '*') { + if (value === '$' || value === '^') { + value = '\\' + value; + } - while (!eos()) { - value = advance(); + let match = REGEX_NON_SPECIAL_CHAR.exec(input.slice(state.index + 1)); + if (match) { + value += match[0]; + state.index += match[0].length; + } - if (value === '\u0000') { + push({ type: 'text', value }); continue; } /** - * Escaped characters + * Stars */ - if (value === '\\') { - let next = peek(); + if (prev && (prev.type === 'globstar' || prev.star === true)) { + prev.type = 'star'; + prev.star = true; + prev.value += value; + prev.output = star; + state.backtrack = true; + state.consumed += value; + continue; + } - if (next === '/' && opts.bash !== true) { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('star', value); + continue; + } + + if (prev.type === 'star') { + if (opts.noglobstar === true) { + state.consumed += value; continue; } - if (next === '.' || next === ';') { + let prior = prev.prev; + let before = prior.prev; + let isStart = prior.type === 'slash' || prior.type === 'bos'; + let afterStar = before && (before.type === 'star' || before.type === 'globstar'); + + if (opts.bash === true && (!isStart || (!eos() && peek() !== '/'))) { + push({ type: 'star', value, output: '' }); continue; } - if (!next) { - value += '\\'; - push({ type: 'text', value }); + let isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); + let isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); + if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { + push({ type: 'star', value, output: '' }); continue; } - // collapse slashes to reduce potential for exploits - let match = /^\\+/.exec(input.slice(state.index + 1)); - let slashes = 0; - - if (match && match[0].length > 2) { - slashes = match[0].length; - state.index += slashes; - if (slashes % 2 !== 0) { - value += '\\'; + // strip consecutive `/**/` + while (input.slice(state.index + 1, state.index + 4) === '/**') { + let after = input[state.index + 4]; + if (after && after !== '/') { + break; } + state.consumed += '/**'; + state.index += 3; } - if (opts.unescape === true) { - value = advance() || ''; - } else { - value += advance() || ''; + if (prior.type === 'bos' && eos()) { + prev.type = 'globstar'; + prev.value += value; + prev.output = globstar(opts); + state.output = prev.output; + state.consumed += value; + continue; } - if (state.brackets === 0) { - push({ type: 'text', value }); + if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = '(?:' + prior.output; + + prev.type = 'globstar'; + prev.output = globstar(opts) + '|$)'; + prev.value += value; + + state.output += prior.output + prev.output; + state.consumed += value; continue; } - } - /** - * If we're inside a regex character class, continue - * until we reach the closing bracket. - */ + let next = peek(); + if (prior.type === 'slash' && prior.prev.type !== 'bos' && next === '/') { + let end = peek(2) !== void 0 ? '|$' : ''; - if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { - if (opts.posix !== false && value === ':') { - let inner = prev.value.slice(1); - if (inner.includes('[')) { - prev.posix = true; + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = '(?:' + prior.output; - if (inner.includes(':')) { - let idx = prev.value.lastIndexOf('['); - let pre = prev.value.slice(0, idx); - let rest = prev.value.slice(idx + 2); - let posix = POSIX_REGEX_SOURCE[rest]; - if (posix) { - prev.value = pre + posix; - state.backtrack = true; - advance(); + prev.type = 'globstar'; + prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; + prev.value += value; - if (!bos.output && tokens.indexOf(prev) === 1) { - bos.output = ONE_CHAR; - } - continue; - } - } - } + state.output += prior.output + prev.output; + state.consumed += value + advance(); + + push({ type: 'slash', value, output: '' }); + continue; } - if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { - value = '\\' + value; + if (prior.type === 'bos' && next === '/') { + prev.type = 'globstar'; + prev.value += value; + prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; + state.output = prev.output; + state.consumed += value + advance(); + push({ type: 'slash', value, output: '' }); + continue; } - if (value === ']' && (prev.value === '[' || prev.value === '[^')) { - value = '\\' + value; + // remove single star from output + state.output = state.output.slice(0, -prev.output.length); + + // reset previous token to globstar + prev.type = 'globstar'; + prev.output = globstar(opts); + prev.value += value; + + // reset output with globstar + state.output += prev.output; + state.consumed += value; + continue; + } + + let token = { type: 'star', value, output: star }; + + if (opts.bash === true) { + token.output = '.*?'; + if (prev.type === 'bos' || prev.type === 'slash') { + token.output = nodot + token.output; + } + push(token); + continue; + } + + if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { + token.output = value; + push(token); + continue; + } + + if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { + if (prev.type === 'dot') { + state.output += NO_DOT_SLASH; + prev.output += NO_DOT_SLASH; + + } else if (opts.dot === true) { + state.output += NO_DOTS_SLASH; + prev.output += NO_DOTS_SLASH; + + } else { + state.output += nodot; + prev.output += nodot; } - if (opts.posix === true && value === '!' && prev.value === '[') { - value = '^'; + if (peek() !== '*') { + state.output += ONE_CHAR; + prev.output += ONE_CHAR; + } + } + + push(token); + } + + while (state.brackets > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); + state.output = utils.escapeLast(state.output, '['); + decrement('brackets'); + } + + while (state.parens > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); + state.output = utils.escapeLast(state.output, '('); + decrement('parens'); + } + + while (state.braces > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); + state.output = utils.escapeLast(state.output, '{'); + decrement('braces'); + } + + if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { + push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); + } + + // rebuild the output if we had to backtrack at any point + if (state.backtrack === true) { + state.output = ''; + + for (let token of state.tokens) { + state.output += token.output != null ? token.output : token.value; + + if (token.suffix) { + state.output += token.suffix; } + } + } + + return state; +}; + +/** + * Fast paths for creating regular expressions for common glob patterns. + * This can significantly speed up processing and has very little downside + * impact when none of the fast paths match. + */ + +parse.fastpaths = (input, options) => { + let opts = { ...options }; + let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + let len = input.length; + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + } + + input = REPLACEMENTS[input] || input; + let win32 = utils.isWindows(options); + + // create constants based on platform, for windows or posix + const { + DOT_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOTS_SLASH, + STAR, + START_ANCHOR + } = constants.globChars(win32); + + let capture = opts.capture ? '' : '?:'; + let star = opts.bash === true ? '.*?' : STAR; + let nodot = opts.dot ? NO_DOTS : NO_DOT; + let slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; + + if (opts.capture) { + star = `(${star})`; + } + + const globstar = (opts) => { + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; + + const create = str => { + switch (str) { + case '*': + return `${nodot}${ONE_CHAR}${star}`; + + case '.*': + return `${DOT_LITERAL}${ONE_CHAR}${star}`; + + case '*.*': + return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; + + case '*/*': + return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; + + case '**': + return nodot + globstar(opts); + + case '**/*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; - prev.value += value; - append({ value }); - continue; - } + case '**/*.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; - /** - * If we're inside a quoted string, continue - * until we reach the closing double quote. - */ + case '**/.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; - if (state.quotes === 1 && value !== '"') { - value = utils.escapeRegex(value); - prev.value += value; - append({ value }); - continue; - } + default: { + let match = /^(.*?)\.(\w+)$/.exec(str); + if (!match) return; - /** - * Double quotes - */ + let source = create(match[1], options); + if (!source) return; - if (value === '"') { - state.quotes = state.quotes === 1 ? 0 : 1; - if (opts.keepQuotes === true) { - push({ type: 'text', value }); + return source + DOT_LITERAL + match[2]; } - continue; } + }; - /** - * Parentheses - */ + let output = create(input); + if (output && opts.strictSlashes !== true) { + output += `${SLASH_LITERAL}?`; + } - if (value === '(') { - push({ type: 'paren', value }); - increment('parens'); - continue; - } + return output; +}; - if (value === ')') { - if (state.parens === 0 && opts.strictBrackets === true) { - throw new SyntaxError(syntaxError('opening', '(')); - } +module.exports = parse; - let extglob = extglobs[extglobs.length - 1]; - if (extglob && state.parens === extglob.parens + 1) { - extglobClose(extglobs.pop()); - continue; - } - push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); - decrement('parens'); - continue; - } +/***/ }), +/* 619 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Brackets - */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const merge2 = __webpack_require__(585); +function merge(streams) { + const mergedStream = merge2(streams); + streams.forEach((stream) => { + stream.once('error', (err) => mergedStream.emit('error', err)); + }); + return mergedStream; +} +exports.merge = merge; - if (value === '[') { - if (opts.nobracket === true || !input.slice(state.index + 1).includes(']')) { - if (opts.nobracket !== true && opts.strictBrackets === true) { - throw new SyntaxError(syntaxError('closing', ']')); - } - value = '\\' + value; - } else { - increment('brackets'); - } +/***/ }), +/* 620 */ +/***/ (function(module, exports, __webpack_require__) { - push({ type: 'bracket', value }); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = __webpack_require__(621); +const provider_1 = __webpack_require__(648); +class ProviderAsync extends provider_1.default { + constructor() { + super(...arguments); + this._reader = new stream_1.default(this._settings); + } + read(task) { + const root = this._getRootDirectory(task); + const options = this._getReaderOptions(task); + const entries = []; + return new Promise((resolve, reject) => { + const stream = this.api(root, task, options); + stream.once('error', reject); + stream.on('data', (entry) => entries.push(options.transform(entry))); + stream.once('end', () => resolve(entries)); + }); + } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } + return this._reader.static(task.patterns, options); + } +} +exports.default = ProviderAsync; - if (value === ']') { - if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { - push({ type: 'text', value, output: '\\' + value }); - continue; - } - if (state.brackets === 0) { - if (opts.strictBrackets === true) { - throw new SyntaxError(syntaxError('opening', '[')); - } +/***/ }), +/* 621 */ +/***/ (function(module, exports, __webpack_require__) { - push({ type: 'text', value, output: '\\' + value }); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = __webpack_require__(382); +const fsStat = __webpack_require__(622); +const fsWalk = __webpack_require__(627); +const reader_1 = __webpack_require__(647); +class ReaderStream extends reader_1.default { + constructor() { + super(...arguments); + this._walkStream = fsWalk.walkStream; + this._stat = fsStat.stat; + } + dynamic(root, options) { + return this._walkStream(root, options); + } + static(patterns, options) { + const filepaths = patterns.map(this._getFullEntryPath, this); + const stream = new stream_1.PassThrough({ objectMode: true }); + stream._write = (index, _enc, done) => { + return this._getEntry(filepaths[index], patterns[index], options) + .then((entry) => { + if (entry !== null && options.entryFilter(entry)) { + stream.push(entry); + } + if (index === filepaths.length - 1) { + stream.end(); + } + done(); + }) + .catch(done); + }; + for (let i = 0; i < filepaths.length; i++) { + stream.write(i); + } + return stream; + } + _getEntry(filepath, pattern, options) { + return this._getStat(filepath) + .then((stats) => this._makeEntry(stats, pattern)) + .catch((error) => { + if (options.errorFilter(error)) { + return null; + } + throw error; + }); + } + _getStat(filepath) { + return new Promise((resolve, reject) => { + this._stat(filepath, this._fsStatSettings, (error, stats) => { + error ? reject(error) : resolve(stats); + }); + }); + } +} +exports.default = ReaderStream; - decrement('brackets'); - let prevValue = prev.value.slice(1); - if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { - value = '/' + value; - } +/***/ }), +/* 622 */ +/***/ (function(module, exports, __webpack_require__) { - prev.value += value; - append({ value }); +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const async = __webpack_require__(623); +const sync = __webpack_require__(624); +const settings_1 = __webpack_require__(625); +exports.Settings = settings_1.default; +function stat(path, optionsOrSettingsOrCallback, callback) { + if (typeof optionsOrSettingsOrCallback === 'function') { + return async.read(path, getSettings(), optionsOrSettingsOrCallback); + } + async.read(path, getSettings(optionsOrSettingsOrCallback), callback); +} +exports.stat = stat; +function statSync(path, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + return sync.read(path, settings); +} +exports.statSync = statSync; +function getSettings(settingsOrOptions = {}) { + if (settingsOrOptions instanceof settings_1.default) { + return settingsOrOptions; + } + return new settings_1.default(settingsOrOptions); +} - // when literal brackets are explicitly disabled - // assume we should match with a regex character class - if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { - continue; - } - let escaped = utils.escapeRegex(prev.value); - state.output = state.output.slice(0, -prev.value.length); +/***/ }), +/* 623 */ +/***/ (function(module, exports, __webpack_require__) { - // when literal brackets are explicitly enabled - // assume we should escape the brackets to match literal characters - if (opts.literalBrackets === true) { - state.output += escaped; - prev.value = escaped; - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function read(path, settings, callback) { + settings.fs.lstat(path, (lstatError, lstat) => { + if (lstatError) { + return callFailureCallback(callback, lstatError); + } + if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { + return callSuccessCallback(callback, lstat); + } + settings.fs.stat(path, (statError, stat) => { + if (statError) { + if (settings.throwErrorOnBrokenSymbolicLink) { + return callFailureCallback(callback, statError); + } + return callSuccessCallback(callback, lstat); + } + if (settings.markSymbolicLink) { + stat.isSymbolicLink = () => true; + } + callSuccessCallback(callback, stat); + }); + }); +} +exports.read = read; +function callFailureCallback(callback, error) { + callback(error); +} +function callSuccessCallback(callback, result) { + callback(null, result); +} - // when the user specifies nothing, try to match both - prev.value = `(${capture}${escaped}|${prev.value})`; - state.output += prev.value; - continue; - } - /** - * Braces - */ +/***/ }), +/* 624 */ +/***/ (function(module, exports, __webpack_require__) { - if (value === '{' && opts.nobrace !== true) { - push({ type: 'brace', value, output: '(' }); - increment('braces'); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function read(path, settings) { + const lstat = settings.fs.lstatSync(path); + if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { + return lstat; + } + try { + const stat = settings.fs.statSync(path); + if (settings.markSymbolicLink) { + stat.isSymbolicLink = () => true; + } + return stat; + } + catch (error) { + if (!settings.throwErrorOnBrokenSymbolicLink) { + return lstat; + } + throw error; + } +} +exports.read = read; - if (value === '}') { - if (opts.nobrace === true || state.braces === 0) { - push({ type: 'text', value, output: '\\' + value }); - continue; - } - let output = ')'; +/***/ }), +/* 625 */ +/***/ (function(module, exports, __webpack_require__) { - if (state.dots === true) { - let arr = tokens.slice(); - let range = []; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __webpack_require__(626); +class Settings { + constructor(_options = {}) { + this._options = _options; + this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true); + this.fs = fs.createFileSystemAdapter(this._options.fs); + this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); + } + _getValue(option, value) { + return option === undefined ? value : option; + } +} +exports.default = Settings; - for (let i = arr.length - 1; i >= 0; i--) { - tokens.pop(); - if (arr[i].type === 'brace') { - break; - } - if (arr[i].type !== 'dots') { - range.unshift(arr[i].value); - } - } - output = expandRange(range, opts); - state.backtrack = true; - } +/***/ }), +/* 626 */ +/***/ (function(module, exports, __webpack_require__) { - push({ type: 'brace', value, output }); - decrement('braces'); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __webpack_require__(349); +exports.FILE_SYSTEM_ADAPTER = { + lstat: fs.lstat, + stat: fs.stat, + lstatSync: fs.lstatSync, + statSync: fs.statSync +}; +function createFileSystemAdapter(fsMethods) { + if (!fsMethods) { + return exports.FILE_SYSTEM_ADAPTER; + } + return Object.assign({}, exports.FILE_SYSTEM_ADAPTER, fsMethods); +} +exports.createFileSystemAdapter = createFileSystemAdapter; - /** - * Pipes - */ - if (value === '|') { - if (extglobs.length > 0) { - extglobs[extglobs.length - 1].conditions++; - } - push({ type: 'text', value }); - continue; - } +/***/ }), +/* 627 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Commas - */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const async_1 = __webpack_require__(628); +const stream_1 = __webpack_require__(643); +const sync_1 = __webpack_require__(644); +const settings_1 = __webpack_require__(646); +exports.Settings = settings_1.default; +function walk(dir, optionsOrSettingsOrCallback, callback) { + if (typeof optionsOrSettingsOrCallback === 'function') { + return new async_1.default(dir, getSettings()).read(optionsOrSettingsOrCallback); + } + new async_1.default(dir, getSettings(optionsOrSettingsOrCallback)).read(callback); +} +exports.walk = walk; +function walkSync(dir, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + const provider = new sync_1.default(dir, settings); + return provider.read(); +} +exports.walkSync = walkSync; +function walkStream(dir, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + const provider = new stream_1.default(dir, settings); + return provider.read(); +} +exports.walkStream = walkStream; +function getSettings(settingsOrOptions = {}) { + if (settingsOrOptions instanceof settings_1.default) { + return settingsOrOptions; + } + return new settings_1.default(settingsOrOptions); +} - if (value === ',') { - let output = value; - if (state.braces > 0 && stack[stack.length - 1] === 'braces') { - output = '|'; - } +/***/ }), +/* 628 */ +/***/ (function(module, exports, __webpack_require__) { - push({ type: 'comma', value, output }); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const async_1 = __webpack_require__(629); +class AsyncProvider { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._reader = new async_1.default(this._root, this._settings); + this._storage = new Set(); + } + read(callback) { + this._reader.onError((error) => { + callFailureCallback(callback, error); + }); + this._reader.onEntry((entry) => { + this._storage.add(entry); + }); + this._reader.onEnd(() => { + callSuccessCallback(callback, Array.from(this._storage)); + }); + this._reader.read(); + } +} +exports.default = AsyncProvider; +function callFailureCallback(callback, error) { + callback(error); +} +function callSuccessCallback(callback, entries) { + callback(null, entries); +} - /** - * Slashes - */ - if (value === '/') { - // if the beginning of the glob is "./", advance the start - // to the current index, and don't add the "./" characters - // to the state. This greatly simplifies lookbehinds when - // checking for BOS characters like "!" and "." (not "./") - if (prev.type === 'dot' && state.index === 1) { - state.start = state.index + 1; - state.consumed = ''; - state.output = ''; - tokens.pop(); - prev = bos; // reset "prev" to the first token - continue; - } +/***/ }), +/* 629 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const events_1 = __webpack_require__(373); +const fsScandir = __webpack_require__(630); +const fastq = __webpack_require__(639); +const common = __webpack_require__(641); +const reader_1 = __webpack_require__(642); +class AsyncReader extends reader_1.default { + constructor(_root, _settings) { + super(_root, _settings); + this._settings = _settings; + this._scandir = fsScandir.scandir; + this._emitter = new events_1.EventEmitter(); + this._queue = fastq(this._worker.bind(this), this._settings.concurrency); + this._isFatalError = false; + this._isDestroyed = false; + this._queue.drain = () => { + if (!this._isFatalError) { + this._emitter.emit('end'); + } + }; + } + read() { + this._isFatalError = false; + this._isDestroyed = false; + setImmediate(() => { + this._pushToQueue(this._root, this._settings.basePath); + }); + return this._emitter; + } + destroy() { + if (this._isDestroyed) { + throw new Error('The reader is already destroyed'); + } + this._isDestroyed = true; + this._queue.killAndDrain(); + } + onEntry(callback) { + this._emitter.on('entry', callback); + } + onError(callback) { + this._emitter.once('error', callback); + } + onEnd(callback) { + this._emitter.once('end', callback); + } + _pushToQueue(dir, base) { + const queueItem = { dir, base }; + this._queue.push(queueItem, (error) => { + if (error) { + this._handleError(error); + } + }); + } + _worker(item, done) { + this._scandir(item.dir, this._settings.fsScandirSettings, (error, entries) => { + if (error) { + return done(error, undefined); + } + for (const entry of entries) { + this._handleEntry(entry, item.base); + } + done(null, undefined); + }); + } + _handleError(error) { + if (!common.isFatalError(this._settings, error)) { + return; + } + this._isFatalError = true; + this._isDestroyed = true; + this._emitter.emit('error', error); + } + _handleEntry(entry, base) { + if (this._isDestroyed || this._isFatalError) { + return; + } + const fullpath = entry.path; + if (base !== undefined) { + entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); + } + if (common.isAppliedFilter(this._settings.entryFilter, entry)) { + this._emitEntry(entry); + } + if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) { + this._pushToQueue(fullpath, entry.path); + } + } + _emitEntry(entry) { + this._emitter.emit('entry', entry); + } +} +exports.default = AsyncReader; - push({ type: 'slash', value, output: SLASH_LITERAL }); - continue; - } - /** - * Dots - */ +/***/ }), +/* 630 */ +/***/ (function(module, exports, __webpack_require__) { - if (value === '.') { - if (state.braces > 0 && prev.type === 'dot') { - if (prev.value === '.') prev.output = DOT_LITERAL; - prev.type = 'dots'; - prev.output += value; - prev.value += value; - state.dots = true; - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const async = __webpack_require__(631); +const sync = __webpack_require__(636); +const settings_1 = __webpack_require__(637); +exports.Settings = settings_1.default; +function scandir(path, optionsOrSettingsOrCallback, callback) { + if (typeof optionsOrSettingsOrCallback === 'function') { + return async.read(path, getSettings(), optionsOrSettingsOrCallback); + } + async.read(path, getSettings(optionsOrSettingsOrCallback), callback); +} +exports.scandir = scandir; +function scandirSync(path, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + return sync.read(path, settings); +} +exports.scandirSync = scandirSync; +function getSettings(settingsOrOptions = {}) { + if (settingsOrOptions instanceof settings_1.default) { + return settingsOrOptions; + } + return new settings_1.default(settingsOrOptions); +} - push({ type: 'dot', value, output: DOT_LITERAL }); - continue; - } - /** - * Question marks - */ +/***/ }), +/* 631 */ +/***/ (function(module, exports, __webpack_require__) { - if (value === '?') { - if (prev && prev.type === 'paren') { - let next = peek(); - let output = value; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fsStat = __webpack_require__(622); +const rpl = __webpack_require__(632); +const constants_1 = __webpack_require__(633); +const utils = __webpack_require__(634); +function read(dir, settings, callback) { + if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { + return readdirWithFileTypes(dir, settings, callback); + } + return readdir(dir, settings, callback); +} +exports.read = read; +function readdirWithFileTypes(dir, settings, callback) { + settings.fs.readdir(dir, { withFileTypes: true }, (readdirError, dirents) => { + if (readdirError) { + return callFailureCallback(callback, readdirError); + } + const entries = dirents.map((dirent) => ({ + dirent, + name: dirent.name, + path: `${dir}${settings.pathSegmentSeparator}${dirent.name}` + })); + if (!settings.followSymbolicLinks) { + return callSuccessCallback(callback, entries); + } + const tasks = entries.map((entry) => makeRplTaskEntry(entry, settings)); + rpl(tasks, (rplError, rplEntries) => { + if (rplError) { + return callFailureCallback(callback, rplError); + } + callSuccessCallback(callback, rplEntries); + }); + }); +} +exports.readdirWithFileTypes = readdirWithFileTypes; +function makeRplTaskEntry(entry, settings) { + return (done) => { + if (!entry.dirent.isSymbolicLink()) { + return done(null, entry); + } + settings.fs.stat(entry.path, (statError, stats) => { + if (statError) { + if (settings.throwErrorOnBrokenSymbolicLink) { + return done(statError); + } + return done(null, entry); + } + entry.dirent = utils.fs.createDirentFromStats(entry.name, stats); + return done(null, entry); + }); + }; +} +function readdir(dir, settings, callback) { + settings.fs.readdir(dir, (readdirError, names) => { + if (readdirError) { + return callFailureCallback(callback, readdirError); + } + const filepaths = names.map((name) => `${dir}${settings.pathSegmentSeparator}${name}`); + const tasks = filepaths.map((filepath) => { + return (done) => fsStat.stat(filepath, settings.fsStatSettings, done); + }); + rpl(tasks, (rplError, results) => { + if (rplError) { + return callFailureCallback(callback, rplError); + } + const entries = []; + for (let index = 0; index < names.length; index++) { + const name = names[index]; + const stats = results[index]; + const entry = { + name, + path: filepaths[index], + dirent: utils.fs.createDirentFromStats(name, stats) + }; + if (settings.stats) { + entry.stats = stats; + } + entries.push(entry); + } + callSuccessCallback(callback, entries); + }); + }); +} +exports.readdir = readdir; +function callFailureCallback(callback, error) { + callback(error); +} +function callSuccessCallback(callback, result) { + callback(null, result); +} - if (next === '<' && !utils.supportsLookbehinds()) { - throw new Error('Node.js v10 or higher is required for regex lookbehinds'); - } - if (prev.value === '(' && !/[!=<:]/.test(next) || (next === '<' && !/[!=]/.test(peek(2)))) { - output = '\\' + value; - } +/***/ }), +/* 632 */ +/***/ (function(module, exports) { - push({ type: 'text', value, output }); - continue; - } +module.exports = runParallel - if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - extglobOpen('qmark', value); - continue; - } +function runParallel (tasks, cb) { + var results, pending, keys + var isSync = true - if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { - push({ type: 'qmark', value, output: QMARK_NO_DOT }); - continue; - } + if (Array.isArray(tasks)) { + results = [] + pending = tasks.length + } else { + keys = Object.keys(tasks) + results = {} + pending = keys.length + } - push({ type: 'qmark', value, output: QMARK }); - continue; + function done (err) { + function end () { + if (cb) cb(err, results) + cb = null } + if (isSync) process.nextTick(end) + else end() + } - /** - * Exclamation - */ - - if (value === '!') { - if (opts.noextglob !== true && peek() === '(') { - if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { - extglobOpen('negate', value); - continue; - } - } - - if (opts.nonegate !== true && state.index === 0) { - negate(state); - continue; - } + function each (i, err, result) { + results[i] = result + if (--pending === 0 || err) { + done(err) } + } - /** - * Plus - */ - - if (value === '+') { - if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - extglobOpen('plus', value); - continue; - } + if (!pending) { + // empty + done(null) + } else if (keys) { + // object + keys.forEach(function (key) { + tasks[key](function (err, result) { each(key, err, result) }) + }) + } else { + // array + tasks.forEach(function (task, i) { + task(function (err, result) { each(i, err, result) }) + }) + } - if (prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) { - let output = prev.extglob === true ? '\\' + value : value; - push({ type: 'plus', value, output }); - continue; - } + isSync = false +} - // use regex behavior inside parens - if (state.parens > 0 && opts.regex !== false) { - push({ type: 'plus', value }); - continue; - } - push({ type: 'plus', value: PLUS_LITERAL }); - continue; - } +/***/ }), +/* 633 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Plain text - */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.'); +const MAJOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[0], 10); +const MINOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[1], 10); +/** + * IS `true` for Node.js 10.10 and greater. + */ +exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = MAJOR_VERSION > 10 || (MAJOR_VERSION === 10 && MINOR_VERSION >= 10); - if (value === '@') { - if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - push({ type: 'at', value, output: '' }); - continue; - } - push({ type: 'text', value }); - continue; - } +/***/ }), +/* 634 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Plain text - */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __webpack_require__(635); +exports.fs = fs; - if (value !== '*') { - if (value === '$' || value === '^') { - value = '\\' + value; - } - let match = REGEX_NON_SPECIAL_CHAR.exec(input.slice(state.index + 1)); - if (match) { - value += match[0]; - state.index += match[0].length; - } +/***/ }), +/* 635 */ +/***/ (function(module, exports, __webpack_require__) { - push({ type: 'text', value }); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +class DirentFromStats { + constructor(name, stats) { + this.name = name; + this.isBlockDevice = stats.isBlockDevice.bind(stats); + this.isCharacterDevice = stats.isCharacterDevice.bind(stats); + this.isDirectory = stats.isDirectory.bind(stats); + this.isFIFO = stats.isFIFO.bind(stats); + this.isFile = stats.isFile.bind(stats); + this.isSocket = stats.isSocket.bind(stats); + this.isSymbolicLink = stats.isSymbolicLink.bind(stats); + } +} +function createDirentFromStats(name, stats) { + return new DirentFromStats(name, stats); +} +exports.createDirentFromStats = createDirentFromStats; - /** - * Stars - */ - if (prev && (prev.type === 'globstar' || prev.star === true)) { - prev.type = 'star'; - prev.star = true; - prev.value += value; - prev.output = star; - state.backtrack = true; - state.consumed += value; - continue; - } +/***/ }), +/* 636 */ +/***/ (function(module, exports, __webpack_require__) { - if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - extglobOpen('star', value); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fsStat = __webpack_require__(622); +const constants_1 = __webpack_require__(633); +const utils = __webpack_require__(634); +function read(dir, settings) { + if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { + return readdirWithFileTypes(dir, settings); + } + return readdir(dir, settings); +} +exports.read = read; +function readdirWithFileTypes(dir, settings) { + const dirents = settings.fs.readdirSync(dir, { withFileTypes: true }); + return dirents.map((dirent) => { + const entry = { + dirent, + name: dirent.name, + path: `${dir}${settings.pathSegmentSeparator}${dirent.name}` + }; + if (entry.dirent.isSymbolicLink() && settings.followSymbolicLinks) { + try { + const stats = settings.fs.statSync(entry.path); + entry.dirent = utils.fs.createDirentFromStats(entry.name, stats); + } + catch (error) { + if (settings.throwErrorOnBrokenSymbolicLink) { + throw error; + } + } + } + return entry; + }); +} +exports.readdirWithFileTypes = readdirWithFileTypes; +function readdir(dir, settings) { + const names = settings.fs.readdirSync(dir); + return names.map((name) => { + const entryPath = `${dir}${settings.pathSegmentSeparator}${name}`; + const stats = fsStat.statSync(entryPath, settings.fsStatSettings); + const entry = { + name, + path: entryPath, + dirent: utils.fs.createDirentFromStats(name, stats) + }; + if (settings.stats) { + entry.stats = stats; + } + return entry; + }); +} +exports.readdir = readdir; - if (prev.type === 'star') { - if (opts.noglobstar === true) { - state.consumed += value; - continue; - } - let prior = prev.prev; - let before = prior.prev; - let isStart = prior.type === 'slash' || prior.type === 'bos'; - let afterStar = before && (before.type === 'star' || before.type === 'globstar'); +/***/ }), +/* 637 */ +/***/ (function(module, exports, __webpack_require__) { - if (opts.bash === true && (!isStart || (!eos() && peek() !== '/'))) { - push({ type: 'star', value, output: '' }); - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const path = __webpack_require__(4); +const fsStat = __webpack_require__(622); +const fs = __webpack_require__(638); +class Settings { + constructor(_options = {}) { + this._options = _options; + this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false); + this.fs = fs.createFileSystemAdapter(this._options.fs); + this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep); + this.stats = this._getValue(this._options.stats, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); + this.fsStatSettings = new fsStat.Settings({ + followSymbolicLink: this.followSymbolicLinks, + fs: this.fs, + throwErrorOnBrokenSymbolicLink: this.throwErrorOnBrokenSymbolicLink + }); + } + _getValue(option, value) { + return option === undefined ? value : option; + } +} +exports.default = Settings; - let isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); - let isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); - if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { - push({ type: 'star', value, output: '' }); - continue; - } - // strip consecutive `/**/` - while (input.slice(state.index + 1, state.index + 4) === '/**') { - let after = input[state.index + 4]; - if (after && after !== '/') { - break; - } - state.consumed += '/**'; - state.index += 3; - } +/***/ }), +/* 638 */ +/***/ (function(module, exports, __webpack_require__) { - if (prior.type === 'bos' && eos()) { - prev.type = 'globstar'; - prev.value += value; - prev.output = globstar(opts); - state.output = prev.output; - state.consumed += value; - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __webpack_require__(349); +exports.FILE_SYSTEM_ADAPTER = { + lstat: fs.lstat, + stat: fs.stat, + lstatSync: fs.lstatSync, + statSync: fs.statSync, + readdir: fs.readdir, + readdirSync: fs.readdirSync +}; +function createFileSystemAdapter(fsMethods) { + if (!fsMethods) { + return exports.FILE_SYSTEM_ADAPTER; + } + return Object.assign({}, exports.FILE_SYSTEM_ADAPTER, fsMethods); +} +exports.createFileSystemAdapter = createFileSystemAdapter; - if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { - state.output = state.output.slice(0, -(prior.output + prev.output).length); - prior.output = '(?:' + prior.output; - prev.type = 'globstar'; - prev.output = globstar(opts) + '|$)'; - prev.value += value; +/***/ }), +/* 639 */ +/***/ (function(module, exports, __webpack_require__) { - state.output += prior.output + prev.output; - state.consumed += value; - continue; - } +"use strict"; - let next = peek(); - if (prior.type === 'slash' && prior.prev.type !== 'bos' && next === '/') { - let end = peek(2) !== void 0 ? '|$' : ''; - state.output = state.output.slice(0, -(prior.output + prev.output).length); - prior.output = '(?:' + prior.output; +var reusify = __webpack_require__(640) - prev.type = 'globstar'; - prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; - prev.value += value; +function fastqueue (context, worker, concurrency) { + if (typeof context === 'function') { + concurrency = worker + worker = context + context = null + } - state.output += prior.output + prev.output; - state.consumed += value + advance(); + var cache = reusify(Task) + var queueHead = null + var queueTail = null + var _running = 0 - push({ type: 'slash', value, output: '' }); - continue; - } + var self = { + push: push, + drain: noop, + saturated: noop, + pause: pause, + paused: false, + concurrency: concurrency, + running: running, + resume: resume, + idle: idle, + length: length, + unshift: unshift, + empty: noop, + kill: kill, + killAndDrain: killAndDrain + } - if (prior.type === 'bos' && next === '/') { - prev.type = 'globstar'; - prev.value += value; - prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; - state.output = prev.output; - state.consumed += value + advance(); - push({ type: 'slash', value, output: '' }); - continue; - } + return self - // remove single star from output - state.output = state.output.slice(0, -prev.output.length); + function running () { + return _running + } - // reset previous token to globstar - prev.type = 'globstar'; - prev.output = globstar(opts); - prev.value += value; + function pause () { + self.paused = true + } - // reset output with globstar - state.output += prev.output; - state.consumed += value; - continue; + function length () { + var current = queueHead + var counter = 0 + + while (current) { + current = current.next + counter++ } - let token = { type: 'star', value, output: star }; + return counter + } - if (opts.bash === true) { - token.output = '.*?'; - if (prev.type === 'bos' || prev.type === 'slash') { - token.output = nodot + token.output; - } - push(token); - continue; + function resume () { + if (!self.paused) return + self.paused = false + for (var i = 0; i < self.concurrency; i++) { + _running++ + release() } + } - if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { - token.output = value; - push(token); - continue; - } + function idle () { + return _running === 0 && self.length() === 0 + } - if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { - if (prev.type === 'dot') { - state.output += NO_DOT_SLASH; - prev.output += NO_DOT_SLASH; + function push (value, done) { + var current = cache.get() - } else if (opts.dot === true) { - state.output += NO_DOTS_SLASH; - prev.output += NO_DOTS_SLASH; + current.context = context + current.release = release + current.value = value + current.callback = done || noop + if (_running === self.concurrency || self.paused) { + if (queueTail) { + queueTail.next = current + queueTail = current } else { - state.output += nodot; - prev.output += nodot; + queueHead = current + queueTail = current + self.saturated() } + } else { + _running++ + worker.call(context, current.value, current.worked) + } + } - if (peek() !== '*') { - state.output += ONE_CHAR; - prev.output += ONE_CHAR; + function unshift (value, done) { + var current = cache.get() + + current.context = context + current.release = release + current.value = value + current.callback = done || noop + + if (_running === self.concurrency || self.paused) { + if (queueHead) { + current.next = queueHead + queueHead = current + } else { + queueHead = current + queueTail = current + self.saturated() } + } else { + _running++ + worker.call(context, current.value, current.worked) } - - push(token); } - while (state.brackets > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); - state.output = utils.escapeLast(state.output, '['); - decrement('brackets'); + function release (holder) { + if (holder) { + cache.release(holder) + } + var next = queueHead + if (next) { + if (!self.paused) { + if (queueTail === queueHead) { + queueTail = null + } + queueHead = next.next + next.next = null + worker.call(context, next.value, next.worked) + if (queueTail === null) { + self.empty() + } + } else { + _running-- + } + } else if (--_running === 0) { + self.drain() + } } - while (state.parens > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); - state.output = utils.escapeLast(state.output, '('); - decrement('parens'); + function kill () { + queueHead = null + queueTail = null + self.drain = noop } - while (state.braces > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); - state.output = utils.escapeLast(state.output, '{'); - decrement('braces'); + function killAndDrain () { + queueHead = null + queueTail = null + self.drain() + self.drain = noop } +} - if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { - push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); - } +function noop () {} - // rebuild the output if we had to backtrack at any point - if (state.backtrack === true) { - state.output = ''; +function Task () { + this.value = null + this.callback = noop + this.next = null + this.release = noop + this.context = null - for (let token of state.tokens) { - state.output += token.output != null ? token.output : token.value; + var self = this - if (token.suffix) { - state.output += token.suffix; - } - } + this.worked = function worked (err, result) { + var callback = self.callback + self.value = null + self.callback = noop + callback.call(self.context, err, result) + self.release(self) } +} - return state; -}; +module.exports = fastqueue -/** - * Fast paths for creating regular expressions for common glob patterns. - * This can significantly speed up processing and has very little downside - * impact when none of the fast paths match. - */ -parse.fastpaths = (input, options) => { - let opts = { ...options }; - let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; - let len = input.length; - if (len > max) { - throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); - } +/***/ }), +/* 640 */ +/***/ (function(module, exports, __webpack_require__) { - input = REPLACEMENTS[input] || input; - let win32 = utils.isWindows(options); +"use strict"; - // create constants based on platform, for windows or posix - const { - DOT_LITERAL, - SLASH_LITERAL, - ONE_CHAR, - DOTS_SLASH, - NO_DOT, - NO_DOTS, - NO_DOTS_SLASH, - STAR, - START_ANCHOR - } = constants.globChars(win32); - let capture = opts.capture ? '' : '?:'; - let star = opts.bash === true ? '.*?' : STAR; - let nodot = opts.dot ? NO_DOTS : NO_DOT; - let slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; +function reusify (Constructor) { + var head = new Constructor() + var tail = head - if (opts.capture) { - star = `(${star})`; - } + function get () { + var current = head - const globstar = (opts) => { - return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; - }; + if (current.next) { + head = current.next + } else { + head = new Constructor() + tail = head + } - const create = str => { - switch (str) { - case '*': - return `${nodot}${ONE_CHAR}${star}`; + current.next = null - case '.*': - return `${DOT_LITERAL}${ONE_CHAR}${star}`; + return current + } - case '*.*': - return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; + function release (obj) { + tail.next = obj + tail = obj + } - case '*/*': - return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; + return { + get: get, + release: release + } +} - case '**': - return nodot + globstar(opts); +module.exports = reusify - case '**/*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; - case '**/*.*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; +/***/ }), +/* 641 */ +/***/ (function(module, exports, __webpack_require__) { - case '**/.*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function isFatalError(settings, error) { + if (settings.errorFilter === null) { + return true; + } + return !settings.errorFilter(error); +} +exports.isFatalError = isFatalError; +function isAppliedFilter(filter, value) { + return filter === null || filter(value); +} +exports.isAppliedFilter = isAppliedFilter; +function replacePathSegmentSeparator(filepath, separator) { + return filepath.split(/[\\\/]/).join(separator); +} +exports.replacePathSegmentSeparator = replacePathSegmentSeparator; +function joinPathSegments(a, b, separator) { + if (a === '') { + return b; + } + return a + separator + b; +} +exports.joinPathSegments = joinPathSegments; - default: { - let match = /^(.*?)\.(\w+)$/.exec(str); - if (!match) return; - let source = create(match[1], options); - if (!source) return; +/***/ }), +/* 642 */ +/***/ (function(module, exports, __webpack_require__) { - return source + DOT_LITERAL + match[2]; - } - } - }; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const common = __webpack_require__(641); +class Reader { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._root = common.replacePathSegmentSeparator(_root, _settings.pathSegmentSeparator); + } +} +exports.default = Reader; - let output = create(input); - if (output && opts.strictSlashes !== true) { - output += `${SLASH_LITERAL}?`; - } - return output; -}; +/***/ }), +/* 643 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = parse; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = __webpack_require__(382); +const async_1 = __webpack_require__(629); +class StreamProvider { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._reader = new async_1.default(this._root, this._settings); + this._stream = new stream_1.Readable({ + objectMode: true, + read: () => { }, + destroy: this._reader.destroy.bind(this._reader) + }); + } + read() { + this._reader.onError((error) => { + this._stream.emit('error', error); + }); + this._reader.onEntry((entry) => { + this._stream.push(entry); + }); + this._reader.onEnd(() => { + this._stream.push(null); + }); + this._reader.read(); + return this._stream; + } +} +exports.default = StreamProvider; /***/ }), -/* 624 */ +/* 644 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const merge2 = __webpack_require__(590); -function merge(streams) { - const mergedStream = merge2(streams); - streams.forEach((stream) => { - stream.once('error', (err) => mergedStream.emit('error', err)); - }); - return mergedStream; +const sync_1 = __webpack_require__(645); +class SyncProvider { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._reader = new sync_1.default(this._root, this._settings); + } + read() { + return this._reader.read(); + } } -exports.merge = merge; +exports.default = SyncProvider; /***/ }), -/* 625 */ +/* 645 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(626); -const provider_1 = __webpack_require__(653); -class ProviderAsync extends provider_1.default { +const fsScandir = __webpack_require__(630); +const common = __webpack_require__(641); +const reader_1 = __webpack_require__(642); +class SyncReader extends reader_1.default { constructor() { super(...arguments); - this._reader = new stream_1.default(this._settings); + this._scandir = fsScandir.scandirSync; + this._storage = new Set(); + this._queue = new Set(); } - read(task) { - const root = this._getRootDirectory(task); - const options = this._getReaderOptions(task); - const entries = []; - return new Promise((resolve, reject) => { - const stream = this.api(root, task, options); - stream.once('error', reject); - stream.on('data', (entry) => entries.push(options.transform(entry))); - stream.once('end', () => resolve(entries)); + read() { + this._pushToQueue(this._root, this._settings.basePath); + this._handleQueue(); + return Array.from(this._storage); + } + _pushToQueue(dir, base) { + this._queue.add({ dir, base }); + } + _handleQueue() { + for (const item of this._queue.values()) { + this._handleDirectory(item.dir, item.base); + } + } + _handleDirectory(dir, base) { + try { + const entries = this._scandir(dir, this._settings.fsScandirSettings); + for (const entry of entries) { + this._handleEntry(entry, base); + } + } + catch (error) { + this._handleError(error); + } + } + _handleError(error) { + if (!common.isFatalError(this._settings, error)) { + return; + } + throw error; + } + _handleEntry(entry, base) { + const fullpath = entry.path; + if (base !== undefined) { + entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); + } + if (common.isAppliedFilter(this._settings.entryFilter, entry)) { + this._pushToStorage(entry); + } + if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) { + this._pushToQueue(fullpath, entry.path); + } + } + _pushToStorage(entry) { + this._storage.add(entry); + } +} +exports.default = SyncReader; + + +/***/ }), +/* 646 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const path = __webpack_require__(4); +const fsScandir = __webpack_require__(630); +class Settings { + constructor(_options = {}) { + this._options = _options; + this.basePath = this._getValue(this._options.basePath, undefined); + this.concurrency = this._getValue(this._options.concurrency, Infinity); + this.deepFilter = this._getValue(this._options.deepFilter, null); + this.entryFilter = this._getValue(this._options.entryFilter, null); + this.errorFilter = this._getValue(this._options.errorFilter, null); + this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep); + this.fsScandirSettings = new fsScandir.Settings({ + followSymbolicLinks: this._options.followSymbolicLinks, + fs: this._options.fs, + pathSegmentSeparator: this._options.pathSegmentSeparator, + stats: this._options.stats, + throwErrorOnBrokenSymbolicLink: this._options.throwErrorOnBrokenSymbolicLink }); } - api(root, task, options) { - if (task.dynamic) { - return this._reader.dynamic(root, options); - } - return this._reader.static(task.patterns, options); + _getValue(option, value) { + return option === undefined ? value : option; } } -exports.default = ProviderAsync; +exports.default = Settings; /***/ }), -/* 626 */ +/* 647 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(27); -const fsStat = __webpack_require__(627); -const fsWalk = __webpack_require__(632); -const reader_1 = __webpack_require__(652); -class ReaderStream extends reader_1.default { - constructor() { - super(...arguments); - this._walkStream = fsWalk.walkStream; - this._stat = fsStat.stat; +const path = __webpack_require__(4); +const fsStat = __webpack_require__(622); +const utils = __webpack_require__(593); +class Reader { + constructor(_settings) { + this._settings = _settings; + this._fsStatSettings = new fsStat.Settings({ + followSymbolicLink: this._settings.followSymbolicLinks, + fs: this._settings.fs, + throwErrorOnBrokenSymbolicLink: this._settings.followSymbolicLinks + }); } - dynamic(root, options) { - return this._walkStream(root, options); + _getFullEntryPath(filepath) { + return path.resolve(this._settings.cwd, filepath); } - static(patterns, options) { - const filepaths = patterns.map(this._getFullEntryPath, this); - const stream = new stream_1.PassThrough({ objectMode: true }); - stream._write = (index, _enc, done) => { - return this._getEntry(filepaths[index], patterns[index], options) - .then((entry) => { - if (entry !== null && options.entryFilter(entry)) { - stream.push(entry); - } - if (index === filepaths.length - 1) { - stream.end(); - } - done(); - }) - .catch(done); + _makeEntry(stats, pattern) { + const entry = { + name: pattern, + path: pattern, + dirent: utils.fs.createDirentFromStats(pattern, stats) }; - for (let i = 0; i < filepaths.length; i++) { - stream.write(i); + if (this._settings.stats) { + entry.stats = stats; } - return stream; - } - _getEntry(filepath, pattern, options) { - return this._getStat(filepath) - .then((stats) => this._makeEntry(stats, pattern)) - .catch((error) => { - if (options.errorFilter(error)) { - return null; - } - throw error; - }); + return entry; } - _getStat(filepath) { - return new Promise((resolve, reject) => { - this._stat(filepath, this._fsStatSettings, (error, stats) => { - error ? reject(error) : resolve(stats); - }); - }); + _isFatalError(error) { + return !utils.errno.isEnoentCodeError(error) && !this._settings.suppressErrors; } } -exports.default = ReaderStream; +exports.default = Reader; /***/ }), -/* 627 */ +/* 648 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async = __webpack_require__(628); -const sync = __webpack_require__(629); -const settings_1 = __webpack_require__(630); -exports.Settings = settings_1.default; -function stat(path, optionsOrSettingsOrCallback, callback) { - if (typeof optionsOrSettingsOrCallback === 'function') { - return async.read(path, getSettings(), optionsOrSettingsOrCallback); +const path = __webpack_require__(4); +const deep_1 = __webpack_require__(649); +const entry_1 = __webpack_require__(650); +const error_1 = __webpack_require__(651); +const entry_2 = __webpack_require__(652); +class Provider { + constructor(_settings) { + this._settings = _settings; + this.errorFilter = new error_1.default(this._settings); + this.entryFilter = new entry_1.default(this._settings, this._getMicromatchOptions()); + this.deepFilter = new deep_1.default(this._settings, this._getMicromatchOptions()); + this.entryTransformer = new entry_2.default(this._settings); } - async.read(path, getSettings(optionsOrSettingsOrCallback), callback); -} -exports.stat = stat; -function statSync(path, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - return sync.read(path, settings); -} -exports.statSync = statSync; -function getSettings(settingsOrOptions = {}) { - if (settingsOrOptions instanceof settings_1.default) { - return settingsOrOptions; + _getRootDirectory(task) { + return path.resolve(this._settings.cwd, task.base); + } + _getReaderOptions(task) { + const basePath = task.base === '.' ? '' : task.base; + return { + basePath, + pathSegmentSeparator: '/', + concurrency: this._settings.concurrency, + deepFilter: this.deepFilter.getFilter(basePath, task.positive, task.negative), + entryFilter: this.entryFilter.getFilter(task.positive, task.negative), + errorFilter: this.errorFilter.getFilter(), + followSymbolicLinks: this._settings.followSymbolicLinks, + fs: this._settings.fs, + stats: this._settings.stats, + throwErrorOnBrokenSymbolicLink: this._settings.throwErrorOnBrokenSymbolicLink, + transform: this.entryTransformer.getTransformer() + }; + } + _getMicromatchOptions() { + return { + dot: this._settings.dot, + matchBase: this._settings.baseNameMatch, + nobrace: !this._settings.braceExpansion, + nocase: !this._settings.caseSensitiveMatch, + noext: !this._settings.extglob, + noglobstar: !this._settings.globstar, + posix: true, + strictSlashes: false + }; } - return new settings_1.default(settingsOrOptions); } +exports.default = Provider; /***/ }), -/* 628 */ +/* 649 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -function read(path, settings, callback) { - settings.fs.lstat(path, (lstatError, lstat) => { - if (lstatError) { - return callFailureCallback(callback, lstatError); +const utils = __webpack_require__(593); +class DeepFilter { + constructor(_settings, _micromatchOptions) { + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; + } + getFilter(basePath, positive, negative) { + const maxPatternDepth = this._getMaxPatternDepth(positive); + const negativeRe = this._getNegativePatternsRe(negative); + return (entry) => this._filter(basePath, entry, negativeRe, maxPatternDepth); + } + _getMaxPatternDepth(patterns) { + const globstar = patterns.some(utils.pattern.hasGlobStar); + return globstar ? Infinity : utils.pattern.getMaxNaivePatternsDepth(patterns); + } + _getNegativePatternsRe(patterns) { + const affectDepthOfReadingPatterns = patterns.filter(utils.pattern.isAffectDepthOfReadingPattern); + return utils.pattern.convertPatternsToRe(affectDepthOfReadingPatterns, this._micromatchOptions); + } + _filter(basePath, entry, negativeRe, maxPatternDepth) { + const depth = this._getEntryDepth(basePath, entry.path); + if (this._isSkippedByDeep(depth)) { + return false; } - if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { - return callSuccessCallback(callback, lstat); + if (this._isSkippedByMaxPatternDepth(depth, maxPatternDepth)) { + return false; } - settings.fs.stat(path, (statError, stat) => { - if (statError) { - if (settings.throwErrorOnBrokenSymbolicLink) { - return callFailureCallback(callback, statError); - } - return callSuccessCallback(callback, lstat); - } - if (settings.markSymbolicLink) { - stat.isSymbolicLink = () => true; - } - callSuccessCallback(callback, stat); - }); - }); -} -exports.read = read; -function callFailureCallback(callback, error) { - callback(error); -} -function callSuccessCallback(callback, result) { - callback(null, result); + if (this._isSkippedSymbolicLink(entry)) { + return false; + } + if (this._isSkippedDotDirectory(entry)) { + return false; + } + return this._isSkippedByNegativePatterns(entry, negativeRe); + } + _getEntryDepth(basePath, entryPath) { + const basePathDepth = basePath.split('/').length; + const entryPathDepth = entryPath.split('/').length; + return entryPathDepth - (basePath === '' ? 0 : basePathDepth); + } + _isSkippedByDeep(entryDepth) { + return entryDepth >= this._settings.deep; + } + _isSkippedByMaxPatternDepth(entryDepth, maxPatternDepth) { + return !this._settings.baseNameMatch && maxPatternDepth !== Infinity && entryDepth > maxPatternDepth; + } + _isSkippedSymbolicLink(entry) { + return !this._settings.followSymbolicLinks && entry.dirent.isSymbolicLink(); + } + _isSkippedDotDirectory(entry) { + return !this._settings.dot && entry.name.startsWith('.'); + } + _isSkippedByNegativePatterns(entry, negativeRe) { + return !utils.pattern.matchAny(entry.path, negativeRe); + } } +exports.default = DeepFilter; /***/ }), -/* 629 */ +/* 650 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -function read(path, settings) { - const lstat = settings.fs.lstatSync(path); - if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { - return lstat; +const utils = __webpack_require__(593); +class EntryFilter { + constructor(_settings, _micromatchOptions) { + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; + this.index = new Map(); } - try { - const stat = settings.fs.statSync(path); - if (settings.markSymbolicLink) { - stat.isSymbolicLink = () => true; + getFilter(positive, negative) { + const positiveRe = utils.pattern.convertPatternsToRe(positive, this._micromatchOptions); + const negativeRe = utils.pattern.convertPatternsToRe(negative, this._micromatchOptions); + return (entry) => this._filter(entry, positiveRe, negativeRe); + } + _filter(entry, positiveRe, negativeRe) { + if (this._settings.unique) { + if (this._isDuplicateEntry(entry)) { + return false; + } + this._createIndexRecord(entry); } - return stat; + if (this._onlyFileFilter(entry) || this._onlyDirectoryFilter(entry)) { + return false; + } + if (this._isSkippedByAbsoluteNegativePatterns(entry, negativeRe)) { + return false; + } + const filepath = this._settings.baseNameMatch ? entry.name : entry.path; + return this._isMatchToPatterns(filepath, positiveRe) && !this._isMatchToPatterns(entry.path, negativeRe); } - catch (error) { - if (!settings.throwErrorOnBrokenSymbolicLink) { - return lstat; + _isDuplicateEntry(entry) { + return this.index.has(entry.path); + } + _createIndexRecord(entry) { + this.index.set(entry.path, undefined); + } + _onlyFileFilter(entry) { + return this._settings.onlyFiles && !entry.dirent.isFile(); + } + _onlyDirectoryFilter(entry) { + return this._settings.onlyDirectories && !entry.dirent.isDirectory(); + } + _isSkippedByAbsoluteNegativePatterns(entry, negativeRe) { + if (!this._settings.absolute) { + return false; } - throw error; + const fullpath = utils.path.makeAbsolute(this._settings.cwd, entry.path); + return this._isMatchToPatterns(fullpath, negativeRe); + } + _isMatchToPatterns(filepath, patternsRe) { + return utils.pattern.matchAny(filepath, patternsRe); } } -exports.read = read; +exports.default = EntryFilter; /***/ }), -/* 630 */ +/* 651 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(631); -class Settings { - constructor(_options = {}) { - this._options = _options; - this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true); - this.fs = fs.createFileSystemAdapter(this._options.fs); - this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false); - this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); +const utils = __webpack_require__(593); +class ErrorFilter { + constructor(_settings) { + this._settings = _settings; } - _getValue(option, value) { - return option === undefined ? value : option; + getFilter() { + return (error) => this._isNonFatalError(error); + } + _isNonFatalError(error) { + return utils.errno.isEnoentCodeError(error) || this._settings.suppressErrors; } } -exports.default = Settings; +exports.default = ErrorFilter; /***/ }), -/* 631 */ +/* 652 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(23); -exports.FILE_SYSTEM_ADAPTER = { - lstat: fs.lstat, - stat: fs.stat, - lstatSync: fs.lstatSync, - statSync: fs.statSync -}; -function createFileSystemAdapter(fsMethods) { - if (!fsMethods) { - return exports.FILE_SYSTEM_ADAPTER; +const utils = __webpack_require__(593); +class EntryTransformer { + constructor(_settings) { + this._settings = _settings; + } + getTransformer() { + return (entry) => this._transform(entry); + } + _transform(entry) { + let filepath = entry.path; + if (this._settings.absolute) { + filepath = utils.path.makeAbsolute(this._settings.cwd, filepath); + filepath = utils.path.unixify(filepath); + } + if (this._settings.markDirectories && entry.dirent.isDirectory()) { + filepath += '/'; + } + if (!this._settings.objectMode) { + return filepath; + } + return Object.assign({}, entry, { path: filepath }); } - return Object.assign({}, exports.FILE_SYSTEM_ADAPTER, fsMethods); } -exports.createFileSystemAdapter = createFileSystemAdapter; +exports.default = EntryTransformer; /***/ }), -/* 632 */ +/* 653 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async_1 = __webpack_require__(633); -const stream_1 = __webpack_require__(648); -const sync_1 = __webpack_require__(649); -const settings_1 = __webpack_require__(651); -exports.Settings = settings_1.default; -function walk(dir, optionsOrSettingsOrCallback, callback) { - if (typeof optionsOrSettingsOrCallback === 'function') { - return new async_1.default(dir, getSettings()).read(optionsOrSettingsOrCallback); +const stream_1 = __webpack_require__(382); +const stream_2 = __webpack_require__(621); +const provider_1 = __webpack_require__(648); +class ProviderStream extends provider_1.default { + constructor() { + super(...arguments); + this._reader = new stream_2.default(this._settings); } - new async_1.default(dir, getSettings(optionsOrSettingsOrCallback)).read(callback); -} -exports.walk = walk; -function walkSync(dir, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - const provider = new sync_1.default(dir, settings); - return provider.read(); -} -exports.walkSync = walkSync; -function walkStream(dir, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - const provider = new stream_1.default(dir, settings); - return provider.read(); -} -exports.walkStream = walkStream; -function getSettings(settingsOrOptions = {}) { - if (settingsOrOptions instanceof settings_1.default) { - return settingsOrOptions; + read(task) { + const root = this._getRootDirectory(task); + const options = this._getReaderOptions(task); + const source = this.api(root, task, options); + const dest = new stream_1.Readable({ objectMode: true, read: () => { } }); + source + .once('error', (error) => dest.emit('error', error)) + .on('data', (entry) => dest.emit('data', options.transform(entry))) + .once('end', () => dest.emit('end')); + return dest; + } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } + return this._reader.static(task.patterns, options); } - return new settings_1.default(settingsOrOptions); } +exports.default = ProviderStream; /***/ }), -/* 633 */ +/* 654 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async_1 = __webpack_require__(634); -class AsyncProvider { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._reader = new async_1.default(this._root, this._settings); - this._storage = new Set(); +const sync_1 = __webpack_require__(655); +const provider_1 = __webpack_require__(648); +class ProviderSync extends provider_1.default { + constructor() { + super(...arguments); + this._reader = new sync_1.default(this._settings); } - read(callback) { - this._reader.onError((error) => { - callFailureCallback(callback, error); - }); - this._reader.onEntry((entry) => { - this._storage.add(entry); - }); - this._reader.onEnd(() => { - callSuccessCallback(callback, Array.from(this._storage)); - }); - this._reader.read(); + read(task) { + const root = this._getRootDirectory(task); + const options = this._getReaderOptions(task); + const entries = this.api(root, task, options); + return entries.map(options.transform); + } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } + return this._reader.static(task.patterns, options); } } -exports.default = AsyncProvider; -function callFailureCallback(callback, error) { - callback(error); -} -function callSuccessCallback(callback, entries) { - callback(null, entries); -} +exports.default = ProviderSync; /***/ }), -/* 634 */ +/* 655 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const events_1 = __webpack_require__(399); -const fsScandir = __webpack_require__(635); -const fastq = __webpack_require__(644); -const common = __webpack_require__(646); +const fsStat = __webpack_require__(622); +const fsWalk = __webpack_require__(627); const reader_1 = __webpack_require__(647); -class AsyncReader extends reader_1.default { - constructor(_root, _settings) { - super(_root, _settings); - this._settings = _settings; - this._scandir = fsScandir.scandir; - this._emitter = new events_1.EventEmitter(); - this._queue = fastq(this._worker.bind(this), this._settings.concurrency); - this._isFatalError = false; - this._isDestroyed = false; - this._queue.drain = () => { - if (!this._isFatalError) { - this._emitter.emit('end'); - } - }; - } - read() { - this._isFatalError = false; - this._isDestroyed = false; - setImmediate(() => { - this._pushToQueue(this._root, this._settings.basePath); - }); - return this._emitter; - } - destroy() { - if (this._isDestroyed) { - throw new Error('The reader is already destroyed'); - } - this._isDestroyed = true; - this._queue.killAndDrain(); - } - onEntry(callback) { - this._emitter.on('entry', callback); - } - onError(callback) { - this._emitter.once('error', callback); - } - onEnd(callback) { - this._emitter.once('end', callback); +class ReaderSync extends reader_1.default { + constructor() { + super(...arguments); + this._walkSync = fsWalk.walkSync; + this._statSync = fsStat.statSync; } - _pushToQueue(dir, base) { - const queueItem = { dir, base }; - this._queue.push(queueItem, (error) => { - if (error) { - this._handleError(error); - } - }); + dynamic(root, options) { + return this._walkSync(root, options); } - _worker(item, done) { - this._scandir(item.dir, this._settings.fsScandirSettings, (error, entries) => { - if (error) { - return done(error, undefined); - } - for (const entry of entries) { - this._handleEntry(entry, item.base); + static(patterns, options) { + const entries = []; + for (const pattern of patterns) { + const filepath = this._getFullEntryPath(pattern); + const entry = this._getEntry(filepath, pattern, options); + if (entry === null || !options.entryFilter(entry)) { + continue; } - done(null, undefined); - }); - } - _handleError(error) { - if (!common.isFatalError(this._settings, error)) { - return; - } - this._isFatalError = true; - this._isDestroyed = true; - this._emitter.emit('error', error); - } - _handleEntry(entry, base) { - if (this._isDestroyed || this._isFatalError) { - return; - } - const fullpath = entry.path; - if (base !== undefined) { - entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); + entries.push(entry); } - if (common.isAppliedFilter(this._settings.entryFilter, entry)) { - this._emitEntry(entry); + return entries; + } + _getEntry(filepath, pattern, options) { + try { + const stats = this._getStat(filepath); + return this._makeEntry(stats, pattern); } - if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) { - this._pushToQueue(fullpath, entry.path); + catch (error) { + if (options.errorFilter(error)) { + return null; + } + throw error; } } - _emitEntry(entry) { - this._emitter.emit('entry', entry); + _getStat(filepath) { + return this._statSync(filepath, this._fsStatSettings); } } -exports.default = AsyncReader; +exports.default = ReaderSync; /***/ }), -/* 635 */ +/* 656 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async = __webpack_require__(636); -const sync = __webpack_require__(641); -const settings_1 = __webpack_require__(642); -exports.Settings = settings_1.default; -function scandir(path, optionsOrSettingsOrCallback, callback) { - if (typeof optionsOrSettingsOrCallback === 'function') { - return async.read(path, getSettings(), optionsOrSettingsOrCallback); +const fs = __webpack_require__(349); +const os = __webpack_require__(364); +const CPU_COUNT = os.cpus().length; +exports.DEFAULT_FILE_SYSTEM_ADAPTER = { + lstat: fs.lstat, + lstatSync: fs.lstatSync, + stat: fs.stat, + statSync: fs.statSync, + readdir: fs.readdir, + readdirSync: fs.readdirSync +}; +// tslint:enable no-redundant-jsdoc +class Settings { + constructor(_options = {}) { + this._options = _options; + this.absolute = this._getValue(this._options.absolute, false); + this.baseNameMatch = this._getValue(this._options.baseNameMatch, false); + this.braceExpansion = this._getValue(this._options.braceExpansion, true); + this.caseSensitiveMatch = this._getValue(this._options.caseSensitiveMatch, true); + this.concurrency = this._getValue(this._options.concurrency, CPU_COUNT); + this.cwd = this._getValue(this._options.cwd, process.cwd()); + this.deep = this._getValue(this._options.deep, Infinity); + this.dot = this._getValue(this._options.dot, false); + this.extglob = this._getValue(this._options.extglob, true); + this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, true); + this.fs = this._getFileSystemMethods(this._options.fs); + this.globstar = this._getValue(this._options.globstar, true); + this.ignore = this._getValue(this._options.ignore, []); + this.markDirectories = this._getValue(this._options.markDirectories, false); + this.objectMode = this._getValue(this._options.objectMode, false); + this.onlyDirectories = this._getValue(this._options.onlyDirectories, false); + this.onlyFiles = this._getValue(this._options.onlyFiles, true); + this.stats = this._getValue(this._options.stats, false); + this.suppressErrors = this._getValue(this._options.suppressErrors, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, false); + this.unique = this._getValue(this._options.unique, true); + if (this.onlyDirectories) { + this.onlyFiles = false; + } + if (this.stats) { + this.objectMode = true; + } } - async.read(path, getSettings(optionsOrSettingsOrCallback), callback); -} -exports.scandir = scandir; -function scandirSync(path, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - return sync.read(path, settings); -} -exports.scandirSync = scandirSync; -function getSettings(settingsOrOptions = {}) { - if (settingsOrOptions instanceof settings_1.default) { - return settingsOrOptions; + _getValue(option, value) { + return option === undefined ? value : option; + } + _getFileSystemMethods(methods = {}) { + return Object.assign({}, exports.DEFAULT_FILE_SYSTEM_ADAPTER, methods); } - return new settings_1.default(settingsOrOptions); } +exports.default = Settings; /***/ }), -/* 636 */ +/* 657 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(627); -const rpl = __webpack_require__(637); -const constants_1 = __webpack_require__(638); -const utils = __webpack_require__(639); -function read(dir, settings, callback) { - if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { - return readdirWithFileTypes(dir, settings, callback); - } - return readdir(dir, settings, callback); -} -exports.read = read; -function readdirWithFileTypes(dir, settings, callback) { - settings.fs.readdir(dir, { withFileTypes: true }, (readdirError, dirents) => { - if (readdirError) { - return callFailureCallback(callback, readdirError); - } - const entries = dirents.map((dirent) => ({ - dirent, - name: dirent.name, - path: `${dir}${settings.pathSegmentSeparator}${dirent.name}` - })); - if (!settings.followSymbolicLinks) { - return callSuccessCallback(callback, entries); - } - const tasks = entries.map((entry) => makeRplTaskEntry(entry, settings)); - rpl(tasks, (rplError, rplEntries) => { - if (rplError) { - return callFailureCallback(callback, rplError); - } - callSuccessCallback(callback, rplEntries); - }); - }); -} -exports.readdirWithFileTypes = readdirWithFileTypes; -function makeRplTaskEntry(entry, settings) { - return (done) => { - if (!entry.dirent.isSymbolicLink()) { - return done(null, entry); - } - settings.fs.stat(entry.path, (statError, stats) => { - if (statError) { - if (settings.throwErrorOnBrokenSymbolicLink) { - return done(statError); - } - return done(null, entry); - } - entry.dirent = utils.fs.createDirentFromStats(entry.name, stats); - return done(null, entry); - }); - }; -} -function readdir(dir, settings, callback) { - settings.fs.readdir(dir, (readdirError, names) => { - if (readdirError) { - return callFailureCallback(callback, readdirError); - } - const filepaths = names.map((name) => `${dir}${settings.pathSegmentSeparator}${name}`); - const tasks = filepaths.map((filepath) => { - return (done) => fsStat.stat(filepath, settings.fsStatSettings, done); - }); - rpl(tasks, (rplError, results) => { - if (rplError) { - return callFailureCallback(callback, rplError); - } - const entries = []; - for (let index = 0; index < names.length; index++) { - const name = names[index]; - const stats = results[index]; - const entry = { - name, - path: filepaths[index], - dirent: utils.fs.createDirentFromStats(name, stats) - }; - if (settings.stats) { - entry.stats = stats; - } - entries.push(entry); - } - callSuccessCallback(callback, entries); - }); - }); -} -exports.readdir = readdir; -function callFailureCallback(callback, error) { - callback(error); -} -function callSuccessCallback(callback, result) { - callback(null, result); -} +const path = __webpack_require__(4); +const pathType = __webpack_require__(658); -/***/ }), -/* 637 */ -/***/ (function(module, exports) { +const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; -module.exports = runParallel +const getPath = (filepath, cwd) => { + const pth = filepath[0] === '!' ? filepath.slice(1) : filepath; + return path.isAbsolute(pth) ? pth : path.join(cwd, pth); +}; -function runParallel (tasks, cb) { - var results, pending, keys - var isSync = true +const addExtensions = (file, extensions) => { + if (path.extname(file)) { + return `**/${file}`; + } - if (Array.isArray(tasks)) { - results = [] - pending = tasks.length - } else { - keys = Object.keys(tasks) - results = {} - pending = keys.length - } + return `**/${file}.${getExtensions(extensions)}`; +}; - function done (err) { - function end () { - if (cb) cb(err, results) - cb = null - } - if (isSync) process.nextTick(end) - else end() - } +const getGlob = (directory, options) => { + if (options.files && !Array.isArray(options.files)) { + throw new TypeError(`Expected \`files\` to be of type \`Array\` but received type \`${typeof options.files}\``); + } - function each (i, err, result) { - results[i] = result - if (--pending === 0 || err) { - done(err) - } - } + if (options.extensions && !Array.isArray(options.extensions)) { + throw new TypeError(`Expected \`extensions\` to be of type \`Array\` but received type \`${typeof options.extensions}\``); + } - if (!pending) { - // empty - done(null) - } else if (keys) { - // object - keys.forEach(function (key) { - tasks[key](function (err, result) { each(key, err, result) }) - }) - } else { - // array - tasks.forEach(function (task, i) { - task(function (err, result) { each(i, err, result) }) - }) - } + if (options.files && options.extensions) { + return options.files.map(x => path.posix.join(directory, addExtensions(x, options.extensions))); + } - isSync = false -} + if (options.files) { + return options.files.map(x => path.posix.join(directory, `**/${x}`)); + } + if (options.extensions) { + return [path.posix.join(directory, `**/*.${getExtensions(options.extensions)}`)]; + } -/***/ }), -/* 638 */ -/***/ (function(module, exports, __webpack_require__) { + return [path.posix.join(directory, '**')]; +}; -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.'); -const MAJOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[0], 10); -const MINOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[1], 10); -/** - * IS `true` for Node.js 10.10 and greater. - */ -exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = MAJOR_VERSION > 10 || (MAJOR_VERSION === 10 && MINOR_VERSION >= 10); +module.exports = async (input, options) => { + options = { + cwd: process.cwd(), + ...options + }; + if (typeof options.cwd !== 'string') { + throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); + } -/***/ }), -/* 639 */ -/***/ (function(module, exports, __webpack_require__) { + const globs = await Promise.all([].concat(input).map(async x => { + const isDirectory = await pathType.isDirectory(getPath(x, options.cwd)); + return isDirectory ? getGlob(x, options) : x; + })); -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(640); -exports.fs = fs; + return [].concat.apply([], globs); // eslint-disable-line prefer-spread +}; + +module.exports.sync = (input, options) => { + options = { + cwd: process.cwd(), + ...options + }; + + if (typeof options.cwd !== 'string') { + throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); + } + + const globs = [].concat(input).map(x => pathType.isDirectorySync(getPath(x, options.cwd)) ? getGlob(x, options) : x); + + return [].concat.apply([], globs); // eslint-disable-line prefer-spread +}; /***/ }), -/* 640 */ +/* 658 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -class DirentFromStats { - constructor(name, stats) { - this.name = name; - this.isBlockDevice = stats.isBlockDevice.bind(stats); - this.isCharacterDevice = stats.isCharacterDevice.bind(stats); - this.isDirectory = stats.isDirectory.bind(stats); - this.isFIFO = stats.isFIFO.bind(stats); - this.isFile = stats.isFile.bind(stats); - this.isSocket = stats.isSocket.bind(stats); - this.isSymbolicLink = stats.isSymbolicLink.bind(stats); - } -} -function createDirentFromStats(name, stats) { - return new DirentFromStats(name, stats); -} -exports.createDirentFromStats = createDirentFromStats; + +const {promisify} = __webpack_require__(397); +const fs = __webpack_require__(349); + +async function isType(fsStatType, statsMethodName, filePath) { + if (typeof filePath !== 'string') { + throw new TypeError(`Expected a string, got ${typeof filePath}`); + } + + try { + const stats = await promisify(fs[fsStatType])(filePath); + return stats[statsMethodName](); + } catch (error) { + if (error.code === 'ENOENT') { + return false; + } + + throw error; + } +} + +function isTypeSync(fsStatType, statsMethodName, filePath) { + if (typeof filePath !== 'string') { + throw new TypeError(`Expected a string, got ${typeof filePath}`); + } + + try { + return fs[fsStatType](filePath)[statsMethodName](); + } catch (error) { + if (error.code === 'ENOENT') { + return false; + } + + throw error; + } +} + +exports.isFile = isType.bind(null, 'stat', 'isFile'); +exports.isDirectory = isType.bind(null, 'stat', 'isDirectory'); +exports.isSymlink = isType.bind(null, 'lstat', 'isSymbolicLink'); +exports.isFileSync = isTypeSync.bind(null, 'statSync', 'isFile'); +exports.isDirectorySync = isTypeSync.bind(null, 'statSync', 'isDirectory'); +exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); /***/ }), -/* 641 */ +/* 659 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(627); -const constants_1 = __webpack_require__(638); -const utils = __webpack_require__(639); -function read(dir, settings) { - if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { - return readdirWithFileTypes(dir, settings); - } - return readdir(dir, settings); -} -exports.read = read; -function readdirWithFileTypes(dir, settings) { - const dirents = settings.fs.readdirSync(dir, { withFileTypes: true }); - return dirents.map((dirent) => { - const entry = { - dirent, - name: dirent.name, - path: `${dir}${settings.pathSegmentSeparator}${dirent.name}` - }; - if (entry.dirent.isSymbolicLink() && settings.followSymbolicLinks) { - try { - const stats = settings.fs.statSync(entry.path); - entry.dirent = utils.fs.createDirentFromStats(entry.name, stats); - } - catch (error) { - if (settings.throwErrorOnBrokenSymbolicLink) { - throw error; - } - } - } - return entry; - }); -} -exports.readdirWithFileTypes = readdirWithFileTypes; -function readdir(dir, settings) { - const names = settings.fs.readdirSync(dir); - return names.map((name) => { - const entryPath = `${dir}${settings.pathSegmentSeparator}${name}`; - const stats = fsStat.statSync(entryPath, settings.fsStatSettings); - const entry = { - name, - path: entryPath, - dirent: utils.fs.createDirentFromStats(name, stats) - }; - if (settings.stats) { - entry.stats = stats; - } - return entry; - }); -} -exports.readdir = readdir; + +const {promisify} = __webpack_require__(397); +const fs = __webpack_require__(349); +const path = __webpack_require__(4); +const fastGlob = __webpack_require__(591); +const gitIgnore = __webpack_require__(660); +const slash = __webpack_require__(661); + +const DEFAULT_IGNORE = [ + '**/node_modules/**', + '**/flow-typed/**', + '**/coverage/**', + '**/.git' +]; + +const readFileP = promisify(fs.readFile); + +const mapGitIgnorePatternTo = base => ignore => { + if (ignore.startsWith('!')) { + return '!' + path.posix.join(base, ignore.slice(1)); + } + + return path.posix.join(base, ignore); +}; + +const parseGitIgnore = (content, options) => { + const base = slash(path.relative(options.cwd, path.dirname(options.fileName))); + + return content + .split(/\r?\n/) + .filter(Boolean) + .filter(line => !line.startsWith('#')) + .map(mapGitIgnorePatternTo(base)); +}; + +const reduceIgnore = files => { + return files.reduce((ignores, file) => { + ignores.add(parseGitIgnore(file.content, { + cwd: file.cwd, + fileName: file.filePath + })); + return ignores; + }, gitIgnore()); +}; + +const ensureAbsolutePathForCwd = (cwd, p) => { + if (path.isAbsolute(p)) { + if (p.startsWith(cwd)) { + return p; + } + + throw new Error(`Path ${p} is not in cwd ${cwd}`); + } + + return path.join(cwd, p); +}; + +const getIsIgnoredPredecate = (ignores, cwd) => { + return p => ignores.ignores(slash(path.relative(cwd, ensureAbsolutePathForCwd(cwd, p)))); +}; + +const getFile = async (file, cwd) => { + const filePath = path.join(cwd, file); + const content = await readFileP(filePath, 'utf8'); + + return { + cwd, + filePath, + content + }; +}; + +const getFileSync = (file, cwd) => { + const filePath = path.join(cwd, file); + const content = fs.readFileSync(filePath, 'utf8'); + + return { + cwd, + filePath, + content + }; +}; + +const normalizeOptions = ({ + ignore = [], + cwd = process.cwd() +} = {}) => { + return {ignore, cwd}; +}; + +module.exports = async options => { + options = normalizeOptions(options); + + const paths = await fastGlob('**/.gitignore', { + ignore: DEFAULT_IGNORE.concat(options.ignore), + cwd: options.cwd + }); + + const files = await Promise.all(paths.map(file => getFile(file, options.cwd))); + const ignores = reduceIgnore(files); + + return getIsIgnoredPredecate(ignores, options.cwd); +}; + +module.exports.sync = options => { + options = normalizeOptions(options); + + const paths = fastGlob.sync('**/.gitignore', { + ignore: DEFAULT_IGNORE.concat(options.ignore), + cwd: options.cwd + }); + + const files = paths.map(file => getFileSync(file, options.cwd)); + const ignores = reduceIgnore(files); + + return getIsIgnoredPredecate(ignores, options.cwd); +}; /***/ }), -/* 642 */ -/***/ (function(module, exports, __webpack_require__) { +/* 660 */ +/***/ (function(module, exports) { -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(16); -const fsStat = __webpack_require__(627); -const fs = __webpack_require__(643); -class Settings { - constructor(_options = {}) { - this._options = _options; - this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false); - this.fs = fs.createFileSystemAdapter(this._options.fs); - this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep); - this.stats = this._getValue(this._options.stats, false); - this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); - this.fsStatSettings = new fsStat.Settings({ - followSymbolicLink: this.followSymbolicLinks, - fs: this.fs, - throwErrorOnBrokenSymbolicLink: this.throwErrorOnBrokenSymbolicLink - }); - } - _getValue(option, value) { - return option === undefined ? value : option; - } -} -exports.default = Settings; +// A simple implementation of make-array +function makeArray (subject) { + return Array.isArray(subject) + ? subject + : [subject] +} +const REGEX_TEST_BLANK_LINE = /^\s+$/ +const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/ +const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/ +const REGEX_SPLITALL_CRLF = /\r?\n/g +// /foo, +// ./foo, +// ../foo, +// . +// .. +const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/ -/***/ }), -/* 643 */ -/***/ (function(module, exports, __webpack_require__) { +const SLASH = '/' +const KEY_IGNORE = typeof Symbol !== 'undefined' + ? Symbol.for('node-ignore') + /* istanbul ignore next */ + : 'node-ignore' -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(23); -exports.FILE_SYSTEM_ADAPTER = { - lstat: fs.lstat, - stat: fs.stat, - lstatSync: fs.lstatSync, - statSync: fs.statSync, - readdir: fs.readdir, - readdirSync: fs.readdirSync -}; -function createFileSystemAdapter(fsMethods) { - if (!fsMethods) { - return exports.FILE_SYSTEM_ADAPTER; - } - return Object.assign({}, exports.FILE_SYSTEM_ADAPTER, fsMethods); -} -exports.createFileSystemAdapter = createFileSystemAdapter; +const define = (object, key, value) => + Object.defineProperty(object, key, {value}) +const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g -/***/ }), -/* 644 */ -/***/ (function(module, exports, __webpack_require__) { +// Sanitize the range of a regular expression +// The cases are complicated, see test cases for details +const sanitizeRange = range => range.replace( + REGEX_REGEXP_RANGE, + (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0) + ? match + // Invalid range (out of order) which is ok for gitignore rules but + // fatal for JavaScript regular expression, so eliminate it. + : '' +) -"use strict"; +// > If the pattern ends with a slash, +// > it is removed for the purpose of the following description, +// > but it would only find a match with a directory. +// > In other words, foo/ will match a directory foo and paths underneath it, +// > but will not match a regular file or a symbolic link foo +// > (this is consistent with the way how pathspec works in general in Git). +// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`' +// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call +// you could use option `mark: true` with `glob` +// '`foo/`' should not continue with the '`..`' +const DEFAULT_REPLACER_PREFIX = [ -var reusify = __webpack_require__(645) + // > Trailing spaces are ignored unless they are quoted with backslash ("\") + [ + // (a\ ) -> (a ) + // (a ) -> (a) + // (a \ ) -> (a ) + /\\?\s+$/, + match => match.indexOf('\\') === 0 + ? ' ' + : '' + ], -function fastqueue (context, worker, concurrency) { - if (typeof context === 'function') { - concurrency = worker - worker = context - context = null - } + // replace (\ ) with ' ' + [ + /\\\s/g, + () => ' ' + ], - var cache = reusify(Task) - var queueHead = null - var queueTail = null - var _running = 0 + // Escape metacharacters + // which is written down by users but means special for regular expressions. - var self = { - push: push, - drain: noop, - saturated: noop, - pause: pause, - paused: false, - concurrency: concurrency, - running: running, - resume: resume, - idle: idle, - length: length, - unshift: unshift, - empty: noop, - kill: kill, - killAndDrain: killAndDrain - } + // > There are 12 characters with special meanings: + // > - the backslash \, + // > - the caret ^, + // > - the dollar sign $, + // > - the period or dot ., + // > - the vertical bar or pipe symbol |, + // > - the question mark ?, + // > - the asterisk or star *, + // > - the plus sign +, + // > - the opening parenthesis (, + // > - the closing parenthesis ), + // > - and the opening square bracket [, + // > - the opening curly brace {, + // > These special characters are often called "metacharacters". + [ + /[\\^$.|*+(){]/g, + match => `\\${match}` + ], - return self + [ + // > [abc] matches any character inside the brackets + // > (in this case a, b, or c); + /\[([^\]/]*)($|\])/g, + (match, p1, p2) => p2 === ']' + ? `[${sanitizeRange(p1)}]` + : `\\${match}` + ], - function running () { - return _running - } + [ + // > a question mark (?) matches a single character + /(?!\\)\?/g, + () => '[^/]' + ], - function pause () { - self.paused = true - } + // leading slash + [ - function length () { - var current = queueHead - var counter = 0 + // > A leading slash matches the beginning of the pathname. + // > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c". + // A leading slash matches the beginning of the pathname + /^\//, + () => '^' + ], - while (current) { - current = current.next - counter++ - } + // replace special metacharacter slash after the leading slash + [ + /\//g, + () => '\\/' + ], - return counter - } + [ + // > A leading "**" followed by a slash means match in all directories. + // > For example, "**/foo" matches file or directory "foo" anywhere, + // > the same as pattern "foo". + // > "**/foo/bar" matches file or directory "bar" anywhere that is directly + // > under directory "foo". + // Notice that the '*'s have been replaced as '\\*' + /^\^*\\\*\\\*\\\//, - function resume () { - if (!self.paused) return - self.paused = false - for (var i = 0; i < self.concurrency; i++) { - _running++ - release() + // '**/foo' <-> 'foo' + () => '^(?:.*\\/)?' + ] +] + +const DEFAULT_REPLACER_SUFFIX = [ + // starting + [ + // there will be no leading '/' + // (which has been replaced by section "leading slash") + // If starts with '**', adding a '^' to the regular expression also works + /^(?=[^^])/, + function startingReplacer () { + return !/\/(?!$)/.test(this) + // > If the pattern does not contain a slash /, + // > Git treats it as a shell glob pattern + // Actually, if there is only a trailing slash, + // git also treats it as a shell glob pattern + ? '(?:^|\\/)' + + // > Otherwise, Git treats the pattern as a shell glob suitable for + // > consumption by fnmatch(3) + : '^' } - } + ], - function idle () { - return _running === 0 && self.length() === 0 - } + // two globstars + [ + // Use lookahead assertions so that we could match more than one `'/**'` + /\\\/\\\*\\\*(?=\\\/|$)/g, - function push (value, done) { - var current = cache.get() + // Zero, one or several directories + // should not use '*', or it will be replaced by the next replacer - current.context = context - current.release = release - current.value = value - current.callback = done || noop + // Check if it is not the last `'/**'` + (_, index, str) => index + 6 < str.length - if (_running === self.concurrency || self.paused) { - if (queueTail) { - queueTail.next = current - queueTail = current - } else { - queueHead = current - queueTail = current - self.saturated() - } - } else { - _running++ - worker.call(context, current.value, current.worked) - } - } + // case: /**/ + // > A slash followed by two consecutive asterisks then a slash matches + // > zero or more directories. + // > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on. + // '/**/' + ? '(?:\\/[^\\/]+)*' - function unshift (value, done) { - var current = cache.get() + // case: /** + // > A trailing `"/**"` matches everything inside. - current.context = context - current.release = release - current.value = value - current.callback = done || noop + // #21: everything inside but it should not include the current folder + : '\\/.+' + ], - if (_running === self.concurrency || self.paused) { - if (queueHead) { - current.next = queueHead - queueHead = current - } else { - queueHead = current - queueTail = current - self.saturated() - } - } else { - _running++ - worker.call(context, current.value, current.worked) - } - } + // intermediate wildcards + [ + // Never replace escaped '*' + // ignore rule '\*' will match the path '*' - function release (holder) { - if (holder) { - cache.release(holder) - } - var next = queueHead - if (next) { - if (!self.paused) { - if (queueTail === queueHead) { - queueTail = null - } - queueHead = next.next - next.next = null - worker.call(context, next.value, next.worked) - if (queueTail === null) { - self.empty() - } - } else { - _running-- - } - } else if (--_running === 0) { - self.drain() - } - } + // 'abc.*/' -> go + // 'abc.*' -> skip this rule + /(^|[^\\]+)\\\*(?=.+)/g, - function kill () { - queueHead = null - queueTail = null - self.drain = noop - } + // '*.js' matches '.js' + // '*.js' doesn't match 'abc' + (_, p1) => `${p1}[^\\/]*` + ], - function killAndDrain () { - queueHead = null - queueTail = null - self.drain() - self.drain = noop - } -} + // trailing wildcard + [ + /(\^|\\\/)?\\\*$/, + (_, p1) => { + const prefix = p1 + // '\^': + // '/*' does not match '' + // '/*' does not match everything -function noop () {} + // '\\\/': + // 'abc/*' does not match 'abc/' + ? `${p1}[^/]+` -function Task () { - this.value = null - this.callback = noop - this.next = null - this.release = noop - this.context = null + // 'a*' matches 'a' + // 'a*' matches 'aa' + : '[^/]*' - var self = this + return `${prefix}(?=$|\\/$)` + } + ], - this.worked = function worked (err, result) { - var callback = self.callback - self.value = null - self.callback = noop - callback.call(self.context, err, result) - self.release(self) - } -} + [ + // unescape + /\\\\\\/g, + () => '\\' + ] +] -module.exports = fastqueue +const POSITIVE_REPLACERS = [ + ...DEFAULT_REPLACER_PREFIX, + // 'f' + // matches + // - /f(end) + // - /f/ + // - (start)f(end) + // - (start)f/ + // doesn't match + // - oof + // - foo + // pseudo: + // -> (^|/)f(/|$) -/***/ }), -/* 645 */ -/***/ (function(module, exports, __webpack_require__) { + // ending + [ + // 'js' will not match 'js.' + // 'ab' will not match 'abc' + /(?:[^*/])$/, -"use strict"; + // 'js*' will not match 'a.js' + // 'js/' will not match 'a.js' + // 'js' will match 'a.js' and 'a.js/' + match => `${match}(?=$|\\/)` + ], + ...DEFAULT_REPLACER_SUFFIX +] -function reusify (Constructor) { - var head = new Constructor() - var tail = head +const NEGATIVE_REPLACERS = [ + ...DEFAULT_REPLACER_PREFIX, - function get () { - var current = head + // #24, #38 + // The MISSING rule of [gitignore docs](https://git-scm.com/docs/gitignore) + // A negative pattern without a trailing wildcard should not + // re-include the things inside that directory. - if (current.next) { - head = current.next - } else { - head = new Constructor() - tail = head - } + // eg: + // ['node_modules/*', '!node_modules'] + // should ignore `node_modules/a.js` + [ + /(?:[^*])$/, + match => `${match}(?=$|\\/$)` + ], - current.next = null + ...DEFAULT_REPLACER_SUFFIX +] - return current - } +// A simple cache, because an ignore rule only has only one certain meaning +const regexCache = Object.create(null) - function release (obj) { - tail.next = obj - tail = obj +// @param {pattern} +const makeRegex = (pattern, negative, ignorecase) => { + const r = regexCache[pattern] + if (r) { + return r } - return { - get: get, - release: release + const replacers = negative + ? NEGATIVE_REPLACERS + : POSITIVE_REPLACERS + + const source = replacers.reduce( + (prev, current) => prev.replace(current[0], current[1].bind(pattern)), + pattern + ) + + return regexCache[pattern] = ignorecase + ? new RegExp(source, 'i') + : new RegExp(source) +} + +const isString = subject => typeof subject === 'string' + +// > A blank line matches no files, so it can serve as a separator for readability. +const checkPattern = pattern => pattern + && isString(pattern) + && !REGEX_TEST_BLANK_LINE.test(pattern) + + // > A line starting with # serves as a comment. + && pattern.indexOf('#') !== 0 + +const splitPattern = pattern => pattern.split(REGEX_SPLITALL_CRLF) + +class IgnoreRule { + constructor ( + origin, + pattern, + negative, + regex + ) { + this.origin = origin + this.pattern = pattern + this.negative = negative + this.regex = regex } } -module.exports = reusify +const createRule = (pattern, ignorecase) => { + const origin = pattern + let negative = false + + // > An optional prefix "!" which negates the pattern; + if (pattern.indexOf('!') === 0) { + negative = true + pattern = pattern.substr(1) + } + + pattern = pattern + // > Put a backslash ("\") in front of the first "!" for patterns that + // > begin with a literal "!", for example, `"\!important!.txt"`. + .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!') + // > Put a backslash ("\") in front of the first hash for patterns that + // > begin with a hash. + .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#') + const regex = makeRegex(pattern, negative, ignorecase) -/***/ }), -/* 646 */ -/***/ (function(module, exports, __webpack_require__) { + return new IgnoreRule( + origin, + pattern, + negative, + regex + ) +} -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -function isFatalError(settings, error) { - if (settings.errorFilter === null) { - return true; - } - return !settings.errorFilter(error); -} -exports.isFatalError = isFatalError; -function isAppliedFilter(filter, value) { - return filter === null || filter(value); -} -exports.isAppliedFilter = isAppliedFilter; -function replacePathSegmentSeparator(filepath, separator) { - return filepath.split(/[\\\/]/).join(separator); -} -exports.replacePathSegmentSeparator = replacePathSegmentSeparator; -function joinPathSegments(a, b, separator) { - if (a === '') { - return b; - } - return a + separator + b; -} -exports.joinPathSegments = joinPathSegments; +const throwError = (message, Ctor) => { + throw new Ctor(message) +} +const checkPath = (path, originalPath, doThrow) => { + if (!isString(path)) { + return doThrow( + `path must be a string, but got \`${originalPath}\``, + TypeError + ) + } -/***/ }), -/* 647 */ -/***/ (function(module, exports, __webpack_require__) { + // We don't know if we should ignore '', so throw + if (!path) { + return doThrow(`path must not be empty`, TypeError) + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const common = __webpack_require__(646); -class Reader { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._root = common.replacePathSegmentSeparator(_root, _settings.pathSegmentSeparator); - } -} -exports.default = Reader; + // Check if it is a relative path + if (checkPath.isNotRelative(path)) { + const r = '`path.relative()`d' + return doThrow( + `path should be a ${r} string, but got "${originalPath}"`, + RangeError + ) + } + return true +} -/***/ }), -/* 648 */ -/***/ (function(module, exports, __webpack_require__) { +const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path) -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(27); -const async_1 = __webpack_require__(634); -class StreamProvider { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._reader = new async_1.default(this._root, this._settings); - this._stream = new stream_1.Readable({ - objectMode: true, - read: () => { }, - destroy: this._reader.destroy.bind(this._reader) - }); - } - read() { - this._reader.onError((error) => { - this._stream.emit('error', error); - }); - this._reader.onEntry((entry) => { - this._stream.push(entry); - }); - this._reader.onEnd(() => { - this._stream.push(null); - }); - this._reader.read(); - return this._stream; - } -} -exports.default = StreamProvider; +checkPath.isNotRelative = isNotRelative +checkPath.convert = p => p +class Ignore { + constructor ({ + ignorecase = true + } = {}) { + this._rules = [] + this._ignorecase = ignorecase + define(this, KEY_IGNORE, true) + this._initCache() + } -/***/ }), -/* 649 */ -/***/ (function(module, exports, __webpack_require__) { + _initCache () { + this._ignoreCache = Object.create(null) + this._testCache = Object.create(null) + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const sync_1 = __webpack_require__(650); -class SyncProvider { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._reader = new sync_1.default(this._root, this._settings); - } - read() { - return this._reader.read(); - } -} -exports.default = SyncProvider; + _addPattern (pattern) { + // #32 + if (pattern && pattern[KEY_IGNORE]) { + this._rules = this._rules.concat(pattern._rules) + this._added = true + return + } + if (checkPattern(pattern)) { + const rule = createRule(pattern, this._ignorecase) + this._added = true + this._rules.push(rule) + } + } -/***/ }), -/* 650 */ -/***/ (function(module, exports, __webpack_require__) { + // @param {Array | string | Ignore} pattern + add (pattern) { + this._added = false -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fsScandir = __webpack_require__(635); -const common = __webpack_require__(646); -const reader_1 = __webpack_require__(647); -class SyncReader extends reader_1.default { - constructor() { - super(...arguments); - this._scandir = fsScandir.scandirSync; - this._storage = new Set(); - this._queue = new Set(); - } - read() { - this._pushToQueue(this._root, this._settings.basePath); - this._handleQueue(); - return Array.from(this._storage); - } - _pushToQueue(dir, base) { - this._queue.add({ dir, base }); - } - _handleQueue() { - for (const item of this._queue.values()) { - this._handleDirectory(item.dir, item.base); - } - } - _handleDirectory(dir, base) { - try { - const entries = this._scandir(dir, this._settings.fsScandirSettings); - for (const entry of entries) { - this._handleEntry(entry, base); - } - } - catch (error) { - this._handleError(error); - } - } - _handleError(error) { - if (!common.isFatalError(this._settings, error)) { - return; - } - throw error; - } - _handleEntry(entry, base) { - const fullpath = entry.path; - if (base !== undefined) { - entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); - } - if (common.isAppliedFilter(this._settings.entryFilter, entry)) { - this._pushToStorage(entry); - } - if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) { - this._pushToQueue(fullpath, entry.path); - } - } - _pushToStorage(entry) { - this._storage.add(entry); - } -} -exports.default = SyncReader; + makeArray( + isString(pattern) + ? splitPattern(pattern) + : pattern + ).forEach(this._addPattern, this) + // Some rules have just added to the ignore, + // making the behavior changed. + if (this._added) { + this._initCache() + } -/***/ }), -/* 651 */ -/***/ (function(module, exports, __webpack_require__) { + return this + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(16); -const fsScandir = __webpack_require__(635); -class Settings { - constructor(_options = {}) { - this._options = _options; - this.basePath = this._getValue(this._options.basePath, undefined); - this.concurrency = this._getValue(this._options.concurrency, Infinity); - this.deepFilter = this._getValue(this._options.deepFilter, null); - this.entryFilter = this._getValue(this._options.entryFilter, null); - this.errorFilter = this._getValue(this._options.errorFilter, null); - this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep); - this.fsScandirSettings = new fsScandir.Settings({ - followSymbolicLinks: this._options.followSymbolicLinks, - fs: this._options.fs, - pathSegmentSeparator: this._options.pathSegmentSeparator, - stats: this._options.stats, - throwErrorOnBrokenSymbolicLink: this._options.throwErrorOnBrokenSymbolicLink - }); - } - _getValue(option, value) { - return option === undefined ? value : option; - } -} -exports.default = Settings; + // legacy + addPattern (pattern) { + return this.add(pattern) + } + // | ignored : unignored + // negative | 0:0 | 0:1 | 1:0 | 1:1 + // -------- | ------- | ------- | ------- | -------- + // 0 | TEST | TEST | SKIP | X + // 1 | TESTIF | SKIP | TEST | X -/***/ }), -/* 652 */ -/***/ (function(module, exports, __webpack_require__) { + // - SKIP: always skip + // - TEST: always test + // - TESTIF: only test if checkUnignored + // - X: that never happen -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(16); -const fsStat = __webpack_require__(627); -const utils = __webpack_require__(598); -class Reader { - constructor(_settings) { - this._settings = _settings; - this._fsStatSettings = new fsStat.Settings({ - followSymbolicLink: this._settings.followSymbolicLinks, - fs: this._settings.fs, - throwErrorOnBrokenSymbolicLink: this._settings.followSymbolicLinks - }); - } - _getFullEntryPath(filepath) { - return path.resolve(this._settings.cwd, filepath); - } - _makeEntry(stats, pattern) { - const entry = { - name: pattern, - path: pattern, - dirent: utils.fs.createDirentFromStats(pattern, stats) - }; - if (this._settings.stats) { - entry.stats = stats; - } - return entry; - } - _isFatalError(error) { - return !utils.errno.isEnoentCodeError(error) && !this._settings.suppressErrors; - } -} -exports.default = Reader; + // @param {boolean} whether should check if the path is unignored, + // setting `checkUnignored` to `false` could reduce additional + // path matching. + // @returns {TestResult} true if a file is ignored + _testOne (path, checkUnignored) { + let ignored = false + let unignored = false -/***/ }), -/* 653 */ -/***/ (function(module, exports, __webpack_require__) { + this._rules.forEach(rule => { + const {negative} = rule + if ( + unignored === negative && ignored !== unignored + || negative && !ignored && !unignored && !checkUnignored + ) { + return + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(16); -const deep_1 = __webpack_require__(654); -const entry_1 = __webpack_require__(655); -const error_1 = __webpack_require__(656); -const entry_2 = __webpack_require__(657); -class Provider { - constructor(_settings) { - this._settings = _settings; - this.errorFilter = new error_1.default(this._settings); - this.entryFilter = new entry_1.default(this._settings, this._getMicromatchOptions()); - this.deepFilter = new deep_1.default(this._settings, this._getMicromatchOptions()); - this.entryTransformer = new entry_2.default(this._settings); - } - _getRootDirectory(task) { - return path.resolve(this._settings.cwd, task.base); - } - _getReaderOptions(task) { - const basePath = task.base === '.' ? '' : task.base; - return { - basePath, - pathSegmentSeparator: '/', - concurrency: this._settings.concurrency, - deepFilter: this.deepFilter.getFilter(basePath, task.positive, task.negative), - entryFilter: this.entryFilter.getFilter(task.positive, task.negative), - errorFilter: this.errorFilter.getFilter(), - followSymbolicLinks: this._settings.followSymbolicLinks, - fs: this._settings.fs, - stats: this._settings.stats, - throwErrorOnBrokenSymbolicLink: this._settings.throwErrorOnBrokenSymbolicLink, - transform: this.entryTransformer.getTransformer() - }; - } - _getMicromatchOptions() { - return { - dot: this._settings.dot, - matchBase: this._settings.baseNameMatch, - nobrace: !this._settings.braceExpansion, - nocase: !this._settings.caseSensitiveMatch, - noext: !this._settings.extglob, - noglobstar: !this._settings.globstar, - posix: true, - strictSlashes: false - }; - } -} -exports.default = Provider; + const matched = rule.regex.test(path) + if (matched) { + ignored = !negative + unignored = negative + } + }) -/***/ }), -/* 654 */ -/***/ (function(module, exports, __webpack_require__) { + return { + ignored, + unignored + } + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(598); -class DeepFilter { - constructor(_settings, _micromatchOptions) { - this._settings = _settings; - this._micromatchOptions = _micromatchOptions; - } - getFilter(basePath, positive, negative) { - const maxPatternDepth = this._getMaxPatternDepth(positive); - const negativeRe = this._getNegativePatternsRe(negative); - return (entry) => this._filter(basePath, entry, negativeRe, maxPatternDepth); - } - _getMaxPatternDepth(patterns) { - const globstar = patterns.some(utils.pattern.hasGlobStar); - return globstar ? Infinity : utils.pattern.getMaxNaivePatternsDepth(patterns); - } - _getNegativePatternsRe(patterns) { - const affectDepthOfReadingPatterns = patterns.filter(utils.pattern.isAffectDepthOfReadingPattern); - return utils.pattern.convertPatternsToRe(affectDepthOfReadingPatterns, this._micromatchOptions); - } - _filter(basePath, entry, negativeRe, maxPatternDepth) { - const depth = this._getEntryDepth(basePath, entry.path); - if (this._isSkippedByDeep(depth)) { - return false; - } - if (this._isSkippedByMaxPatternDepth(depth, maxPatternDepth)) { - return false; - } - if (this._isSkippedSymbolicLink(entry)) { - return false; - } - if (this._isSkippedDotDirectory(entry)) { - return false; - } - return this._isSkippedByNegativePatterns(entry, negativeRe); - } - _getEntryDepth(basePath, entryPath) { - const basePathDepth = basePath.split('/').length; - const entryPathDepth = entryPath.split('/').length; - return entryPathDepth - (basePath === '' ? 0 : basePathDepth); - } - _isSkippedByDeep(entryDepth) { - return entryDepth >= this._settings.deep; - } - _isSkippedByMaxPatternDepth(entryDepth, maxPatternDepth) { - return !this._settings.baseNameMatch && maxPatternDepth !== Infinity && entryDepth > maxPatternDepth; - } - _isSkippedSymbolicLink(entry) { - return !this._settings.followSymbolicLinks && entry.dirent.isSymbolicLink(); - } - _isSkippedDotDirectory(entry) { - return !this._settings.dot && entry.name.startsWith('.'); - } - _isSkippedByNegativePatterns(entry, negativeRe) { - return !utils.pattern.matchAny(entry.path, negativeRe); - } -} -exports.default = DeepFilter; + // @returns {TestResult} + _test (originalPath, cache, checkUnignored, slices) { + const path = originalPath + // Supports nullable path + && checkPath.convert(originalPath) + checkPath(path, originalPath, throwError) -/***/ }), -/* 655 */ -/***/ (function(module, exports, __webpack_require__) { + return this._t(path, cache, checkUnignored, slices) + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(598); -class EntryFilter { - constructor(_settings, _micromatchOptions) { - this._settings = _settings; - this._micromatchOptions = _micromatchOptions; - this.index = new Map(); - } - getFilter(positive, negative) { - const positiveRe = utils.pattern.convertPatternsToRe(positive, this._micromatchOptions); - const negativeRe = utils.pattern.convertPatternsToRe(negative, this._micromatchOptions); - return (entry) => this._filter(entry, positiveRe, negativeRe); - } - _filter(entry, positiveRe, negativeRe) { - if (this._settings.unique) { - if (this._isDuplicateEntry(entry)) { - return false; - } - this._createIndexRecord(entry); - } - if (this._onlyFileFilter(entry) || this._onlyDirectoryFilter(entry)) { - return false; - } - if (this._isSkippedByAbsoluteNegativePatterns(entry, negativeRe)) { - return false; - } - const filepath = this._settings.baseNameMatch ? entry.name : entry.path; - return this._isMatchToPatterns(filepath, positiveRe) && !this._isMatchToPatterns(entry.path, negativeRe); - } - _isDuplicateEntry(entry) { - return this.index.has(entry.path); - } - _createIndexRecord(entry) { - this.index.set(entry.path, undefined); - } - _onlyFileFilter(entry) { - return this._settings.onlyFiles && !entry.dirent.isFile(); - } - _onlyDirectoryFilter(entry) { - return this._settings.onlyDirectories && !entry.dirent.isDirectory(); - } - _isSkippedByAbsoluteNegativePatterns(entry, negativeRe) { - if (!this._settings.absolute) { - return false; - } - const fullpath = utils.path.makeAbsolute(this._settings.cwd, entry.path); - return this._isMatchToPatterns(fullpath, negativeRe); - } - _isMatchToPatterns(filepath, patternsRe) { - return utils.pattern.matchAny(filepath, patternsRe); - } -} -exports.default = EntryFilter; + _t (path, cache, checkUnignored, slices) { + if (path in cache) { + return cache[path] + } + if (!slices) { + // path/to/a.js + // ['path', 'to', 'a.js'] + slices = path.split(SLASH) + } -/***/ }), -/* 656 */ -/***/ (function(module, exports, __webpack_require__) { + slices.pop() -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(598); -class ErrorFilter { - constructor(_settings) { - this._settings = _settings; - } - getFilter() { - return (error) => this._isNonFatalError(error); - } - _isNonFatalError(error) { - return utils.errno.isEnoentCodeError(error) || this._settings.suppressErrors; - } -} -exports.default = ErrorFilter; + // If the path has no parent directory, just test it + if (!slices.length) { + return cache[path] = this._testOne(path, checkUnignored) + } + const parent = this._t( + slices.join(SLASH) + SLASH, + cache, + checkUnignored, + slices + ) -/***/ }), -/* 657 */ -/***/ (function(module, exports, __webpack_require__) { + // If the path contains a parent directory, check the parent first + return cache[path] = parent.ignored + // > It is not possible to re-include a file if a parent directory of + // > that file is excluded. + ? parent + : this._testOne(path, checkUnignored) + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(598); -class EntryTransformer { - constructor(_settings) { - this._settings = _settings; - } - getTransformer() { - return (entry) => this._transform(entry); - } - _transform(entry) { - let filepath = entry.path; - if (this._settings.absolute) { - filepath = utils.path.makeAbsolute(this._settings.cwd, filepath); - filepath = utils.path.unixify(filepath); - } - if (this._settings.markDirectories && entry.dirent.isDirectory()) { - filepath += '/'; - } - if (!this._settings.objectMode) { - return filepath; - } - return Object.assign({}, entry, { path: filepath }); - } -} -exports.default = EntryTransformer; + ignores (path) { + return this._test(path, this._ignoreCache, false).ignored + } + createFilter () { + return path => !this.ignores(path) + } -/***/ }), -/* 658 */ -/***/ (function(module, exports, __webpack_require__) { + filter (paths) { + return makeArray(paths).filter(this.createFilter()) + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(27); -const stream_2 = __webpack_require__(626); -const provider_1 = __webpack_require__(653); -class ProviderStream extends provider_1.default { - constructor() { - super(...arguments); - this._reader = new stream_2.default(this._settings); - } - read(task) { - const root = this._getRootDirectory(task); - const options = this._getReaderOptions(task); - const source = this.api(root, task, options); - const dest = new stream_1.Readable({ objectMode: true, read: () => { } }); - source - .once('error', (error) => dest.emit('error', error)) - .on('data', (entry) => dest.emit('data', options.transform(entry))) - .once('end', () => dest.emit('end')); - return dest; - } - api(root, task, options) { - if (task.dynamic) { - return this._reader.dynamic(root, options); - } - return this._reader.static(task.patterns, options); - } -} -exports.default = ProviderStream; + // @returns {TestResult} + test (path) { + return this._test(path, this._testCache, true) + } +} +const factory = options => new Ignore(options) -/***/ }), -/* 659 */ -/***/ (function(module, exports, __webpack_require__) { +const returnFalse = () => false -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const sync_1 = __webpack_require__(660); -const provider_1 = __webpack_require__(653); -class ProviderSync extends provider_1.default { - constructor() { - super(...arguments); - this._reader = new sync_1.default(this._settings); - } - read(task) { - const root = this._getRootDirectory(task); - const options = this._getReaderOptions(task); - const entries = this.api(root, task, options); - return entries.map(options.transform); - } - api(root, task, options) { - if (task.dynamic) { - return this._reader.dynamic(root, options); - } - return this._reader.static(task.patterns, options); - } -} -exports.default = ProviderSync; +const isPathValid = path => + checkPath(path && checkPath.convert(path), path, returnFalse) +factory.isPathValid = isPathValid -/***/ }), -/* 660 */ -/***/ (function(module, exports, __webpack_require__) { +// Fixes typescript +factory.default = factory -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(627); -const fsWalk = __webpack_require__(632); -const reader_1 = __webpack_require__(652); -class ReaderSync extends reader_1.default { - constructor() { - super(...arguments); - this._walkSync = fsWalk.walkSync; - this._statSync = fsStat.statSync; - } - dynamic(root, options) { - return this._walkSync(root, options); - } - static(patterns, options) { - const entries = []; - for (const pattern of patterns) { - const filepath = this._getFullEntryPath(pattern); - const entry = this._getEntry(filepath, pattern, options); - if (entry === null || !options.entryFilter(entry)) { - continue; - } - entries.push(entry); - } - return entries; - } - _getEntry(filepath, pattern, options) { - try { - const stats = this._getStat(filepath); - return this._makeEntry(stats, pattern); - } - catch (error) { - if (options.errorFilter(error)) { - return null; - } - throw error; - } - } - _getStat(filepath) { - return this._statSync(filepath, this._fsStatSettings); - } -} -exports.default = ReaderSync; +module.exports = factory + +// Windows +// -------------------------------------------------------------- +/* istanbul ignore if */ +if ( + // Detect `process` so that it can run in browsers. + typeof process !== 'undefined' + && ( + process.env && process.env.IGNORE_TEST_WIN32 + || process.platform === 'win32' + ) +) { + /* eslint no-control-regex: "off" */ + const makePosix = str => /^\\\\\?\\/.test(str) + || /["<>|\u0000-\u001F]+/u.test(str) + ? str + : str.replace(/\\/g, '/') + + checkPath.convert = makePosix + + // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/' + // 'd:\\foo' + const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i + checkPath.isNotRelative = path => + REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path) + || isNotRelative(path) +} /***/ }), @@ -75639,59 +75887,17 @@ exports.default = ReaderSync; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(23); -const os = __webpack_require__(11); -const CPU_COUNT = os.cpus().length; -exports.DEFAULT_FILE_SYSTEM_ADAPTER = { - lstat: fs.lstat, - lstatSync: fs.lstatSync, - stat: fs.stat, - statSync: fs.statSync, - readdir: fs.readdir, - readdirSync: fs.readdirSync -}; -// tslint:enable no-redundant-jsdoc -class Settings { - constructor(_options = {}) { - this._options = _options; - this.absolute = this._getValue(this._options.absolute, false); - this.baseNameMatch = this._getValue(this._options.baseNameMatch, false); - this.braceExpansion = this._getValue(this._options.braceExpansion, true); - this.caseSensitiveMatch = this._getValue(this._options.caseSensitiveMatch, true); - this.concurrency = this._getValue(this._options.concurrency, CPU_COUNT); - this.cwd = this._getValue(this._options.cwd, process.cwd()); - this.deep = this._getValue(this._options.deep, Infinity); - this.dot = this._getValue(this._options.dot, false); - this.extglob = this._getValue(this._options.extglob, true); - this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, true); - this.fs = this._getFileSystemMethods(this._options.fs); - this.globstar = this._getValue(this._options.globstar, true); - this.ignore = this._getValue(this._options.ignore, []); - this.markDirectories = this._getValue(this._options.markDirectories, false); - this.objectMode = this._getValue(this._options.objectMode, false); - this.onlyDirectories = this._getValue(this._options.onlyDirectories, false); - this.onlyFiles = this._getValue(this._options.onlyFiles, true); - this.stats = this._getValue(this._options.stats, false); - this.suppressErrors = this._getValue(this._options.suppressErrors, false); - this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, false); - this.unique = this._getValue(this._options.unique, true); - if (this.onlyDirectories) { - this.onlyFiles = false; - } - if (this.stats) { - this.objectMode = true; - } - } - _getValue(option, value) { - return option === undefined ? value : option; - } - _getFileSystemMethods(methods = {}) { - return Object.assign({}, exports.DEFAULT_FILE_SYSTEM_ADAPTER, methods); - } -} -exports.default = Settings; + +module.exports = path => { + const isExtendedLengthPath = /^\\\\\?\\/.test(path); + const hasNonAscii = /[^\u0000-\u0080]+/.test(path); // eslint-disable-line no-control-regex + + if (isExtendedLengthPath || hasNonAscii) { + return path; + } + + return path.replace(/\\/g, '/'); +}; /***/ }), @@ -75700,1739 +75906,1725 @@ exports.default = Settings; "use strict"; -const path = __webpack_require__(16); -const pathType = __webpack_require__(663); +const {Transform} = __webpack_require__(382); -const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; - -const getPath = (filepath, cwd) => { - const pth = filepath[0] === '!' ? filepath.slice(1) : filepath; - return path.isAbsolute(pth) ? pth : path.join(cwd, pth); -}; - -const addExtensions = (file, extensions) => { - if (path.extname(file)) { - return `**/${file}`; +class ObjectTransform extends Transform { + constructor() { + super({ + objectMode: true + }); } +} - return `**/${file}.${getExtensions(extensions)}`; -}; - -const getGlob = (directory, options) => { - if (options.files && !Array.isArray(options.files)) { - throw new TypeError(`Expected \`files\` to be of type \`Array\` but received type \`${typeof options.files}\``); +class FilterStream extends ObjectTransform { + constructor(filter) { + super(); + this._filter = filter; } - if (options.extensions && !Array.isArray(options.extensions)) { - throw new TypeError(`Expected \`extensions\` to be of type \`Array\` but received type \`${typeof options.extensions}\``); - } + _transform(data, encoding, callback) { + if (this._filter(data)) { + this.push(data); + } - if (options.files && options.extensions) { - return options.files.map(x => path.posix.join(directory, addExtensions(x, options.extensions))); + callback(); } +} - if (options.files) { - return options.files.map(x => path.posix.join(directory, `**/${x}`)); +class UniqueStream extends ObjectTransform { + constructor() { + super(); + this._pushed = new Set(); } - if (options.extensions) { - return [path.posix.join(directory, `**/*.${getExtensions(options.extensions)}`)]; + _transform(data, encoding, callback) { + if (!this._pushed.has(data)) { + this.push(data); + this._pushed.add(data); + } + + callback(); } +} - return [path.posix.join(directory, '**')]; +module.exports = { + FilterStream, + UniqueStream }; -module.exports = async (input, options) => { - options = { - cwd: process.cwd(), - ...options - }; - if (typeof options.cwd !== 'string') { - throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); - } +/***/ }), +/* 663 */ +/***/ (function(module, exports, __webpack_require__) { - const globs = await Promise.all([].concat(input).map(async x => { - const isDirectory = await pathType.isDirectory(getPath(x, options.cwd)); - return isDirectory ? getGlob(x, options) : x; - })); +"use strict"; - return [].concat.apply([], globs); // eslint-disable-line prefer-spread -}; +const path = __webpack_require__(4); -module.exports.sync = (input, options) => { - options = { - cwd: process.cwd(), - ...options - }; +module.exports = path_ => { + let cwd = process.cwd(); - if (typeof options.cwd !== 'string') { - throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); - } + path_ = path.resolve(path_); - const globs = [].concat(input).map(x => pathType.isDirectorySync(getPath(x, options.cwd)) ? getGlob(x, options) : x); + if (process.platform === 'win32') { + cwd = cwd.toLowerCase(); + path_ = path_.toLowerCase(); + } - return [].concat.apply([], globs); // eslint-disable-line prefer-spread + return path_ === cwd; }; /***/ }), -/* 663 */ +/* 664 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const {promisify} = __webpack_require__(29); -const fs = __webpack_require__(23); +const path = __webpack_require__(4); -async function isType(fsStatType, statsMethodName, filePath) { - if (typeof filePath !== 'string') { - throw new TypeError(`Expected a string, got ${typeof filePath}`); - } +module.exports = (childPath, parentPath) => { + childPath = path.resolve(childPath); + parentPath = path.resolve(parentPath); - try { - const stats = await promisify(fs[fsStatType])(filePath); - return stats[statsMethodName](); - } catch (error) { - if (error.code === 'ENOENT') { - return false; - } + if (process.platform === 'win32') { + childPath = childPath.toLowerCase(); + parentPath = parentPath.toLowerCase(); + } - throw error; + if (childPath === parentPath) { + return false; } + + childPath += path.sep; + parentPath += path.sep; + + return childPath.startsWith(parentPath); +}; + + +/***/ }), +/* 665 */ +/***/ (function(module, exports, __webpack_require__) { + +const assert = __webpack_require__(371) +const path = __webpack_require__(4) +const fs = __webpack_require__(349) +let glob = undefined +try { + glob = __webpack_require__(586) +} catch (_err) { + // treat glob as optional. } -function isTypeSync(fsStatType, statsMethodName, filePath) { - if (typeof filePath !== 'string') { - throw new TypeError(`Expected a string, got ${typeof filePath}`); - } +const defaultGlobOpts = { + nosort: true, + silent: true +} - try { - return fs[fsStatType](filePath)[statsMethodName](); - } catch (error) { - if (error.code === 'ENOENT') { - return false; - } +// for EMFILE handling +let timeout = 0 - throw error; - } +const isWindows = (process.platform === "win32") + +const defaults = options => { + const methods = [ + 'unlink', + 'chmod', + 'stat', + 'lstat', + 'rmdir', + 'readdir' + ] + methods.forEach(m => { + options[m] = options[m] || fs[m] + m = m + 'Sync' + options[m] = options[m] || fs[m] + }) + + options.maxBusyTries = options.maxBusyTries || 3 + options.emfileWait = options.emfileWait || 1000 + if (options.glob === false) { + options.disableGlob = true + } + if (options.disableGlob !== true && glob === undefined) { + throw Error('glob dependency not found, set `options.disableGlob = true` if intentional') + } + options.disableGlob = options.disableGlob || false + options.glob = options.glob || defaultGlobOpts } -exports.isFile = isType.bind(null, 'stat', 'isFile'); -exports.isDirectory = isType.bind(null, 'stat', 'isDirectory'); -exports.isSymlink = isType.bind(null, 'lstat', 'isSymbolicLink'); -exports.isFileSync = isTypeSync.bind(null, 'statSync', 'isFile'); -exports.isDirectorySync = isTypeSync.bind(null, 'statSync', 'isDirectory'); -exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); +const rimraf = (p, options, cb) => { + if (typeof options === 'function') { + cb = options + options = {} + } + + assert(p, 'rimraf: missing path') + assert.equal(typeof p, 'string', 'rimraf: path should be a string') + assert.equal(typeof cb, 'function', 'rimraf: callback function required') + assert(options, 'rimraf: invalid options argument provided') + assert.equal(typeof options, 'object', 'rimraf: options should be object') + + defaults(options) + + let busyTries = 0 + let errState = null + let n = 0 + + const next = (er) => { + errState = errState || er + if (--n === 0) + cb(errState) + } + + const afterGlob = (er, results) => { + if (er) + return cb(er) + + n = results.length + if (n === 0) + return cb() + + results.forEach(p => { + const CB = (er) => { + if (er) { + if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") && + busyTries < options.maxBusyTries) { + busyTries ++ + // try again, with the same exact callback as this one. + return setTimeout(() => rimraf_(p, options, CB), busyTries * 100) + } + + // this one won't happen if graceful-fs is used. + if (er.code === "EMFILE" && timeout < options.emfileWait) { + return setTimeout(() => rimraf_(p, options, CB), timeout ++) + } + + // already gone + if (er.code === "ENOENT") er = null + } + timeout = 0 + next(er) + } + rimraf_(p, options, CB) + }) + } -/***/ }), -/* 664 */ -/***/ (function(module, exports, __webpack_require__) { + if (options.disableGlob || !glob.hasMagic(p)) + return afterGlob(null, [p]) -"use strict"; + options.lstat(p, (er, stat) => { + if (!er) + return afterGlob(null, [p]) -const {promisify} = __webpack_require__(29); -const fs = __webpack_require__(23); -const path = __webpack_require__(16); -const fastGlob = __webpack_require__(596); -const gitIgnore = __webpack_require__(665); -const slash = __webpack_require__(666); + glob(p, options.glob, afterGlob) + }) -const DEFAULT_IGNORE = [ - '**/node_modules/**', - '**/flow-typed/**', - '**/coverage/**', - '**/.git' -]; +} -const readFileP = promisify(fs.readFile); +// Two possible strategies. +// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR +// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR +// +// Both result in an extra syscall when you guess wrong. However, there +// are likely far more normal files in the world than directories. This +// is based on the assumption that a the average number of files per +// directory is >= 1. +// +// If anyone ever complains about this, then I guess the strategy could +// be made configurable somehow. But until then, YAGNI. +const rimraf_ = (p, options, cb) => { + assert(p) + assert(options) + assert(typeof cb === 'function') -const mapGitIgnorePatternTo = base => ignore => { - if (ignore.startsWith('!')) { - return '!' + path.posix.join(base, ignore.slice(1)); - } + // sunos lets the root user unlink directories, which is... weird. + // so we have to lstat here and make sure it's not a dir. + options.lstat(p, (er, st) => { + if (er && er.code === "ENOENT") + return cb(null) - return path.posix.join(base, ignore); -}; + // Windows can EPERM on stat. Life is suffering. + if (er && er.code === "EPERM" && isWindows) + fixWinEPERM(p, options, er, cb) -const parseGitIgnore = (content, options) => { - const base = slash(path.relative(options.cwd, path.dirname(options.fileName))); + if (st && st.isDirectory()) + return rmdir(p, options, er, cb) - return content - .split(/\r?\n/) - .filter(Boolean) - .filter(line => !line.startsWith('#')) - .map(mapGitIgnorePatternTo(base)); -}; + options.unlink(p, er => { + if (er) { + if (er.code === "ENOENT") + return cb(null) + if (er.code === "EPERM") + return (isWindows) + ? fixWinEPERM(p, options, er, cb) + : rmdir(p, options, er, cb) + if (er.code === "EISDIR") + return rmdir(p, options, er, cb) + } + return cb(er) + }) + }) +} -const reduceIgnore = files => { - return files.reduce((ignores, file) => { - ignores.add(parseGitIgnore(file.content, { - cwd: file.cwd, - fileName: file.filePath - })); - return ignores; - }, gitIgnore()); -}; +const fixWinEPERM = (p, options, er, cb) => { + assert(p) + assert(options) + assert(typeof cb === 'function') + if (er) + assert(er instanceof Error) -const ensureAbsolutePathForCwd = (cwd, p) => { - if (path.isAbsolute(p)) { - if (p.startsWith(cwd)) { - return p; - } + options.chmod(p, 0o666, er2 => { + if (er2) + cb(er2.code === "ENOENT" ? null : er) + else + options.stat(p, (er3, stats) => { + if (er3) + cb(er3.code === "ENOENT" ? null : er) + else if (stats.isDirectory()) + rmdir(p, options, er, cb) + else + options.unlink(p, cb) + }) + }) +} - throw new Error(`Path ${p} is not in cwd ${cwd}`); - } +const fixWinEPERMSync = (p, options, er) => { + assert(p) + assert(options) + if (er) + assert(er instanceof Error) - return path.join(cwd, p); -}; + try { + options.chmodSync(p, 0o666) + } catch (er2) { + if (er2.code === "ENOENT") + return + else + throw er + } -const getIsIgnoredPredecate = (ignores, cwd) => { - return p => ignores.ignores(slash(path.relative(cwd, ensureAbsolutePathForCwd(cwd, p)))); -}; + let stats + try { + stats = options.statSync(p) + } catch (er3) { + if (er3.code === "ENOENT") + return + else + throw er + } -const getFile = async (file, cwd) => { - const filePath = path.join(cwd, file); - const content = await readFileP(filePath, 'utf8'); + if (stats.isDirectory()) + rmdirSync(p, options, er) + else + options.unlinkSync(p) +} - return { - cwd, - filePath, - content - }; -}; +const rmdir = (p, options, originalEr, cb) => { + assert(p) + assert(options) + if (originalEr) + assert(originalEr instanceof Error) + assert(typeof cb === 'function') -const getFileSync = (file, cwd) => { - const filePath = path.join(cwd, file); - const content = fs.readFileSync(filePath, 'utf8'); + // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) + // if we guessed wrong, and it's not a directory, then + // raise the original error. + options.rmdir(p, er => { + if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")) + rmkids(p, options, cb) + else if (er && er.code === "ENOTDIR") + cb(originalEr) + else + cb(er) + }) +} - return { - cwd, - filePath, - content - }; -}; +const rmkids = (p, options, cb) => { + assert(p) + assert(options) + assert(typeof cb === 'function') -const normalizeOptions = ({ - ignore = [], - cwd = process.cwd() -} = {}) => { - return {ignore, cwd}; -}; + options.readdir(p, (er, files) => { + if (er) + return cb(er) + let n = files.length + if (n === 0) + return options.rmdir(p, cb) + let errState + files.forEach(f => { + rimraf(path.join(p, f), options, er => { + if (errState) + return + if (er) + return cb(errState = er) + if (--n === 0) + options.rmdir(p, cb) + }) + }) + }) +} -module.exports = async options => { - options = normalizeOptions(options); +// this looks simpler, and is strictly *faster*, but will +// tie up the JavaScript thread and fail on excessively +// deep directory trees. +const rimrafSync = (p, options) => { + options = options || {} + defaults(options) - const paths = await fastGlob('**/.gitignore', { - ignore: DEFAULT_IGNORE.concat(options.ignore), - cwd: options.cwd - }); + assert(p, 'rimraf: missing path') + assert.equal(typeof p, 'string', 'rimraf: path should be a string') + assert(options, 'rimraf: missing options') + assert.equal(typeof options, 'object', 'rimraf: options should be object') - const files = await Promise.all(paths.map(file => getFile(file, options.cwd))); - const ignores = reduceIgnore(files); + let results - return getIsIgnoredPredecate(ignores, options.cwd); -}; + if (options.disableGlob || !glob.hasMagic(p)) { + results = [p] + } else { + try { + options.lstatSync(p) + results = [p] + } catch (er) { + results = glob.sync(p, options.glob) + } + } -module.exports.sync = options => { - options = normalizeOptions(options); + if (!results.length) + return - const paths = fastGlob.sync('**/.gitignore', { - ignore: DEFAULT_IGNORE.concat(options.ignore), - cwd: options.cwd - }); + for (let i = 0; i < results.length; i++) { + const p = results[i] - const files = paths.map(file => getFileSync(file, options.cwd)); - const ignores = reduceIgnore(files); + let st + try { + st = options.lstatSync(p) + } catch (er) { + if (er.code === "ENOENT") + return - return getIsIgnoredPredecate(ignores, options.cwd); -}; + // Windows can EPERM on stat. Life is suffering. + if (er.code === "EPERM" && isWindows) + fixWinEPERMSync(p, options, er) + } + try { + // sunos lets the root user unlink directories, which is... weird. + if (st && st.isDirectory()) + rmdirSync(p, options, null) + else + options.unlinkSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + if (er.code === "EPERM") + return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) + if (er.code !== "EISDIR") + throw er -/***/ }), -/* 665 */ -/***/ (function(module, exports) { + rmdirSync(p, options, er) + } + } +} -// A simple implementation of make-array -function makeArray (subject) { - return Array.isArray(subject) - ? subject - : [subject] +const rmdirSync = (p, options, originalEr) => { + assert(p) + assert(options) + if (originalEr) + assert(originalEr instanceof Error) + + try { + options.rmdirSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + if (er.code === "ENOTDIR") + throw originalEr + if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM") + rmkidsSync(p, options) + } } -const REGEX_TEST_BLANK_LINE = /^\s+$/ -const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/ -const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/ -const REGEX_SPLITALL_CRLF = /\r?\n/g -// /foo, -// ./foo, -// ../foo, -// . -// .. -const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/ +const rmkidsSync = (p, options) => { + assert(p) + assert(options) + options.readdirSync(p).forEach(f => rimrafSync(path.join(p, f), options)) -const SLASH = '/' -const KEY_IGNORE = typeof Symbol !== 'undefined' - ? Symbol.for('node-ignore') - /* istanbul ignore next */ - : 'node-ignore' + // We only end up here once we got ENOTEMPTY at least once, and + // at this point, we are guaranteed to have removed all the kids. + // So, we know that it won't be ENOENT or ENOTDIR or anything else. + // try really hard to delete stuff on windows, because it has a + // PROFOUNDLY annoying habit of not closing handles promptly when + // files are deleted, resulting in spurious ENOTEMPTY errors. + const retries = isWindows ? 100 : 1 + let i = 0 + do { + let threw = true + try { + const ret = options.rmdirSync(p, options) + threw = false + return ret + } finally { + if (++i < retries && threw) + continue + } + } while (true) +} -const define = (object, key, value) => - Object.defineProperty(object, key, {value}) +module.exports = rimraf +rimraf.sync = rimrafSync -const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g -// Sanitize the range of a regular expression -// The cases are complicated, see test cases for details -const sanitizeRange = range => range.replace( - REGEX_REGEXP_RANGE, - (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0) - ? match - // Invalid range (out of order) which is ok for gitignore rules but - // fatal for JavaScript regular expression, so eliminate it. - : '' -) +/***/ }), +/* 666 */ +/***/ (function(module, exports, __webpack_require__) { -// > If the pattern ends with a slash, -// > it is removed for the purpose of the following description, -// > but it would only find a match with a directory. -// > In other words, foo/ will match a directory foo and paths underneath it, -// > but will not match a regular file or a symbolic link foo -// > (this is consistent with the way how pathspec works in general in Git). -// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`' -// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call -// you could use option `mark: true` with `glob` +"use strict"; -// '`foo/`' should not continue with the '`..`' -const DEFAULT_REPLACER_PREFIX = [ +const AggregateError = __webpack_require__(667); - // > Trailing spaces are ignored unless they are quoted with backslash ("\") - [ - // (a\ ) -> (a ) - // (a ) -> (a) - // (a \ ) -> (a ) - /\\?\s+$/, - match => match.indexOf('\\') === 0 - ? ' ' - : '' - ], +module.exports = async ( + iterable, + mapper, + { + concurrency = Infinity, + stopOnError = true + } = {} +) => { + return new Promise((resolve, reject) => { + if (typeof mapper !== 'function') { + throw new TypeError('Mapper function is required'); + } - // replace (\ ) with ' ' - [ - /\\\s/g, - () => ' ' - ], + if (!(typeof concurrency === 'number' && concurrency >= 1)) { + throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${concurrency}\` (${typeof concurrency})`); + } - // Escape metacharacters - // which is written down by users but means special for regular expressions. + const ret = []; + const errors = []; + const iterator = iterable[Symbol.iterator](); + let isRejected = false; + let isIterableDone = false; + let resolvingCount = 0; + let currentIndex = 0; - // > There are 12 characters with special meanings: - // > - the backslash \, - // > - the caret ^, - // > - the dollar sign $, - // > - the period or dot ., - // > - the vertical bar or pipe symbol |, - // > - the question mark ?, - // > - the asterisk or star *, - // > - the plus sign +, - // > - the opening parenthesis (, - // > - the closing parenthesis ), - // > - and the opening square bracket [, - // > - the opening curly brace {, - // > These special characters are often called "metacharacters". - [ - /[\\^$.|*+(){]/g, - match => `\\${match}` - ], + const next = () => { + if (isRejected) { + return; + } - [ - // > [abc] matches any character inside the brackets - // > (in this case a, b, or c); - /\[([^\]/]*)($|\])/g, - (match, p1, p2) => p2 === ']' - ? `[${sanitizeRange(p1)}]` - : `\\${match}` - ], + const nextItem = iterator.next(); + const i = currentIndex; + currentIndex++; - [ - // > a question mark (?) matches a single character - /(?!\\)\?/g, - () => '[^/]' - ], + if (nextItem.done) { + isIterableDone = true; - // leading slash - [ + if (resolvingCount === 0) { + if (!stopOnError && errors.length !== 0) { + reject(new AggregateError(errors)); + } else { + resolve(ret); + } + } - // > A leading slash matches the beginning of the pathname. - // > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c". - // A leading slash matches the beginning of the pathname - /^\//, - () => '^' - ], + return; + } - // replace special metacharacter slash after the leading slash - [ - /\//g, - () => '\\/' - ], + resolvingCount++; - [ - // > A leading "**" followed by a slash means match in all directories. - // > For example, "**/foo" matches file or directory "foo" anywhere, - // > the same as pattern "foo". - // > "**/foo/bar" matches file or directory "bar" anywhere that is directly - // > under directory "foo". - // Notice that the '*'s have been replaced as '\\*' - /^\^*\\\*\\\*\\\//, + (async () => { + try { + const element = await nextItem.value; + ret[i] = await mapper(element, i); + resolvingCount--; + next(); + } catch (error) { + if (stopOnError) { + isRejected = true; + reject(error); + } else { + errors.push(error); + resolvingCount--; + next(); + } + } + })(); + }; - // '**/foo' <-> 'foo' - () => '^(?:.*\\/)?' - ] -] + for (let i = 0; i < concurrency; i++) { + next(); -const DEFAULT_REPLACER_SUFFIX = [ - // starting - [ - // there will be no leading '/' - // (which has been replaced by section "leading slash") - // If starts with '**', adding a '^' to the regular expression also works - /^(?=[^^])/, - function startingReplacer () { - return !/\/(?!$)/.test(this) - // > If the pattern does not contain a slash /, - // > Git treats it as a shell glob pattern - // Actually, if there is only a trailing slash, - // git also treats it as a shell glob pattern - ? '(?:^|\\/)' + if (isIterableDone) { + break; + } + } + }); +}; - // > Otherwise, Git treats the pattern as a shell glob suitable for - // > consumption by fnmatch(3) - : '^' - } - ], - // two globstars - [ - // Use lookahead assertions so that we could match more than one `'/**'` - /\\\/\\\*\\\*(?=\\\/|$)/g, +/***/ }), +/* 667 */ +/***/ (function(module, exports, __webpack_require__) { - // Zero, one or several directories - // should not use '*', or it will be replaced by the next replacer +"use strict"; - // Check if it is not the last `'/**'` - (_, index, str) => index + 6 < str.length +const indentString = __webpack_require__(668); +const cleanStack = __webpack_require__(669); - // case: /**/ - // > A slash followed by two consecutive asterisks then a slash matches - // > zero or more directories. - // > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on. - // '/**/' - ? '(?:\\/[^\\/]+)*' +const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, ''); - // case: /** - // > A trailing `"/**"` matches everything inside. +class AggregateError extends Error { + constructor(errors) { + if (!Array.isArray(errors)) { + throw new TypeError(`Expected input to be an Array, got ${typeof errors}`); + } - // #21: everything inside but it should not include the current folder - : '\\/.+' - ], + errors = [...errors].map(error => { + if (error instanceof Error) { + return error; + } - // intermediate wildcards - [ - // Never replace escaped '*' - // ignore rule '\*' will match the path '*' + if (error !== null && typeof error === 'object') { + // Handle plain error objects with message property and/or possibly other metadata + return Object.assign(new Error(error.message), error); + } - // 'abc.*/' -> go - // 'abc.*' -> skip this rule - /(^|[^\\]+)\\\*(?=.+)/g, + return new Error(error); + }); - // '*.js' matches '.js' - // '*.js' doesn't match 'abc' - (_, p1) => `${p1}[^\\/]*` - ], + let message = errors + .map(error => { + // The `stack` property is not standardized, so we can't assume it exists + return typeof error.stack === 'string' ? cleanInternalStack(cleanStack(error.stack)) : String(error); + }) + .join('\n'); + message = '\n' + indentString(message, 4); + super(message); - // trailing wildcard - [ - /(\^|\\\/)?\\\*$/, - (_, p1) => { - const prefix = p1 - // '\^': - // '/*' does not match '' - // '/*' does not match everything + this.name = 'AggregateError'; - // '\\\/': - // 'abc/*' does not match 'abc/' - ? `${p1}[^/]+` + Object.defineProperty(this, '_errors', {value: errors}); + } - // 'a*' matches 'a' - // 'a*' matches 'aa' - : '[^/]*' + * [Symbol.iterator]() { + for (const error of this._errors) { + yield error; + } + } +} - return `${prefix}(?=$|\\/$)` - } - ], +module.exports = AggregateError; - [ - // unescape - /\\\\\\/g, - () => '\\' - ] -] -const POSITIVE_REPLACERS = [ - ...DEFAULT_REPLACER_PREFIX, +/***/ }), +/* 668 */ +/***/ (function(module, exports, __webpack_require__) { - // 'f' - // matches - // - /f(end) - // - /f/ - // - (start)f(end) - // - (start)f/ - // doesn't match - // - oof - // - foo - // pseudo: - // -> (^|/)f(/|$) +"use strict"; - // ending - [ - // 'js' will not match 'js.' - // 'ab' will not match 'abc' - /(?:[^*/])$/, - // 'js*' will not match 'a.js' - // 'js/' will not match 'a.js' - // 'js' will match 'a.js' and 'a.js/' - match => `${match}(?=$|\\/)` - ], +module.exports = (string, count = 1, options) => { + options = { + indent: ' ', + includeEmptyLines: false, + ...options + }; - ...DEFAULT_REPLACER_SUFFIX -] + if (typeof string !== 'string') { + throw new TypeError( + `Expected \`input\` to be a \`string\`, got \`${typeof string}\`` + ); + } -const NEGATIVE_REPLACERS = [ - ...DEFAULT_REPLACER_PREFIX, + if (typeof count !== 'number') { + throw new TypeError( + `Expected \`count\` to be a \`number\`, got \`${typeof count}\`` + ); + } - // #24, #38 - // The MISSING rule of [gitignore docs](https://git-scm.com/docs/gitignore) - // A negative pattern without a trailing wildcard should not - // re-include the things inside that directory. + if (typeof options.indent !== 'string') { + throw new TypeError( + `Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\`` + ); + } - // eg: - // ['node_modules/*', '!node_modules'] - // should ignore `node_modules/a.js` - [ - /(?:[^*])$/, - match => `${match}(?=$|\\/$)` - ], + if (count === 0) { + return string; + } - ...DEFAULT_REPLACER_SUFFIX -] + const regex = options.includeEmptyLines ? /^/gm : /^(?!\s*$)/gm; -// A simple cache, because an ignore rule only has only one certain meaning -const regexCache = Object.create(null) + return string.replace(regex, options.indent.repeat(count)); +}; -// @param {pattern} -const makeRegex = (pattern, negative, ignorecase) => { - const r = regexCache[pattern] - if (r) { - return r - } - const replacers = negative - ? NEGATIVE_REPLACERS - : POSITIVE_REPLACERS +/***/ }), +/* 669 */ +/***/ (function(module, exports, __webpack_require__) { - const source = replacers.reduce( - (prev, current) => prev.replace(current[0], current[1].bind(pattern)), - pattern - ) +"use strict"; - return regexCache[pattern] = ignorecase - ? new RegExp(source, 'i') - : new RegExp(source) -} +const os = __webpack_require__(364); -const isString = subject => typeof subject === 'string' +const extractPathRegex = /\s+at.*(?:\(|\s)(.*)\)?/; +const pathRegex = /^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)\.js:\d+:\d+)|native)/; +const homeDir = typeof os.homedir === 'undefined' ? '' : os.homedir(); -// > A blank line matches no files, so it can serve as a separator for readability. -const checkPattern = pattern => pattern - && isString(pattern) - && !REGEX_TEST_BLANK_LINE.test(pattern) +module.exports = (stack, options) => { + options = Object.assign({pretty: false}, options); - // > A line starting with # serves as a comment. - && pattern.indexOf('#') !== 0 + return stack.replace(/\\/g, '/') + .split('\n') + .filter(line => { + const pathMatches = line.match(extractPathRegex); + if (pathMatches === null || !pathMatches[1]) { + return true; + } -const splitPattern = pattern => pattern.split(REGEX_SPLITALL_CRLF) + const match = pathMatches[1]; -class IgnoreRule { - constructor ( - origin, - pattern, - negative, - regex - ) { - this.origin = origin - this.pattern = pattern - this.negative = negative - this.regex = regex - } -} + // Electron + if ( + match.includes('.app/Contents/Resources/electron.asar') || + match.includes('.app/Contents/Resources/default_app.asar') + ) { + return false; + } -const createRule = (pattern, ignorecase) => { - const origin = pattern - let negative = false + return !pathRegex.test(match); + }) + .filter(line => line.trim() !== '') + .map(line => { + if (options.pretty) { + return line.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir, '~'))); + } - // > An optional prefix "!" which negates the pattern; - if (pattern.indexOf('!') === 0) { - negative = true - pattern = pattern.substr(1) - } + return line; + }) + .join('\n'); +}; - pattern = pattern - // > Put a backslash ("\") in front of the first "!" for patterns that - // > begin with a literal "!", for example, `"\!important!.txt"`. - .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!') - // > Put a backslash ("\") in front of the first hash for patterns that - // > begin with a hash. - .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#') - const regex = makeRegex(pattern, negative, ignorecase) +/***/ }), +/* 670 */ +/***/ (function(module, exports, __webpack_require__) { - return new IgnoreRule( - origin, - pattern, - negative, - regex - ) -} +"use strict"; -const throwError = (message, Ctor) => { - throw new Ctor(message) -} +const chalk = __webpack_require__(671); +const cliCursor = __webpack_require__(675); +const cliSpinners = __webpack_require__(679); +const logSymbols = __webpack_require__(681); -const checkPath = (path, originalPath, doThrow) => { - if (!isString(path)) { - return doThrow( - `path must be a string, but got \`${originalPath}\``, - TypeError - ) - } +class Ora { + constructor(options) { + if (typeof options === 'string') { + options = { + text: options + }; + } - // We don't know if we should ignore '', so throw - if (!path) { - return doThrow(`path must not be empty`, TypeError) - } + this.options = Object.assign({ + text: '', + color: 'cyan', + stream: process.stderr + }, options); - // Check if it is a relative path - if (checkPath.isNotRelative(path)) { - const r = '`path.relative()`d' - return doThrow( - `path should be a ${r} string, but got "${originalPath}"`, - RangeError - ) - } + const sp = this.options.spinner; + this.spinner = typeof sp === 'object' ? sp : (process.platform === 'win32' ? cliSpinners.line : (cliSpinners[sp] || cliSpinners.dots)); // eslint-disable-line no-nested-ternary - return true -} + if (this.spinner.frames === undefined) { + throw new Error('Spinner must define `frames`'); + } -const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path) + this.text = this.options.text; + this.color = this.options.color; + this.interval = this.options.interval || this.spinner.interval || 100; + this.stream = this.options.stream; + this.id = null; + this.frameIndex = 0; + this.enabled = typeof this.options.enabled === 'boolean' ? this.options.enabled : ((this.stream && this.stream.isTTY) && !process.env.CI); + } + frame() { + const frames = this.spinner.frames; + let frame = frames[this.frameIndex]; -checkPath.isNotRelative = isNotRelative -checkPath.convert = p => p + if (this.color) { + frame = chalk[this.color](frame); + } -class Ignore { - constructor ({ - ignorecase = true - } = {}) { - this._rules = [] - this._ignorecase = ignorecase - define(this, KEY_IGNORE, true) - this._initCache() - } + this.frameIndex = ++this.frameIndex % frames.length; - _initCache () { - this._ignoreCache = Object.create(null) - this._testCache = Object.create(null) - } + return frame + ' ' + this.text; + } + clear() { + if (!this.enabled) { + return this; + } - _addPattern (pattern) { - // #32 - if (pattern && pattern[KEY_IGNORE]) { - this._rules = this._rules.concat(pattern._rules) - this._added = true - return - } + this.stream.clearLine(); + this.stream.cursorTo(0); - if (checkPattern(pattern)) { - const rule = createRule(pattern, this._ignorecase) - this._added = true - this._rules.push(rule) - } - } + return this; + } + render() { + this.clear(); + this.stream.write(this.frame()); - // @param {Array | string | Ignore} pattern - add (pattern) { - this._added = false + return this; + } + start(text) { + if (text) { + this.text = text; + } - makeArray( - isString(pattern) - ? splitPattern(pattern) - : pattern - ).forEach(this._addPattern, this) + if (!this.enabled || this.id) { + return this; + } - // Some rules have just added to the ignore, - // making the behavior changed. - if (this._added) { - this._initCache() - } + cliCursor.hide(this.stream); + this.render(); + this.id = setInterval(this.render.bind(this), this.interval); - return this - } + return this; + } + stop() { + if (!this.enabled) { + return this; + } - // legacy - addPattern (pattern) { - return this.add(pattern) - } + clearInterval(this.id); + this.id = null; + this.frameIndex = 0; + this.clear(); + cliCursor.show(this.stream); - // | ignored : unignored - // negative | 0:0 | 0:1 | 1:0 | 1:1 - // -------- | ------- | ------- | ------- | -------- - // 0 | TEST | TEST | SKIP | X - // 1 | TESTIF | SKIP | TEST | X + return this; + } + succeed(text) { + return this.stopAndPersist({symbol: logSymbols.success, text}); + } + fail(text) { + return this.stopAndPersist({symbol: logSymbols.error, text}); + } + warn(text) { + return this.stopAndPersist({symbol: logSymbols.warning, text}); + } + info(text) { + return this.stopAndPersist({symbol: logSymbols.info, text}); + } + stopAndPersist(options) { + if (!this.enabled) { + return this; + } - // - SKIP: always skip - // - TEST: always test - // - TESTIF: only test if checkUnignored - // - X: that never happen + // Legacy argument + // TODO: Deprecate sometime in the future + if (typeof options === 'string') { + options = { + symbol: options + }; + } - // @param {boolean} whether should check if the path is unignored, - // setting `checkUnignored` to `false` could reduce additional - // path matching. + options = options || {}; - // @returns {TestResult} true if a file is ignored - _testOne (path, checkUnignored) { - let ignored = false - let unignored = false + this.stop(); + this.stream.write(`${options.symbol || ' '} ${options.text || this.text}\n`); - this._rules.forEach(rule => { - const {negative} = rule - if ( - unignored === negative && ignored !== unignored - || negative && !ignored && !unignored && !checkUnignored - ) { - return - } + return this; + } +} - const matched = rule.regex.test(path) +module.exports = function (opts) { + return new Ora(opts); +}; - if (matched) { - ignored = !negative - unignored = negative - } - }) +module.exports.promise = (action, options) => { + if (typeof action.then !== 'function') { + throw new TypeError('Parameter `action` must be a Promise'); + } - return { - ignored, - unignored - } - } + const spinner = new Ora(options); + spinner.start(); - // @returns {TestResult} - _test (originalPath, cache, checkUnignored, slices) { - const path = originalPath - // Supports nullable path - && checkPath.convert(originalPath) + action.then( + () => { + spinner.succeed(); + }, + () => { + spinner.fail(); + } + ); - checkPath(path, originalPath, throwError) + return spinner; +}; - return this._t(path, cache, checkUnignored, slices) - } - _t (path, cache, checkUnignored, slices) { - if (path in cache) { - return cache[path] - } +/***/ }), +/* 671 */ +/***/ (function(module, exports, __webpack_require__) { - if (!slices) { - // path/to/a.js - // ['path', 'to', 'a.js'] - slices = path.split(SLASH) - } +"use strict"; - slices.pop() +const escapeStringRegexp = __webpack_require__(387); +const ansiStyles = __webpack_require__(672); +const stdoutColor = __webpack_require__(673).stdout; - // If the path has no parent directory, just test it - if (!slices.length) { - return cache[path] = this._testOne(path, checkUnignored) - } +const template = __webpack_require__(674); - const parent = this._t( - slices.join(SLASH) + SLASH, - cache, - checkUnignored, - slices - ) +const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); - // If the path contains a parent directory, check the parent first - return cache[path] = parent.ignored - // > It is not possible to re-include a file if a parent directory of - // > that file is excluded. - ? parent - : this._testOne(path, checkUnignored) - } +// `supportsColor.level` → `ansiStyles.color[name]` mapping +const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; - ignores (path) { - return this._test(path, this._ignoreCache, false).ignored - } +// `color-convert` models to exclude from the Chalk API due to conflicts and such +const skipModels = new Set(['gray']); - createFilter () { - return path => !this.ignores(path) - } +const styles = Object.create(null); - filter (paths) { - return makeArray(paths).filter(this.createFilter()) - } +function applyOptions(obj, options) { + options = options || {}; - // @returns {TestResult} - test (path) { - return this._test(path, this._testCache, true) - } + // Detect level if not set manually + const scLevel = stdoutColor ? stdoutColor.level : 0; + obj.level = options.level === undefined ? scLevel : options.level; + obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; } -const factory = options => new Ignore(options) +function Chalk(options) { + // We check for this.template here since calling `chalk.constructor()` + // by itself will have a `this` of a previously constructed chalk object + if (!this || !(this instanceof Chalk) || this.template) { + const chalk = {}; + applyOptions(chalk, options); -const returnFalse = () => false + chalk.template = function () { + const args = [].slice.call(arguments); + return chalkTag.apply(null, [chalk.template].concat(args)); + }; -const isPathValid = path => - checkPath(path && checkPath.convert(path), path, returnFalse) + Object.setPrototypeOf(chalk, Chalk.prototype); + Object.setPrototypeOf(chalk.template, chalk); -factory.isPathValid = isPathValid + chalk.template.constructor = Chalk; -// Fixes typescript -factory.default = factory + return chalk.template; + } -module.exports = factory + applyOptions(this, options); +} -// Windows -// -------------------------------------------------------------- -/* istanbul ignore if */ -if ( - // Detect `process` so that it can run in browsers. - typeof process !== 'undefined' - && ( - process.env && process.env.IGNORE_TEST_WIN32 - || process.platform === 'win32' - ) -) { - /* eslint no-control-regex: "off" */ - const makePosix = str => /^\\\\\?\\/.test(str) - || /["<>|\u0000-\u001F]+/u.test(str) - ? str - : str.replace(/\\/g, '/') +// Use bright blue on Windows as the normal blue color is illegible +if (isSimpleWindowsTerm) { + ansiStyles.blue.open = '\u001B[94m'; +} - checkPath.convert = makePosix +for (const key of Object.keys(ansiStyles)) { + ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); - // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/' - // 'd:\\foo' - const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i - checkPath.isNotRelative = path => - REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path) - || isNotRelative(path) + styles[key] = { + get() { + const codes = ansiStyles[key]; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); + } + }; } +styles.visible = { + get() { + return build.call(this, this._styles || [], true, 'visible'); + } +}; -/***/ }), -/* 666 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; +ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); +for (const model of Object.keys(ansiStyles.color.ansi)) { + if (skipModels.has(model)) { + continue; + } -module.exports = path => { - const isExtendedLengthPath = /^\\\\\?\\/.test(path); - const hasNonAscii = /[^\u0000-\u0080]+/.test(path); // eslint-disable-line no-control-regex + styles[model] = { + get() { + const level = this.level; + return function () { + const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); + const codes = { + open, + close: ansiStyles.color.close, + closeRe: ansiStyles.color.closeRe + }; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + }; + } + }; +} - if (isExtendedLengthPath || hasNonAscii) { - return path; +ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); +for (const model of Object.keys(ansiStyles.bgColor.ansi)) { + if (skipModels.has(model)) { + continue; } - return path.replace(/\\/g, '/'); -}; - + const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); + styles[bgModel] = { + get() { + const level = this.level; + return function () { + const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); + const codes = { + open, + close: ansiStyles.bgColor.close, + closeRe: ansiStyles.bgColor.closeRe + }; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + }; + } + }; +} -/***/ }), -/* 667 */ -/***/ (function(module, exports, __webpack_require__) { +const proto = Object.defineProperties(() => {}, styles); -"use strict"; +function build(_styles, _empty, key) { + const builder = function () { + return applyStyle.apply(builder, arguments); + }; -const {Transform} = __webpack_require__(27); + builder._styles = _styles; + builder._empty = _empty; -class ObjectTransform extends Transform { - constructor() { - super({ - objectMode: true - }); - } -} + const self = this; -class FilterStream extends ObjectTransform { - constructor(filter) { - super(); - this._filter = filter; - } + Object.defineProperty(builder, 'level', { + enumerable: true, + get() { + return self.level; + }, + set(level) { + self.level = level; + } + }); - _transform(data, encoding, callback) { - if (this._filter(data)) { - this.push(data); + Object.defineProperty(builder, 'enabled', { + enumerable: true, + get() { + return self.enabled; + }, + set(enabled) { + self.enabled = enabled; } + }); - callback(); - } + // See below for fix regarding invisible grey/dim combination on Windows + builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; + + // `__proto__` is used because we must return a function, but there is + // no way to create a function with a different prototype + builder.__proto__ = proto; // eslint-disable-line no-proto + + return builder; } -class UniqueStream extends ObjectTransform { - constructor() { - super(); - this._pushed = new Set(); +function applyStyle() { + // Support varags, but simply cast to string in case there's only one arg + const args = arguments; + const argsLen = args.length; + let str = String(arguments[0]); + + if (argsLen === 0) { + return ''; } - _transform(data, encoding, callback) { - if (!this._pushed.has(data)) { - this.push(data); - this._pushed.add(data); + if (argsLen > 1) { + // Don't slice `arguments`, it prevents V8 optimizations + for (let a = 1; a < argsLen; a++) { + str += ' ' + args[a]; } + } - callback(); + if (!this.enabled || this.level <= 0 || !str) { + return this._empty ? '' : str; } -} -module.exports = { - FilterStream, - UniqueStream -}; + // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, + // see https://github.com/chalk/chalk/issues/58 + // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. + const originalDim = ansiStyles.dim.open; + if (isSimpleWindowsTerm && this.hasGrey) { + ansiStyles.dim.open = ''; + } + for (const code of this._styles.slice().reverse()) { + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code + // will be colored, and the rest will simply be 'plain'. + str = code.open + str.replace(code.closeRe, code.open) + code.close; -/***/ }), -/* 668 */ -/***/ (function(module, exports, __webpack_require__) { + // Close the styling before a linebreak and reopen + // after next line to fix a bleed issue on macOS + // https://github.com/chalk/chalk/pull/92 + str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); + } -"use strict"; + // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue + ansiStyles.dim.open = originalDim; -const path = __webpack_require__(16); + return str; +} -module.exports = path_ => { - let cwd = process.cwd(); +function chalkTag(chalk, strings) { + if (!Array.isArray(strings)) { + // If chalk() was called by itself or with a string, + // return the string itself as a string. + return [].slice.call(arguments, 1).join(' '); + } - path_ = path.resolve(path_); + const args = [].slice.call(arguments, 2); + const parts = [strings.raw[0]]; - if (process.platform === 'win32') { - cwd = cwd.toLowerCase(); - path_ = path_.toLowerCase(); + for (let i = 1; i < strings.length; i++) { + parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); + parts.push(String(strings.raw[i])); } - return path_ === cwd; -}; + return template(chalk, parts.join('')); +} + +Object.defineProperties(Chalk.prototype, styles); + +module.exports = Chalk(); // eslint-disable-line new-cap +module.exports.supportsColor = stdoutColor; +module.exports.default = module.exports; // For TypeScript /***/ }), -/* 669 */ +/* 672 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +/* WEBPACK VAR INJECTION */(function(module) { +const colorConvert = __webpack_require__(389); -const path = __webpack_require__(16); - -module.exports = (childPath, parentPath) => { - childPath = path.resolve(childPath); - parentPath = path.resolve(parentPath); - - if (process.platform === 'win32') { - childPath = childPath.toLowerCase(); - parentPath = parentPath.toLowerCase(); - } - - if (childPath === parentPath) { - return false; - } - - childPath += path.sep; - parentPath += path.sep; +const wrapAnsi16 = (fn, offset) => function () { + const code = fn.apply(colorConvert, arguments); + return `\u001B[${code + offset}m`; +}; - return childPath.startsWith(parentPath); +const wrapAnsi256 = (fn, offset) => function () { + const code = fn.apply(colorConvert, arguments); + return `\u001B[${38 + offset};5;${code}m`; }; +const wrapAnsi16m = (fn, offset) => function () { + const rgb = fn.apply(colorConvert, arguments); + return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; +}; -/***/ }), -/* 670 */ -/***/ (function(module, exports, __webpack_require__) { +function assembleStyles() { + const codes = new Map(); + const styles = { + modifier: { + reset: [0, 0], + // 21 isn't widely supported and 22 does the same thing + bold: [1, 22], + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29] + }, + color: { + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], + gray: [90, 39], -const assert = __webpack_require__(30) -const path = __webpack_require__(16) -const fs = __webpack_require__(23) -let glob = undefined -try { - glob = __webpack_require__(591) -} catch (_err) { - // treat glob as optional. -} + // Bright color + redBright: [91, 39], + greenBright: [92, 39], + yellowBright: [93, 39], + blueBright: [94, 39], + magentaBright: [95, 39], + cyanBright: [96, 39], + whiteBright: [97, 39] + }, + bgColor: { + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], -const defaultGlobOpts = { - nosort: true, - silent: true -} + // Bright color + bgBlackBright: [100, 49], + bgRedBright: [101, 49], + bgGreenBright: [102, 49], + bgYellowBright: [103, 49], + bgBlueBright: [104, 49], + bgMagentaBright: [105, 49], + bgCyanBright: [106, 49], + bgWhiteBright: [107, 49] + } + }; -// for EMFILE handling -let timeout = 0 + // Fix humans + styles.color.grey = styles.color.gray; -const isWindows = (process.platform === "win32") + for (const groupName of Object.keys(styles)) { + const group = styles[groupName]; -const defaults = options => { - const methods = [ - 'unlink', - 'chmod', - 'stat', - 'lstat', - 'rmdir', - 'readdir' - ] - methods.forEach(m => { - options[m] = options[m] || fs[m] - m = m + 'Sync' - options[m] = options[m] || fs[m] - }) + for (const styleName of Object.keys(group)) { + const style = group[styleName]; - options.maxBusyTries = options.maxBusyTries || 3 - options.emfileWait = options.emfileWait || 1000 - if (options.glob === false) { - options.disableGlob = true - } - if (options.disableGlob !== true && glob === undefined) { - throw Error('glob dependency not found, set `options.disableGlob = true` if intentional') - } - options.disableGlob = options.disableGlob || false - options.glob = options.glob || defaultGlobOpts -} + styles[styleName] = { + open: `\u001B[${style[0]}m`, + close: `\u001B[${style[1]}m` + }; -const rimraf = (p, options, cb) => { - if (typeof options === 'function') { - cb = options - options = {} - } + group[styleName] = styles[styleName]; - assert(p, 'rimraf: missing path') - assert.equal(typeof p, 'string', 'rimraf: path should be a string') - assert.equal(typeof cb, 'function', 'rimraf: callback function required') - assert(options, 'rimraf: invalid options argument provided') - assert.equal(typeof options, 'object', 'rimraf: options should be object') + codes.set(style[0], style[1]); + } - defaults(options) + Object.defineProperty(styles, groupName, { + value: group, + enumerable: false + }); - let busyTries = 0 - let errState = null - let n = 0 + Object.defineProperty(styles, 'codes', { + value: codes, + enumerable: false + }); + } - const next = (er) => { - errState = errState || er - if (--n === 0) - cb(errState) - } + const ansi2ansi = n => n; + const rgb2rgb = (r, g, b) => [r, g, b]; - const afterGlob = (er, results) => { - if (er) - return cb(er) + styles.color.close = '\u001B[39m'; + styles.bgColor.close = '\u001B[49m'; - n = results.length - if (n === 0) - return cb() + styles.color.ansi = { + ansi: wrapAnsi16(ansi2ansi, 0) + }; + styles.color.ansi256 = { + ansi256: wrapAnsi256(ansi2ansi, 0) + }; + styles.color.ansi16m = { + rgb: wrapAnsi16m(rgb2rgb, 0) + }; - results.forEach(p => { - const CB = (er) => { - if (er) { - if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") && - busyTries < options.maxBusyTries) { - busyTries ++ - // try again, with the same exact callback as this one. - return setTimeout(() => rimraf_(p, options, CB), busyTries * 100) - } + styles.bgColor.ansi = { + ansi: wrapAnsi16(ansi2ansi, 10) + }; + styles.bgColor.ansi256 = { + ansi256: wrapAnsi256(ansi2ansi, 10) + }; + styles.bgColor.ansi16m = { + rgb: wrapAnsi16m(rgb2rgb, 10) + }; - // this one won't happen if graceful-fs is used. - if (er.code === "EMFILE" && timeout < options.emfileWait) { - return setTimeout(() => rimraf_(p, options, CB), timeout ++) - } + for (let key of Object.keys(colorConvert)) { + if (typeof colorConvert[key] !== 'object') { + continue; + } - // already gone - if (er.code === "ENOENT") er = null - } + const suite = colorConvert[key]; - timeout = 0 - next(er) - } - rimraf_(p, options, CB) - }) - } + if (key === 'ansi16') { + key = 'ansi'; + } - if (options.disableGlob || !glob.hasMagic(p)) - return afterGlob(null, [p]) + if ('ansi16' in suite) { + styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); + styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); + } - options.lstat(p, (er, stat) => { - if (!er) - return afterGlob(null, [p]) + if ('ansi256' in suite) { + styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); + styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); + } - glob(p, options.glob, afterGlob) - }) + if ('rgb' in suite) { + styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); + styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); + } + } + return styles; } -// Two possible strategies. -// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR -// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR -// -// Both result in an extra syscall when you guess wrong. However, there -// are likely far more normal files in the world than directories. This -// is based on the assumption that a the average number of files per -// directory is >= 1. -// -// If anyone ever complains about this, then I guess the strategy could -// be made configurable somehow. But until then, YAGNI. -const rimraf_ = (p, options, cb) => { - assert(p) - assert(options) - assert(typeof cb === 'function') +// Make the export immutable +Object.defineProperty(module, 'exports', { + enumerable: true, + get: assembleStyles +}); - // sunos lets the root user unlink directories, which is... weird. - // so we have to lstat here and make sure it's not a dir. - options.lstat(p, (er, st) => { - if (er && er.code === "ENOENT") - return cb(null) +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(11)(module))) - // Windows can EPERM on stat. Life is suffering. - if (er && er.code === "EPERM" && isWindows) - fixWinEPERM(p, options, er, cb) +/***/ }), +/* 673 */ +/***/ (function(module, exports, __webpack_require__) { - if (st && st.isDirectory()) - return rmdir(p, options, er, cb) +"use strict"; - options.unlink(p, er => { - if (er) { - if (er.code === "ENOENT") - return cb(null) - if (er.code === "EPERM") - return (isWindows) - ? fixWinEPERM(p, options, er, cb) - : rmdir(p, options, er, cb) - if (er.code === "EISDIR") - return rmdir(p, options, er, cb) - } - return cb(er) - }) - }) -} +const os = __webpack_require__(364); +const hasFlag = __webpack_require__(394); -const fixWinEPERM = (p, options, er, cb) => { - assert(p) - assert(options) - assert(typeof cb === 'function') - if (er) - assert(er instanceof Error) +const env = process.env; - options.chmod(p, 0o666, er2 => { - if (er2) - cb(er2.code === "ENOENT" ? null : er) - else - options.stat(p, (er3, stats) => { - if (er3) - cb(er3.code === "ENOENT" ? null : er) - else if (stats.isDirectory()) - rmdir(p, options, er, cb) - else - options.unlink(p, cb) - }) - }) +let forceColor; +if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false')) { + forceColor = false; +} else if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + forceColor = true; +} +if ('FORCE_COLOR' in env) { + forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; } -const fixWinEPERMSync = (p, options, er) => { - assert(p) - assert(options) - if (er) - assert(er instanceof Error) +function translateLevel(level) { + if (level === 0) { + return false; + } - try { - options.chmodSync(p, 0o666) - } catch (er2) { - if (er2.code === "ENOENT") - return - else - throw er - } + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; +} - let stats - try { - stats = options.statSync(p) - } catch (er3) { - if (er3.code === "ENOENT") - return - else - throw er - } +function supportsColor(stream) { + if (forceColor === false) { + return 0; + } - if (stats.isDirectory()) - rmdirSync(p, options, er) - else - options.unlinkSync(p) -} + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } -const rmdir = (p, options, originalEr, cb) => { - assert(p) - assert(options) - if (originalEr) - assert(originalEr instanceof Error) - assert(typeof cb === 'function') + if (hasFlag('color=256')) { + return 2; + } - // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) - // if we guessed wrong, and it's not a directory, then - // raise the original error. - options.rmdir(p, er => { - if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")) - rmkids(p, options, cb) - else if (er && er.code === "ENOTDIR") - cb(originalEr) - else - cb(er) - }) -} + if (stream && !stream.isTTY && forceColor !== true) { + // VS code debugger doesn't have isTTY set + if (env.VSCODE_PID) { + return 1; + } + return 0; + } -const rmkids = (p, options, cb) => { - assert(p) - assert(options) - assert(typeof cb === 'function') + const min = forceColor ? 1 : 0; - options.readdir(p, (er, files) => { - if (er) - return cb(er) - let n = files.length - if (n === 0) - return options.rmdir(p, cb) - let errState - files.forEach(f => { - rimraf(path.join(p, f), options, er => { - if (errState) - return - if (er) - return cb(errState = er) - if (--n === 0) - options.rmdir(p, cb) - }) - }) - }) -} + if (process.platform === 'win32') { + // Node.js 7.5.0 is the first version of Node.js to include a patch to + // libuv that enables 256 color output on Windows. Anything earlier and it + // won't work. However, here we target Node.js 8 at minimum as it is an LTS + // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows + // release that supports 256 colors. Windows 10 build 14931 is the first release + // that supports 16m/TrueColor. + const osRelease = os.release().split('.'); + if ( + Number(process.versions.node.split('.')[0]) >= 8 && + Number(osRelease[0]) >= 10 && + Number(osRelease[2]) >= 10586 + ) { + return Number(osRelease[2]) >= 14931 ? 3 : 2; + } -// this looks simpler, and is strictly *faster*, but will -// tie up the JavaScript thread and fail on excessively -// deep directory trees. -const rimrafSync = (p, options) => { - options = options || {} - defaults(options) + return 1; + } - assert(p, 'rimraf: missing path') - assert.equal(typeof p, 'string', 'rimraf: path should be a string') - assert(options, 'rimraf: missing options') - assert.equal(typeof options, 'object', 'rimraf: options should be object') + if ('CI' in env) { + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } - let results + return min; + } - if (options.disableGlob || !glob.hasMagic(p)) { - results = [p] - } else { - try { - options.lstatSync(p) - results = [p] - } catch (er) { - results = glob.sync(p, options.glob) - } - } + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } - if (!results.length) - return + if (env.COLORTERM === 'truecolor') { + return 3; + } - for (let i = 0; i < results.length; i++) { - const p = results[i] + if ('TERM_PROGRAM' in env) { + const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - let st - try { - st = options.lstatSync(p) - } catch (er) { - if (er.code === "ENOENT") - return + switch (env.TERM_PROGRAM) { + case 'iTerm.app': + return version >= 3 ? 3 : 2; + case 'Apple_Terminal': + return 2; + // No default + } + } - // Windows can EPERM on stat. Life is suffering. - if (er.code === "EPERM" && isWindows) - fixWinEPERMSync(p, options, er) - } + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } - try { - // sunos lets the root user unlink directories, which is... weird. - if (st && st.isDirectory()) - rmdirSync(p, options, null) - else - options.unlinkSync(p) - } catch (er) { - if (er.code === "ENOENT") - return - if (er.code === "EPERM") - return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) - if (er.code !== "EISDIR") - throw er + if (/^screen|^xterm|^vt100|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } - rmdirSync(p, options, er) - } - } -} + if ('COLORTERM' in env) { + return 1; + } -const rmdirSync = (p, options, originalEr) => { - assert(p) - assert(options) - if (originalEr) - assert(originalEr instanceof Error) + if (env.TERM === 'dumb') { + return min; + } - try { - options.rmdirSync(p) - } catch (er) { - if (er.code === "ENOENT") - return - if (er.code === "ENOTDIR") - throw originalEr - if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM") - rmkidsSync(p, options) - } + return min; } -const rmkidsSync = (p, options) => { - assert(p) - assert(options) - options.readdirSync(p).forEach(f => rimrafSync(path.join(p, f), options)) - - // We only end up here once we got ENOTEMPTY at least once, and - // at this point, we are guaranteed to have removed all the kids. - // So, we know that it won't be ENOENT or ENOTDIR or anything else. - // try really hard to delete stuff on windows, because it has a - // PROFOUNDLY annoying habit of not closing handles promptly when - // files are deleted, resulting in spurious ENOTEMPTY errors. - const retries = isWindows ? 100 : 1 - let i = 0 - do { - let threw = true - try { - const ret = options.rmdirSync(p, options) - threw = false - return ret - } finally { - if (++i < retries && threw) - continue - } - } while (true) +function getSupportLevel(stream) { + const level = supportsColor(stream); + return translateLevel(level); } -module.exports = rimraf -rimraf.sync = rimrafSync +module.exports = { + supportsColor: getSupportLevel, + stdout: getSupportLevel(process.stdout), + stderr: getSupportLevel(process.stderr) +}; /***/ }), -/* 671 */ +/* 674 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const AggregateError = __webpack_require__(672); - -module.exports = async ( - iterable, - mapper, - { - concurrency = Infinity, - stopOnError = true - } = {} -) => { - return new Promise((resolve, reject) => { - if (typeof mapper !== 'function') { - throw new TypeError('Mapper function is required'); - } - - if (!(typeof concurrency === 'number' && concurrency >= 1)) { - throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${concurrency}\` (${typeof concurrency})`); - } +const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; +const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; +const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; +const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; - const ret = []; - const errors = []; - const iterator = iterable[Symbol.iterator](); - let isRejected = false; - let isIterableDone = false; - let resolvingCount = 0; - let currentIndex = 0; +const ESCAPES = new Map([ + ['n', '\n'], + ['r', '\r'], + ['t', '\t'], + ['b', '\b'], + ['f', '\f'], + ['v', '\v'], + ['0', '\0'], + ['\\', '\\'], + ['e', '\u001B'], + ['a', '\u0007'] +]); - const next = () => { - if (isRejected) { - return; - } +function unescape(c) { + if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { + return String.fromCharCode(parseInt(c.slice(1), 16)); + } - const nextItem = iterator.next(); - const i = currentIndex; - currentIndex++; + return ESCAPES.get(c) || c; +} - if (nextItem.done) { - isIterableDone = true; +function parseArguments(name, args) { + const results = []; + const chunks = args.trim().split(/\s*,\s*/g); + let matches; - if (resolvingCount === 0) { - if (!stopOnError && errors.length !== 0) { - reject(new AggregateError(errors)); - } else { - resolve(ret); - } - } + for (const chunk of chunks) { + if (!isNaN(chunk)) { + results.push(Number(chunk)); + } else if ((matches = chunk.match(STRING_REGEX))) { + results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); + } else { + throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); + } + } - return; - } + return results; +} - resolvingCount++; +function parseStyle(style) { + STYLE_REGEX.lastIndex = 0; - (async () => { - try { - const element = await nextItem.value; - ret[i] = await mapper(element, i); - resolvingCount--; - next(); - } catch (error) { - if (stopOnError) { - isRejected = true; - reject(error); - } else { - errors.push(error); - resolvingCount--; - next(); - } - } - })(); - }; + const results = []; + let matches; - for (let i = 0; i < concurrency; i++) { - next(); + while ((matches = STYLE_REGEX.exec(style)) !== null) { + const name = matches[1]; - if (isIterableDone) { - break; - } + if (matches[2]) { + const args = parseArguments(name, matches[2]); + results.push([name].concat(args)); + } else { + results.push([name]); } - }); -}; - - -/***/ }), -/* 672 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; + } -const indentString = __webpack_require__(673); -const cleanStack = __webpack_require__(674); + return results; +} -const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, ''); +function buildStyle(chalk, styles) { + const enabled = {}; -class AggregateError extends Error { - constructor(errors) { - if (!Array.isArray(errors)) { - throw new TypeError(`Expected input to be an Array, got ${typeof errors}`); + for (const layer of styles) { + for (const style of layer.styles) { + enabled[style[0]] = layer.inverse ? null : style.slice(1); } + } - errors = [...errors].map(error => { - if (error instanceof Error) { - return error; + let current = chalk; + for (const styleName of Object.keys(enabled)) { + if (Array.isArray(enabled[styleName])) { + if (!(styleName in current)) { + throw new Error(`Unknown Chalk style: ${styleName}`); } - if (error !== null && typeof error === 'object') { - // Handle plain error objects with message property and/or possibly other metadata - return Object.assign(new Error(error.message), error); + if (enabled[styleName].length > 0) { + current = current[styleName].apply(current, enabled[styleName]); + } else { + current = current[styleName]; } + } + } - return new Error(error); - }); - - let message = errors - .map(error => { - // The `stack` property is not standardized, so we can't assume it exists - return typeof error.stack === 'string' ? cleanInternalStack(cleanStack(error.stack)) : String(error); - }) - .join('\n'); - message = '\n' + indentString(message, 4); - super(message); + return current; +} - this.name = 'AggregateError'; +module.exports = (chalk, tmp) => { + const styles = []; + const chunks = []; + let chunk = []; - Object.defineProperty(this, '_errors', {value: errors}); - } + // eslint-disable-next-line max-params + tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { + if (escapeChar) { + chunk.push(unescape(escapeChar)); + } else if (style) { + const str = chunk.join(''); + chunk = []; + chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); + styles.push({inverse, styles: parseStyle(style)}); + } else if (close) { + if (styles.length === 0) { + throw new Error('Found extraneous } in Chalk template literal'); + } - * [Symbol.iterator]() { - for (const error of this._errors) { - yield error; + chunks.push(buildStyle(chalk, styles)(chunk.join(''))); + chunk = []; + styles.pop(); + } else { + chunk.push(chr); } + }); + + chunks.push(chunk.join('')); + + if (styles.length > 0) { + const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; + throw new Error(errMsg); } -} -module.exports = AggregateError; + return chunks.join(''); +}; /***/ }), -/* 673 */ +/* 675 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const restoreCursor = __webpack_require__(676); -module.exports = (string, count = 1, options) => { - options = { - indent: ' ', - includeEmptyLines: false, - ...options - }; +let hidden = false; - if (typeof string !== 'string') { - throw new TypeError( - `Expected \`input\` to be a \`string\`, got \`${typeof string}\`` - ); - } +exports.show = stream => { + const s = stream || process.stderr; - if (typeof count !== 'number') { - throw new TypeError( - `Expected \`count\` to be a \`number\`, got \`${typeof count}\`` - ); + if (!s.isTTY) { + return; } - if (typeof options.indent !== 'string') { - throw new TypeError( - `Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\`` - ); - } + hidden = false; + s.write('\u001b[?25h'); +}; - if (count === 0) { - return string; +exports.hide = stream => { + const s = stream || process.stderr; + + if (!s.isTTY) { + return; } - const regex = options.includeEmptyLines ? /^/gm : /^(?!\s*$)/gm; + restoreCursor(); + hidden = true; + s.write('\u001b[?25l'); +}; - return string.replace(regex, options.indent.repeat(count)); +exports.toggle = (force, stream) => { + if (force !== undefined) { + hidden = force; + } + + if (hidden) { + exports.show(stream); + } else { + exports.hide(stream); + } }; /***/ }), -/* 674 */ +/* 676 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const os = __webpack_require__(11); - -const extractPathRegex = /\s+at.*(?:\(|\s)(.*)\)?/; -const pathRegex = /^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)\.js:\d+:\d+)|native)/; -const homeDir = typeof os.homedir === 'undefined' ? '' : os.homedir(); - -module.exports = (stack, options) => { - options = Object.assign({pretty: false}, options); - - return stack.replace(/\\/g, '/') - .split('\n') - .filter(line => { - const pathMatches = line.match(extractPathRegex); - if (pathMatches === null || !pathMatches[1]) { - return true; - } - - const match = pathMatches[1]; - - // Electron - if ( - match.includes('.app/Contents/Resources/electron.asar') || - match.includes('.app/Contents/Resources/default_app.asar') - ) { - return false; - } - - return !pathRegex.test(match); - }) - .filter(line => line.trim() !== '') - .map(line => { - if (options.pretty) { - return line.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir, '~'))); - } +const onetime = __webpack_require__(677); +const signalExit = __webpack_require__(370); - return line; - }) - .join('\n'); -}; +module.exports = onetime(() => { + signalExit(() => { + process.stderr.write('\u001b[?25h'); + }, {alwaysLast: true}); +}); /***/ }), -/* 675 */ +/* 677 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const chalk = __webpack_require__(676); -const cliCursor = __webpack_require__(680); -const cliSpinners = __webpack_require__(684); -const logSymbols = __webpack_require__(565); +const mimicFn = __webpack_require__(678); -class Ora { - constructor(options) { - if (typeof options === 'string') { - options = { - text: options - }; - } +module.exports = (fn, opts) => { + // TODO: Remove this in v3 + if (opts === true) { + throw new TypeError('The second argument is now an options object'); + } - this.options = Object.assign({ - text: '', - color: 'cyan', - stream: process.stderr - }, options); + if (typeof fn !== 'function') { + throw new TypeError('Expected a function'); + } - const sp = this.options.spinner; - this.spinner = typeof sp === 'object' ? sp : (process.platform === 'win32' ? cliSpinners.line : (cliSpinners[sp] || cliSpinners.dots)); // eslint-disable-line no-nested-ternary + opts = opts || {}; - if (this.spinner.frames === undefined) { - throw new Error('Spinner must define `frames`'); - } + let ret; + let called = false; + const fnName = fn.displayName || fn.name || ''; - this.text = this.options.text; - this.color = this.options.color; - this.interval = this.options.interval || this.spinner.interval || 100; - this.stream = this.options.stream; - this.id = null; - this.frameIndex = 0; - this.enabled = typeof this.options.enabled === 'boolean' ? this.options.enabled : ((this.stream && this.stream.isTTY) && !process.env.CI); - } - frame() { - const frames = this.spinner.frames; - let frame = frames[this.frameIndex]; + const onetime = function () { + if (called) { + if (opts.throw === true) { + throw new Error(`Function \`${fnName}\` can only be called once`); + } - if (this.color) { - frame = chalk[this.color](frame); + return ret; } - this.frameIndex = ++this.frameIndex % frames.length; + called = true; + ret = fn.apply(this, arguments); + fn = null; - return frame + ' ' + this.text; - } - clear() { - if (!this.enabled) { - return this; - } + return ret; + }; - this.stream.clearLine(); - this.stream.cursorTo(0); + mimicFn(onetime, fn); - return this; - } - render() { - this.clear(); - this.stream.write(this.frame()); + return onetime; +}; - return this; - } - start(text) { - if (text) { - this.text = text; - } - if (!this.enabled || this.id) { - return this; - } +/***/ }), +/* 678 */ +/***/ (function(module, exports, __webpack_require__) { - cliCursor.hide(this.stream); - this.render(); - this.id = setInterval(this.render.bind(this), this.interval); +"use strict"; - return this; +module.exports = (to, from) => { + // TODO: use `Reflect.ownKeys()` when targeting Node.js 6 + for (const prop of Object.getOwnPropertyNames(from).concat(Object.getOwnPropertySymbols(from))) { + Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop)); } - stop() { - if (!this.enabled) { - return this; - } - clearInterval(this.id); - this.id = null; - this.frameIndex = 0; - this.clear(); - cliCursor.show(this.stream); + return to; +}; - return this; - } - succeed(text) { - return this.stopAndPersist({symbol: logSymbols.success, text}); - } - fail(text) { - return this.stopAndPersist({symbol: logSymbols.error, text}); - } - warn(text) { - return this.stopAndPersist({symbol: logSymbols.warning, text}); - } - info(text) { - return this.stopAndPersist({symbol: logSymbols.info, text}); - } - stopAndPersist(options) { - if (!this.enabled) { - return this; - } - // Legacy argument - // TODO: Deprecate sometime in the future - if (typeof options === 'string') { - options = { - symbol: options - }; - } +/***/ }), +/* 679 */ +/***/ (function(module, exports, __webpack_require__) { - options = options || {}; +"use strict"; - this.stop(); - this.stream.write(`${options.symbol || ' '} ${options.text || this.text}\n`); +module.exports = __webpack_require__(680); - return this; - } -} -module.exports = function (opts) { - return new Ora(opts); -}; +/***/ }), +/* 680 */ +/***/ (function(module) { -module.exports.promise = (action, options) => { - if (typeof action.then !== 'function') { - throw new TypeError('Parameter `action` must be a Promise'); - } +module.exports = JSON.parse("{\"dots\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠹\",\"⠸\",\"⠼\",\"⠴\",\"⠦\",\"⠧\",\"⠇\",\"⠏\"]},\"dots2\":{\"interval\":80,\"frames\":[\"⣾\",\"⣽\",\"⣻\",\"⢿\",\"⡿\",\"⣟\",\"⣯\",\"⣷\"]},\"dots3\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠞\",\"⠖\",\"⠦\",\"⠴\",\"⠲\",\"⠳\",\"⠓\"]},\"dots4\":{\"interval\":80,\"frames\":[\"⠄\",\"⠆\",\"⠇\",\"⠋\",\"⠙\",\"⠸\",\"⠰\",\"⠠\",\"⠰\",\"⠸\",\"⠙\",\"⠋\",\"⠇\",\"⠆\"]},\"dots5\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\"]},\"dots6\":{\"interval\":80,\"frames\":[\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠴\",\"⠲\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠚\",\"⠙\",\"⠉\",\"⠁\"]},\"dots7\":{\"interval\":80,\"frames\":[\"⠈\",\"⠉\",\"⠋\",\"⠓\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠖\",\"⠦\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\"]},\"dots8\":{\"interval\":80,\"frames\":[\"⠁\",\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\",\"⠈\"]},\"dots9\":{\"interval\":80,\"frames\":[\"⢹\",\"⢺\",\"⢼\",\"⣸\",\"⣇\",\"⡧\",\"⡗\",\"⡏\"]},\"dots10\":{\"interval\":80,\"frames\":[\"⢄\",\"⢂\",\"⢁\",\"⡁\",\"⡈\",\"⡐\",\"⡠\"]},\"dots11\":{\"interval\":100,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⡀\",\"⢀\",\"⠠\",\"⠐\",\"⠈\"]},\"dots12\":{\"interval\":80,\"frames\":[\"⢀⠀\",\"⡀⠀\",\"⠄⠀\",\"⢂⠀\",\"⡂⠀\",\"⠅⠀\",\"⢃⠀\",\"⡃⠀\",\"⠍⠀\",\"⢋⠀\",\"⡋⠀\",\"⠍⠁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⢈⠩\",\"⡀⢙\",\"⠄⡙\",\"⢂⠩\",\"⡂⢘\",\"⠅⡘\",\"⢃⠨\",\"⡃⢐\",\"⠍⡐\",\"⢋⠠\",\"⡋⢀\",\"⠍⡁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⠈⠩\",\"⠀⢙\",\"⠀⡙\",\"⠀⠩\",\"⠀⢘\",\"⠀⡘\",\"⠀⠨\",\"⠀⢐\",\"⠀⡐\",\"⠀⠠\",\"⠀⢀\",\"⠀⡀\"]},\"line\":{\"interval\":130,\"frames\":[\"-\",\"\\\\\",\"|\",\"/\"]},\"line2\":{\"interval\":100,\"frames\":[\"⠂\",\"-\",\"–\",\"—\",\"–\",\"-\"]},\"pipe\":{\"interval\":100,\"frames\":[\"┤\",\"┘\",\"┴\",\"└\",\"├\",\"┌\",\"┬\",\"┐\"]},\"simpleDots\":{\"interval\":400,\"frames\":[\". \",\".. \",\"...\",\" \"]},\"simpleDotsScrolling\":{\"interval\":200,\"frames\":[\". \",\".. \",\"...\",\" ..\",\" .\",\" \"]},\"star\":{\"interval\":70,\"frames\":[\"✶\",\"✸\",\"✹\",\"✺\",\"✹\",\"✷\"]},\"star2\":{\"interval\":80,\"frames\":[\"+\",\"x\",\"*\"]},\"flip\":{\"interval\":70,\"frames\":[\"_\",\"_\",\"_\",\"-\",\"`\",\"`\",\"'\",\"´\",\"-\",\"_\",\"_\",\"_\"]},\"hamburger\":{\"interval\":100,\"frames\":[\"☱\",\"☲\",\"☴\"]},\"growVertical\":{\"interval\":120,\"frames\":[\"▁\",\"▃\",\"▄\",\"▅\",\"▆\",\"▇\",\"▆\",\"▅\",\"▄\",\"▃\"]},\"growHorizontal\":{\"interval\":120,\"frames\":[\"▏\",\"▎\",\"▍\",\"▌\",\"▋\",\"▊\",\"▉\",\"▊\",\"▋\",\"▌\",\"▍\",\"▎\"]},\"balloon\":{\"interval\":140,\"frames\":[\" \",\".\",\"o\",\"O\",\"@\",\"*\",\" \"]},\"balloon2\":{\"interval\":120,\"frames\":[\".\",\"o\",\"O\",\"°\",\"O\",\"o\",\".\"]},\"noise\":{\"interval\":100,\"frames\":[\"▓\",\"▒\",\"░\"]},\"bounce\":{\"interval\":120,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⠂\"]},\"boxBounce\":{\"interval\":120,\"frames\":[\"▖\",\"▘\",\"▝\",\"▗\"]},\"boxBounce2\":{\"interval\":100,\"frames\":[\"▌\",\"▀\",\"▐\",\"▄\"]},\"triangle\":{\"interval\":50,\"frames\":[\"◢\",\"◣\",\"◤\",\"◥\"]},\"arc\":{\"interval\":100,\"frames\":[\"◜\",\"◠\",\"◝\",\"◞\",\"◡\",\"◟\"]},\"circle\":{\"interval\":120,\"frames\":[\"◡\",\"⊙\",\"◠\"]},\"squareCorners\":{\"interval\":180,\"frames\":[\"◰\",\"◳\",\"◲\",\"◱\"]},\"circleQuarters\":{\"interval\":120,\"frames\":[\"◴\",\"◷\",\"◶\",\"◵\"]},\"circleHalves\":{\"interval\":50,\"frames\":[\"◐\",\"◓\",\"◑\",\"◒\"]},\"squish\":{\"interval\":100,\"frames\":[\"╫\",\"╪\"]},\"toggle\":{\"interval\":250,\"frames\":[\"⊶\",\"⊷\"]},\"toggle2\":{\"interval\":80,\"frames\":[\"▫\",\"▪\"]},\"toggle3\":{\"interval\":120,\"frames\":[\"□\",\"■\"]},\"toggle4\":{\"interval\":100,\"frames\":[\"■\",\"□\",\"▪\",\"▫\"]},\"toggle5\":{\"interval\":100,\"frames\":[\"▮\",\"▯\"]},\"toggle6\":{\"interval\":300,\"frames\":[\"ဝ\",\"၀\"]},\"toggle7\":{\"interval\":80,\"frames\":[\"⦾\",\"⦿\"]},\"toggle8\":{\"interval\":100,\"frames\":[\"◍\",\"◌\"]},\"toggle9\":{\"interval\":100,\"frames\":[\"◉\",\"◎\"]},\"toggle10\":{\"interval\":100,\"frames\":[\"㊂\",\"㊀\",\"㊁\"]},\"toggle11\":{\"interval\":50,\"frames\":[\"⧇\",\"⧆\"]},\"toggle12\":{\"interval\":120,\"frames\":[\"☗\",\"☖\"]},\"toggle13\":{\"interval\":80,\"frames\":[\"=\",\"*\",\"-\"]},\"arrow\":{\"interval\":100,\"frames\":[\"←\",\"↖\",\"↑\",\"↗\",\"→\",\"↘\",\"↓\",\"↙\"]},\"arrow2\":{\"interval\":80,\"frames\":[\"⬆️ \",\"↗️ \",\"➡️ \",\"↘️ \",\"⬇️ \",\"↙️ \",\"⬅️ \",\"↖️ \"]},\"arrow3\":{\"interval\":120,\"frames\":[\"▹▹▹▹▹\",\"▸▹▹▹▹\",\"▹▸▹▹▹\",\"▹▹▸▹▹\",\"▹▹▹▸▹\",\"▹▹▹▹▸\"]},\"bouncingBar\":{\"interval\":80,\"frames\":[\"[ ]\",\"[= ]\",\"[== ]\",\"[=== ]\",\"[ ===]\",\"[ ==]\",\"[ =]\",\"[ ]\",\"[ =]\",\"[ ==]\",\"[ ===]\",\"[====]\",\"[=== ]\",\"[== ]\",\"[= ]\"]},\"bouncingBall\":{\"interval\":80,\"frames\":[\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ●)\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"(● )\"]},\"smiley\":{\"interval\":200,\"frames\":[\"😄 \",\"😝 \"]},\"monkey\":{\"interval\":300,\"frames\":[\"🙈 \",\"🙈 \",\"🙉 \",\"🙊 \"]},\"hearts\":{\"interval\":100,\"frames\":[\"💛 \",\"💙 \",\"💜 \",\"💚 \",\"❤️ \"]},\"clock\":{\"interval\":100,\"frames\":[\"🕐 \",\"🕑 \",\"🕒 \",\"🕓 \",\"🕔 \",\"🕕 \",\"🕖 \",\"🕗 \",\"🕘 \",\"🕙 \",\"🕚 \"]},\"earth\":{\"interval\":180,\"frames\":[\"🌍 \",\"🌎 \",\"🌏 \"]},\"moon\":{\"interval\":80,\"frames\":[\"🌑 \",\"🌒 \",\"🌓 \",\"🌔 \",\"🌕 \",\"🌖 \",\"🌗 \",\"🌘 \"]},\"runner\":{\"interval\":140,\"frames\":[\"🚶 \",\"🏃 \"]},\"pong\":{\"interval\":80,\"frames\":[\"▐⠂ ▌\",\"▐⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂▌\",\"▐ ⠠▌\",\"▐ ⡀▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐⠠ ▌\"]},\"shark\":{\"interval\":120,\"frames\":[\"▐|\\\\____________▌\",\"▐_|\\\\___________▌\",\"▐__|\\\\__________▌\",\"▐___|\\\\_________▌\",\"▐____|\\\\________▌\",\"▐_____|\\\\_______▌\",\"▐______|\\\\______▌\",\"▐_______|\\\\_____▌\",\"▐________|\\\\____▌\",\"▐_________|\\\\___▌\",\"▐__________|\\\\__▌\",\"▐___________|\\\\_▌\",\"▐____________|\\\\▌\",\"▐____________/|▌\",\"▐___________/|_▌\",\"▐__________/|__▌\",\"▐_________/|___▌\",\"▐________/|____▌\",\"▐_______/|_____▌\",\"▐______/|______▌\",\"▐_____/|_______▌\",\"▐____/|________▌\",\"▐___/|_________▌\",\"▐__/|__________▌\",\"▐_/|___________▌\",\"▐/|____________▌\"]},\"dqpb\":{\"interval\":100,\"frames\":[\"d\",\"q\",\"p\",\"b\"]},\"weather\":{\"interval\":100,\"frames\":[\"☀️ \",\"☀️ \",\"☀️ \",\"🌤 \",\"⛅️ \",\"🌥 \",\"☁️ \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"⛈ \",\"🌨 \",\"🌧 \",\"🌨 \",\"☁️ \",\"🌥 \",\"⛅️ \",\"🌤 \",\"☀️ \",\"☀️ \"]},\"christmas\":{\"interval\":400,\"frames\":[\"🌲\",\"🎄\"]}}"); - const spinner = new Ora(options); - spinner.start(); +/***/ }), +/* 681 */ +/***/ (function(module, exports, __webpack_require__) { - action.then( - () => { - spinner.succeed(); - }, - () => { - spinner.fail(); - } - ); +"use strict"; - return spinner; +const chalk = __webpack_require__(682); + +const isSupported = process.platform !== 'win32' || process.env.CI || process.env.TERM === 'xterm-256color'; + +const main = { + info: chalk.blue('ℹ'), + success: chalk.green('✔'), + warning: chalk.yellow('⚠'), + error: chalk.red('✖') +}; + +const fallbacks = { + info: chalk.blue('i'), + success: chalk.green('√'), + warning: chalk.yellow('‼'), + error: chalk.red('×') }; +module.exports = isSupported ? main : fallbacks; + /***/ }), -/* 676 */ +/* 682 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const escapeStringRegexp = __webpack_require__(3); -const ansiStyles = __webpack_require__(677); -const stdoutColor = __webpack_require__(678).stdout; +const escapeStringRegexp = __webpack_require__(387); +const ansiStyles = __webpack_require__(683); +const stdoutColor = __webpack_require__(684).stdout; -const template = __webpack_require__(679); +const template = __webpack_require__(685); const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); @@ -77658,12 +77850,12 @@ module.exports.default = module.exports; // For TypeScript /***/ }), -/* 677 */ +/* 683 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(6); +const colorConvert = __webpack_require__(389); const wrapAnsi16 = (fn, offset) => function () { const code = fn.apply(colorConvert, arguments); @@ -77828,16 +78020,16 @@ Object.defineProperty(module, 'exports', { get: assembleStyles }); -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(5)(module))) +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(11)(module))) /***/ }), -/* 678 */ +/* 684 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const os = __webpack_require__(11); -const hasFlag = __webpack_require__(12); +const os = __webpack_require__(364); +const hasFlag = __webpack_require__(394); const env = process.env; @@ -77973,7 +78165,7 @@ module.exports = { /***/ }), -/* 679 */ +/* 685 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78107,145 +78299,6 @@ module.exports = (chalk, tmp) => { }; -/***/ }), -/* 680 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const restoreCursor = __webpack_require__(681); - -let hidden = false; - -exports.show = stream => { - const s = stream || process.stderr; - - if (!s.isTTY) { - return; - } - - hidden = false; - s.write('\u001b[?25h'); -}; - -exports.hide = stream => { - const s = stream || process.stderr; - - if (!s.isTTY) { - return; - } - - restoreCursor(); - hidden = true; - s.write('\u001b[?25l'); -}; - -exports.toggle = (force, stream) => { - if (force !== undefined) { - hidden = force; - } - - if (hidden) { - exports.show(stream); - } else { - exports.hide(stream); - } -}; - - -/***/ }), -/* 681 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const onetime = __webpack_require__(682); -const signalExit = __webpack_require__(397); - -module.exports = onetime(() => { - signalExit(() => { - process.stderr.write('\u001b[?25h'); - }, {alwaysLast: true}); -}); - - -/***/ }), -/* 682 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const mimicFn = __webpack_require__(683); - -module.exports = (fn, opts) => { - // TODO: Remove this in v3 - if (opts === true) { - throw new TypeError('The second argument is now an options object'); - } - - if (typeof fn !== 'function') { - throw new TypeError('Expected a function'); - } - - opts = opts || {}; - - let ret; - let called = false; - const fnName = fn.displayName || fn.name || ''; - - const onetime = function () { - if (called) { - if (opts.throw === true) { - throw new Error(`Function \`${fnName}\` can only be called once`); - } - - return ret; - } - - called = true; - ret = fn.apply(this, arguments); - fn = null; - - return ret; - }; - - mimicFn(onetime, fn); - - return onetime; -}; - - -/***/ }), -/* 683 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -module.exports = (to, from) => { - // TODO: use `Reflect.ownKeys()` when targeting Node.js 6 - for (const prop of Object.getOwnPropertyNames(from).concat(Object.getOwnPropertySymbols(from))) { - Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop)); - } - - return to; -}; - - -/***/ }), -/* 684 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -module.exports = __webpack_require__(685); - - -/***/ }), -/* 685 */ -/***/ (function(module) { - -module.exports = JSON.parse("{\"dots\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠹\",\"⠸\",\"⠼\",\"⠴\",\"⠦\",\"⠧\",\"⠇\",\"⠏\"]},\"dots2\":{\"interval\":80,\"frames\":[\"⣾\",\"⣽\",\"⣻\",\"⢿\",\"⡿\",\"⣟\",\"⣯\",\"⣷\"]},\"dots3\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠞\",\"⠖\",\"⠦\",\"⠴\",\"⠲\",\"⠳\",\"⠓\"]},\"dots4\":{\"interval\":80,\"frames\":[\"⠄\",\"⠆\",\"⠇\",\"⠋\",\"⠙\",\"⠸\",\"⠰\",\"⠠\",\"⠰\",\"⠸\",\"⠙\",\"⠋\",\"⠇\",\"⠆\"]},\"dots5\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\"]},\"dots6\":{\"interval\":80,\"frames\":[\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠴\",\"⠲\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠚\",\"⠙\",\"⠉\",\"⠁\"]},\"dots7\":{\"interval\":80,\"frames\":[\"⠈\",\"⠉\",\"⠋\",\"⠓\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠖\",\"⠦\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\"]},\"dots8\":{\"interval\":80,\"frames\":[\"⠁\",\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\",\"⠈\"]},\"dots9\":{\"interval\":80,\"frames\":[\"⢹\",\"⢺\",\"⢼\",\"⣸\",\"⣇\",\"⡧\",\"⡗\",\"⡏\"]},\"dots10\":{\"interval\":80,\"frames\":[\"⢄\",\"⢂\",\"⢁\",\"⡁\",\"⡈\",\"⡐\",\"⡠\"]},\"dots11\":{\"interval\":100,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⡀\",\"⢀\",\"⠠\",\"⠐\",\"⠈\"]},\"dots12\":{\"interval\":80,\"frames\":[\"⢀⠀\",\"⡀⠀\",\"⠄⠀\",\"⢂⠀\",\"⡂⠀\",\"⠅⠀\",\"⢃⠀\",\"⡃⠀\",\"⠍⠀\",\"⢋⠀\",\"⡋⠀\",\"⠍⠁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⢈⠩\",\"⡀⢙\",\"⠄⡙\",\"⢂⠩\",\"⡂⢘\",\"⠅⡘\",\"⢃⠨\",\"⡃⢐\",\"⠍⡐\",\"⢋⠠\",\"⡋⢀\",\"⠍⡁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⠈⠩\",\"⠀⢙\",\"⠀⡙\",\"⠀⠩\",\"⠀⢘\",\"⠀⡘\",\"⠀⠨\",\"⠀⢐\",\"⠀⡐\",\"⠀⠠\",\"⠀⢀\",\"⠀⡀\"]},\"line\":{\"interval\":130,\"frames\":[\"-\",\"\\\\\",\"|\",\"/\"]},\"line2\":{\"interval\":100,\"frames\":[\"⠂\",\"-\",\"–\",\"—\",\"–\",\"-\"]},\"pipe\":{\"interval\":100,\"frames\":[\"┤\",\"┘\",\"┴\",\"└\",\"├\",\"┌\",\"┬\",\"┐\"]},\"simpleDots\":{\"interval\":400,\"frames\":[\". \",\".. \",\"...\",\" \"]},\"simpleDotsScrolling\":{\"interval\":200,\"frames\":[\". \",\".. \",\"...\",\" ..\",\" .\",\" \"]},\"star\":{\"interval\":70,\"frames\":[\"✶\",\"✸\",\"✹\",\"✺\",\"✹\",\"✷\"]},\"star2\":{\"interval\":80,\"frames\":[\"+\",\"x\",\"*\"]},\"flip\":{\"interval\":70,\"frames\":[\"_\",\"_\",\"_\",\"-\",\"`\",\"`\",\"'\",\"´\",\"-\",\"_\",\"_\",\"_\"]},\"hamburger\":{\"interval\":100,\"frames\":[\"☱\",\"☲\",\"☴\"]},\"growVertical\":{\"interval\":120,\"frames\":[\"▁\",\"▃\",\"▄\",\"▅\",\"▆\",\"▇\",\"▆\",\"▅\",\"▄\",\"▃\"]},\"growHorizontal\":{\"interval\":120,\"frames\":[\"▏\",\"▎\",\"▍\",\"▌\",\"▋\",\"▊\",\"▉\",\"▊\",\"▋\",\"▌\",\"▍\",\"▎\"]},\"balloon\":{\"interval\":140,\"frames\":[\" \",\".\",\"o\",\"O\",\"@\",\"*\",\" \"]},\"balloon2\":{\"interval\":120,\"frames\":[\".\",\"o\",\"O\",\"°\",\"O\",\"o\",\".\"]},\"noise\":{\"interval\":100,\"frames\":[\"▓\",\"▒\",\"░\"]},\"bounce\":{\"interval\":120,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⠂\"]},\"boxBounce\":{\"interval\":120,\"frames\":[\"▖\",\"▘\",\"▝\",\"▗\"]},\"boxBounce2\":{\"interval\":100,\"frames\":[\"▌\",\"▀\",\"▐\",\"▄\"]},\"triangle\":{\"interval\":50,\"frames\":[\"◢\",\"◣\",\"◤\",\"◥\"]},\"arc\":{\"interval\":100,\"frames\":[\"◜\",\"◠\",\"◝\",\"◞\",\"◡\",\"◟\"]},\"circle\":{\"interval\":120,\"frames\":[\"◡\",\"⊙\",\"◠\"]},\"squareCorners\":{\"interval\":180,\"frames\":[\"◰\",\"◳\",\"◲\",\"◱\"]},\"circleQuarters\":{\"interval\":120,\"frames\":[\"◴\",\"◷\",\"◶\",\"◵\"]},\"circleHalves\":{\"interval\":50,\"frames\":[\"◐\",\"◓\",\"◑\",\"◒\"]},\"squish\":{\"interval\":100,\"frames\":[\"╫\",\"╪\"]},\"toggle\":{\"interval\":250,\"frames\":[\"⊶\",\"⊷\"]},\"toggle2\":{\"interval\":80,\"frames\":[\"▫\",\"▪\"]},\"toggle3\":{\"interval\":120,\"frames\":[\"□\",\"■\"]},\"toggle4\":{\"interval\":100,\"frames\":[\"■\",\"□\",\"▪\",\"▫\"]},\"toggle5\":{\"interval\":100,\"frames\":[\"▮\",\"▯\"]},\"toggle6\":{\"interval\":300,\"frames\":[\"ဝ\",\"၀\"]},\"toggle7\":{\"interval\":80,\"frames\":[\"⦾\",\"⦿\"]},\"toggle8\":{\"interval\":100,\"frames\":[\"◍\",\"◌\"]},\"toggle9\":{\"interval\":100,\"frames\":[\"◉\",\"◎\"]},\"toggle10\":{\"interval\":100,\"frames\":[\"㊂\",\"㊀\",\"㊁\"]},\"toggle11\":{\"interval\":50,\"frames\":[\"⧇\",\"⧆\"]},\"toggle12\":{\"interval\":120,\"frames\":[\"☗\",\"☖\"]},\"toggle13\":{\"interval\":80,\"frames\":[\"=\",\"*\",\"-\"]},\"arrow\":{\"interval\":100,\"frames\":[\"←\",\"↖\",\"↑\",\"↗\",\"→\",\"↘\",\"↓\",\"↙\"]},\"arrow2\":{\"interval\":80,\"frames\":[\"⬆️ \",\"↗️ \",\"➡️ \",\"↘️ \",\"⬇️ \",\"↙️ \",\"⬅️ \",\"↖️ \"]},\"arrow3\":{\"interval\":120,\"frames\":[\"▹▹▹▹▹\",\"▸▹▹▹▹\",\"▹▸▹▹▹\",\"▹▹▸▹▹\",\"▹▹▹▸▹\",\"▹▹▹▹▸\"]},\"bouncingBar\":{\"interval\":80,\"frames\":[\"[ ]\",\"[= ]\",\"[== ]\",\"[=== ]\",\"[ ===]\",\"[ ==]\",\"[ =]\",\"[ ]\",\"[ =]\",\"[ ==]\",\"[ ===]\",\"[====]\",\"[=== ]\",\"[== ]\",\"[= ]\"]},\"bouncingBall\":{\"interval\":80,\"frames\":[\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ●)\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"(● )\"]},\"smiley\":{\"interval\":200,\"frames\":[\"😄 \",\"😝 \"]},\"monkey\":{\"interval\":300,\"frames\":[\"🙈 \",\"🙈 \",\"🙉 \",\"🙊 \"]},\"hearts\":{\"interval\":100,\"frames\":[\"💛 \",\"💙 \",\"💜 \",\"💚 \",\"❤️ \"]},\"clock\":{\"interval\":100,\"frames\":[\"🕐 \",\"🕑 \",\"🕒 \",\"🕓 \",\"🕔 \",\"🕕 \",\"🕖 \",\"🕗 \",\"🕘 \",\"🕙 \",\"🕚 \"]},\"earth\":{\"interval\":180,\"frames\":[\"🌍 \",\"🌎 \",\"🌏 \"]},\"moon\":{\"interval\":80,\"frames\":[\"🌑 \",\"🌒 \",\"🌓 \",\"🌔 \",\"🌕 \",\"🌖 \",\"🌗 \",\"🌘 \"]},\"runner\":{\"interval\":140,\"frames\":[\"🚶 \",\"🏃 \"]},\"pong\":{\"interval\":80,\"frames\":[\"▐⠂ ▌\",\"▐⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂▌\",\"▐ ⠠▌\",\"▐ ⡀▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐⠠ ▌\"]},\"shark\":{\"interval\":120,\"frames\":[\"▐|\\\\____________▌\",\"▐_|\\\\___________▌\",\"▐__|\\\\__________▌\",\"▐___|\\\\_________▌\",\"▐____|\\\\________▌\",\"▐_____|\\\\_______▌\",\"▐______|\\\\______▌\",\"▐_______|\\\\_____▌\",\"▐________|\\\\____▌\",\"▐_________|\\\\___▌\",\"▐__________|\\\\__▌\",\"▐___________|\\\\_▌\",\"▐____________|\\\\▌\",\"▐____________/|▌\",\"▐___________/|_▌\",\"▐__________/|__▌\",\"▐_________/|___▌\",\"▐________/|____▌\",\"▐_______/|_____▌\",\"▐______/|______▌\",\"▐_____/|_______▌\",\"▐____/|________▌\",\"▐___/|_________▌\",\"▐__/|__________▌\",\"▐_/|___________▌\",\"▐/|____________▌\"]},\"dqpb\":{\"interval\":100,\"frames\":[\"d\",\"q\",\"p\",\"b\"]},\"weather\":{\"interval\":100,\"frames\":[\"☀️ \",\"☀️ \",\"☀️ \",\"🌤 \",\"⛅️ \",\"🌥 \",\"☁️ \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"⛈ \",\"🌨 \",\"🌧 \",\"🌨 \",\"☁️ \",\"🌥 \",\"⛅️ \",\"🌤 \",\"☀️ \",\"☀️ \"]},\"christmas\":{\"interval\":400,\"frames\":[\"🌲\",\"🎄\"]}}"); - /***/ }), /* 686 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { @@ -78253,9 +78306,8 @@ module.exports = JSON.parse("{\"dots\":{\"interval\":80,\"frames\":[\"⠋\",\" "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RunCommand", function() { return RunCommand; }); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(34); +/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(516); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(500); /* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(501); /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(502); /* @@ -78290,16 +78342,18 @@ const RunCommand = { const batchedProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_3__["topologicallyBatchProjects"])(projects, projectGraph); if (extraArgs.length === 0) { - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.red.bold('\nNo script specified')); - process.exit(1); + throw new _utils_errors__WEBPACK_IMPORTED_MODULE_0__["CliError"]('No script specified'); } const scriptName = extraArgs[0]; const scriptArgs = extraArgs.slice(1); - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold(`\nRunning script [${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(scriptName)}] in batched topological order\n`)); - await Object(_utils_parallelize__WEBPACK_IMPORTED_MODULE_2__["parallelizeBatches"])(batchedProjects, async pkg => { - if (pkg.hasScript(scriptName)) { - await pkg.runScriptStreaming(scriptName, scriptArgs); + await Object(_utils_parallelize__WEBPACK_IMPORTED_MODULE_2__["parallelizeBatches"])(batchedProjects, async project => { + if (project.hasScript(scriptName)) { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].info(`[${project.name}] running "${scriptName}" script`); + await project.runScriptStreaming(scriptName, { + args: scriptArgs + }); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].success(`[${project.name}] complete`); } }); } @@ -78313,9 +78367,8 @@ const RunCommand = { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WatchCommand", function() { return WatchCommand; }); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(34); +/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(516); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(500); /* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(501); /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(502); /* harmony import */ var _utils_watch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(688); @@ -78378,12 +78431,11 @@ const WatchCommand = { } if (projectsToWatch.size === 0) { - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.red(`\nThere are no projects to watch found. Make sure that projects define 'kbn:watch' script in 'package.json'.\n`)); - return; + throw new _utils_errors__WEBPACK_IMPORTED_MODULE_0__["CliError"](`There are no projects to watch found. Make sure that projects define 'kbn:watch' script in 'package.json'.`); } const projectNames = Array.from(projectsToWatch.keys()); - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(`Running ${watchScriptName} scripts for [${projectNames.join(', ')}].`))); // Kibana should always be run the last, so we don't rely on automatic + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].info(`Running ${watchScriptName} scripts for [${projectNames.join(', ')}].`); // Kibana should always be run the last, so we don't rely on automatic // topological batching and push it to the last one-entry batch manually. const shouldWatchKibanaProject = projectsToWatch.delete(kibanaProjectName); @@ -78394,8 +78446,10 @@ const WatchCommand = { } await Object(_utils_parallelize__WEBPACK_IMPORTED_MODULE_2__["parallelizeBatches"])(batchedProjects, async pkg => { - const completionHint = await Object(_utils_watch__WEBPACK_IMPORTED_MODULE_4__["waitUntilWatchIsReady"])(pkg.runScriptStreaming(watchScriptName).stdout); - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold(`[${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(pkg.name)}] Initial build completed (${completionHint}).`)); + const completionHint = await Object(_utils_watch__WEBPACK_IMPORTED_MODULE_4__["waitUntilWatchIsReady"])(pkg.runScriptStreaming(watchScriptName, { + debug: false + }).stdout); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].success(`[${pkg.name}] Initial build completed (${completionHint}).`); }); } @@ -78408,8 +78462,8 @@ const WatchCommand = { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "waitUntilWatchIsReady", function() { return waitUntilWatchIsReady; }); -/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(169); -/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(270); +/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(140); +/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(241); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -78482,17 +78536,11 @@ function waitUntilWatchIsReady(stream, opts = {}) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runCommand", function() { return runCommand; }); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var indent_string__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(690); -/* harmony import */ var indent_string__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(indent_string__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var wrap_ansi__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(691); -/* harmony import */ var wrap_ansi__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(wrap_ansi__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(516); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(34); -/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(502); -/* harmony import */ var _utils_projects_tree__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(698); -/* harmony import */ var _utils_kibana__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(699); +/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(516); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(500); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(502); +/* harmony import */ var _utils_projects_tree__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(690); +/* harmony import */ var _utils_kibana__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(691); 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; } function _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; } @@ -78522,13 +78570,10 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope - - - async function runCommand(command, config) { try { - _utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold(`Running [${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(command.name)}] command from [${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.yellow(config.rootPath)}]:\n`)); - const kbn = await _utils_kibana__WEBPACK_IMPORTED_MODULE_7__["Kibana"].loadFrom(config.rootPath); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].debug(`Running [${command.name}] command from [${config.rootPath}]`); + const kbn = await _utils_kibana__WEBPACK_IMPORTED_MODULE_4__["Kibana"].loadFrom(config.rootPath); const projects = kbn.getFilteredProjects({ skipKibanaPlugins: Boolean(config.options['skip-kibana-plugins']), ossOnly: Boolean(config.options.oss), @@ -78537,34 +78582,31 @@ async function runCommand(command, config) { }); if (projects.size === 0) { - _utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.red(`There are no projects found. Double check project name(s) in '-i/--include' and '-e/--exclude' filters.\n`)); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].error(`There are no projects found. Double check project name(s) in '-i/--include' and '-e/--exclude' filters.`); return process.exit(1); } - const projectGraph = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_5__["buildProjectGraph"])(projects); - _utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold(`Found [${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(projects.size.toString())}] projects:\n`)); - _utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].write(Object(_utils_projects_tree__WEBPACK_IMPORTED_MODULE_6__["renderProjectsTree"])(config.rootPath, projects)); + const projectGraph = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_2__["buildProjectGraph"])(projects); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].debug(`Found ${projects.size.toString()} projects`); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].debug(Object(_utils_projects_tree__WEBPACK_IMPORTED_MODULE_3__["renderProjectsTree"])(config.rootPath, projects)); await command.run(projects, projectGraph, _objectSpread({}, config, { kbn })); - } catch (e) { - _utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold.red(`\n[${command.name}] failed:\n`)); + } catch (error) { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].error(`[${command.name}] failed:`); - if (e instanceof _utils_errors__WEBPACK_IMPORTED_MODULE_3__["CliError"]) { - const msg = chalk__WEBPACK_IMPORTED_MODULE_0___default.a.red(`CliError: ${e.message}\n`); - _utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].write(wrap_ansi__WEBPACK_IMPORTED_MODULE_2___default()(msg, 80)); - const keys = Object.keys(e.meta); + if (error instanceof _utils_errors__WEBPACK_IMPORTED_MODULE_0__["CliError"]) { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].error(error.message); + const metaOutput = Object.entries(error.meta).map(([key, value]) => `${key}: ${value}`).join('\n'); - if (keys.length > 0) { - const metaOutput = keys.map(key => { - const value = e.meta[key]; - return `${key}: ${value}`; - }); - _utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].write('Additional debugging info:\n'); - _utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].write(indent_string__WEBPACK_IMPORTED_MODULE_1___default()(metaOutput.join('\n'), 3)); + if (metaOutput) { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].info('Additional debugging info:\n'); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].indent(2); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].info(metaOutput); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].indent(-2); } } else { - _utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].write(e.stack); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].error(error); } process.exit(1); @@ -78581,400 +78623,14 @@ function toArray(value) { /***/ }), /* 690 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -module.exports = (str, count, opts) => { - // Support older versions: use the third parameter as options.indent - // TODO: Remove the workaround in the next major version - const options = typeof opts === 'object' ? Object.assign({indent: ' '}, opts) : {indent: opts || ' '}; - count = count === undefined ? 1 : count; - - if (typeof str !== 'string') { - throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof str}\``); - } - - if (typeof count !== 'number') { - throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof count}\``); - } - - if (typeof options.indent !== 'string') { - throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\``); - } - - if (count === 0) { - return str; - } - - const regex = options.includeEmptyLines ? /^/mg : /^(?!\s*$)/mg; - return str.replace(regex, options.indent.repeat(count)); -} -; - - -/***/ }), -/* 691 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const stringWidth = __webpack_require__(692); -const stripAnsi = __webpack_require__(696); - -const ESCAPES = new Set([ - '\u001B', - '\u009B' -]); - -const END_CODE = 39; - -const ESCAPE_CODES = new Map([ - [0, 0], - [1, 22], - [2, 22], - [3, 23], - [4, 24], - [7, 27], - [8, 28], - [9, 29], - [30, 39], - [31, 39], - [32, 39], - [33, 39], - [34, 39], - [35, 39], - [36, 39], - [37, 39], - [90, 39], - [40, 49], - [41, 49], - [42, 49], - [43, 49], - [44, 49], - [45, 49], - [46, 49], - [47, 49] -]); - -const wrapAnsi = code => `${ESCAPES.values().next().value}[${code}m`; - -// Calculate the length of words split on ' ', ignoring -// the extra characters added by ansi escape codes -const wordLengths = str => str.split(' ').map(s => stringWidth(s)); - -// Wrap a long word across multiple rows -// Ansi escape codes do not count towards length -const wrapWord = (rows, word, cols) => { - const arr = Array.from(word); - - let insideEscape = false; - let visible = stringWidth(stripAnsi(rows[rows.length - 1])); - - for (const item of arr.entries()) { - const i = item[0]; - const char = item[1]; - const charLength = stringWidth(char); - - if (visible + charLength <= cols) { - rows[rows.length - 1] += char; - } else { - rows.push(char); - visible = 0; - } - - if (ESCAPES.has(char)) { - insideEscape = true; - } else if (insideEscape && char === 'm') { - insideEscape = false; - continue; - } - - if (insideEscape) { - continue; - } - - visible += charLength; - - if (visible === cols && i < arr.length - 1) { - rows.push(''); - visible = 0; - } - } - - // It's possible that the last row we copy over is only - // ansi escape characters, handle this edge-case - if (!visible && rows[rows.length - 1].length > 0 && rows.length > 1) { - rows[rows.length - 2] += rows.pop(); - } -}; - -// The wrap-ansi module can be invoked -// in either 'hard' or 'soft' wrap mode -// -// 'hard' will never allow a string to take up more -// than cols characters -// -// 'soft' allows long words to expand past the column length -const exec = (str, cols, opts) => { - const options = opts || {}; - - if (str.trim() === '') { - return options.trim === false ? str : str.trim(); - } - - let pre = ''; - let ret = ''; - let escapeCode; - - const lengths = wordLengths(str); - const words = str.split(' '); - const rows = ['']; - - for (const item of Array.from(words).entries()) { - const i = item[0]; - const word = item[1]; - - rows[rows.length - 1] = options.trim === false ? rows[rows.length - 1] : rows[rows.length - 1].trim(); - let rowLength = stringWidth(rows[rows.length - 1]); - - if (rowLength || word === '') { - if (rowLength === cols && options.wordWrap === false) { - // If we start with a new word but the current row length equals the length of the columns, add a new row - rows.push(''); - rowLength = 0; - } - - rows[rows.length - 1] += ' '; - rowLength++; - } - - // In 'hard' wrap mode, the length of a line is - // never allowed to extend past 'cols' - if (lengths[i] > cols && options.hard) { - if (rowLength) { - rows.push(''); - } - wrapWord(rows, word, cols); - continue; - } - - if (rowLength + lengths[i] > cols && rowLength > 0) { - if (options.wordWrap === false && rowLength < cols) { - wrapWord(rows, word, cols); - continue; - } - - rows.push(''); - } - - if (rowLength + lengths[i] > cols && options.wordWrap === false) { - wrapWord(rows, word, cols); - continue; - } - - rows[rows.length - 1] += word; - } - - pre = rows.map(r => options.trim === false ? r : r.trim()).join('\n'); - - for (const item of Array.from(pre).entries()) { - const i = item[0]; - const char = item[1]; - - ret += char; - - if (ESCAPES.has(char)) { - const code = parseFloat(/\d[^m]*/.exec(pre.slice(i, i + 4))); - escapeCode = code === END_CODE ? null : code; - } - - const code = ESCAPE_CODES.get(Number(escapeCode)); - - if (escapeCode && code) { - if (pre[i + 1] === '\n') { - ret += wrapAnsi(code); - } else if (char === '\n') { - ret += wrapAnsi(escapeCode); - } - } - } - - return ret; -}; - -// For each newline, invoke the method separately -module.exports = (str, cols, opts) => { - return String(str) - .normalize() - .split('\n') - .map(line => exec(line, cols, opts)) - .join('\n'); -}; - - -/***/ }), -/* 692 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const stripAnsi = __webpack_require__(693); -const isFullwidthCodePoint = __webpack_require__(695); - -module.exports = str => { - if (typeof str !== 'string' || str.length === 0) { - return 0; - } - - str = stripAnsi(str); - - let width = 0; - - for (let i = 0; i < str.length; i++) { - const code = str.codePointAt(i); - - // Ignore control characters - if (code <= 0x1F || (code >= 0x7F && code <= 0x9F)) { - continue; - } - - // Ignore combining characters - if (code >= 0x300 && code <= 0x36F) { - continue; - } - - // Surrogates - if (code > 0xFFFF) { - i++; - } - - width += isFullwidthCodePoint(code) ? 2 : 1; - } - - return width; -}; - - -/***/ }), -/* 693 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const ansiRegex = __webpack_require__(694); - -module.exports = input => typeof input === 'string' ? input.replace(ansiRegex(), '') : input; - - -/***/ }), -/* 694 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = () => { - const pattern = [ - '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\\u0007)', - '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))' - ].join('|'); - - return new RegExp(pattern, 'g'); -}; - - -/***/ }), -/* 695 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -/* eslint-disable yoda */ -module.exports = x => { - if (Number.isNaN(x)) { - return false; - } - - // code points are derived from: - // http://www.unix.org/Public/UNIDATA/EastAsianWidth.txt - if ( - x >= 0x1100 && ( - x <= 0x115f || // Hangul Jamo - x === 0x2329 || // LEFT-POINTING ANGLE BRACKET - x === 0x232a || // RIGHT-POINTING ANGLE BRACKET - // CJK Radicals Supplement .. Enclosed CJK Letters and Months - (0x2e80 <= x && x <= 0x3247 && x !== 0x303f) || - // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A - (0x3250 <= x && x <= 0x4dbf) || - // CJK Unified Ideographs .. Yi Radicals - (0x4e00 <= x && x <= 0xa4c6) || - // Hangul Jamo Extended-A - (0xa960 <= x && x <= 0xa97c) || - // Hangul Syllables - (0xac00 <= x && x <= 0xd7a3) || - // CJK Compatibility Ideographs - (0xf900 <= x && x <= 0xfaff) || - // Vertical Forms - (0xfe10 <= x && x <= 0xfe19) || - // CJK Compatibility Forms .. Small Form Variants - (0xfe30 <= x && x <= 0xfe6b) || - // Halfwidth and Fullwidth Forms - (0xff01 <= x && x <= 0xff60) || - (0xffe0 <= x && x <= 0xffe6) || - // Kana Supplement - (0x1b000 <= x && x <= 0x1b001) || - // Enclosed Ideographic Supplement - (0x1f200 <= x && x <= 0x1f251) || - // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane - (0x20000 <= x && x <= 0x3fffd) - ) - ) { - return true; - } - - return false; -}; - - -/***/ }), -/* 696 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const ansiRegex = __webpack_require__(697); - -module.exports = input => typeof input === 'string' ? input.replace(ansiRegex(), '') : input; - - -/***/ }), -/* 697 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = () => { - const pattern = [ - '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\\u0007)', - '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))' - ].join('|'); - - return new RegExp(pattern, 'g'); -}; - - -/***/ }), -/* 698 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "renderProjectsTree", function() { return renderProjectsTree; }); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(386); /* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); /* * Licensed to Elasticsearch B.V. under one or more contributor @@ -79119,20 +78775,20 @@ function addProjectToTree(tree, pathParts, project) { } /***/ }), -/* 699 */ +/* 691 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Kibana", function() { return Kibana; }); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(700); +/* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(692); /* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(multimatch__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(704); +/* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(696); /* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(is_path_inside__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(502); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(579); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(574); 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; } function _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; } @@ -79273,15 +78929,15 @@ class Kibana { } /***/ }), -/* 700 */ +/* 692 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const minimatch = __webpack_require__(506); -const arrayUnion = __webpack_require__(701); -const arrayDiffer = __webpack_require__(702); -const arrify = __webpack_require__(703); +const arrayUnion = __webpack_require__(693); +const arrayDiffer = __webpack_require__(694); +const arrify = __webpack_require__(695); module.exports = (list, patterns, options = {}) => { list = arrify(list); @@ -79305,7 +78961,7 @@ module.exports = (list, patterns, options = {}) => { /***/ }), -/* 701 */ +/* 693 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79317,7 +78973,7 @@ module.exports = (...arguments_) => { /***/ }), -/* 702 */ +/* 694 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79332,7 +78988,7 @@ module.exports = arrayDiffer; /***/ }), -/* 703 */ +/* 695 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79362,12 +79018,12 @@ module.exports = arrify; /***/ }), -/* 704 */ +/* 696 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const path = __webpack_require__(16); +const path = __webpack_require__(4); module.exports = (childPath, parentPath) => { childPath = path.resolve(childPath); @@ -79390,15 +79046,15 @@ module.exports = (childPath, parentPath) => { /***/ }), -/* 705 */ +/* 697 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(706); +/* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(698); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _build_production_projects__WEBPACK_IMPORTED_MODULE_0__["buildProductionProjects"]; }); -/* harmony import */ var _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(941); +/* harmony import */ var _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(933); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__["prepareExternalProjectDependencies"]; }); /* @@ -79423,21 +79079,21 @@ __webpack_require__.r(__webpack_exports__); /***/ }), -/* 706 */ +/* 698 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return buildProductionProjects; }); -/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(707); +/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(699); /* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(cpy__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(587); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(582); /* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(579); -/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(20); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(34); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(574); +/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(491); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(500); /* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(518); /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(502); /* @@ -79475,7 +79131,7 @@ async function buildProductionProjects({ const projectGraph = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_7__["buildProjectGraph"])(projects); const batchedProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_7__["topologicallyBatchProjects"])(projects, projectGraph); const projectNames = [...projects.values()].map(project => project.name); - _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].write(`Preparing production build for [${projectNames.join(', ')}]`); + _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].info(`Preparing production build for [${projectNames.join(', ')}]`); for (const batch of batchedProjects) { for (const project of batch) { @@ -79571,21 +79227,21 @@ async function copyToBuild(project, kibanaRoot, buildRoot) { } /***/ }), -/* 707 */ +/* 699 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const EventEmitter = __webpack_require__(399); -const path = __webpack_require__(16); -const os = __webpack_require__(11); -const pAll = __webpack_require__(708); -const arrify = __webpack_require__(710); -const globby = __webpack_require__(711); -const isGlob = __webpack_require__(605); -const cpFile = __webpack_require__(926); -const junk = __webpack_require__(938); -const CpyError = __webpack_require__(939); +const EventEmitter = __webpack_require__(373); +const path = __webpack_require__(4); +const os = __webpack_require__(364); +const pAll = __webpack_require__(700); +const arrify = __webpack_require__(702); +const globby = __webpack_require__(703); +const isGlob = __webpack_require__(600); +const cpFile = __webpack_require__(918); +const junk = __webpack_require__(930); +const CpyError = __webpack_require__(931); const defaultOptions = { ignoreJunk: true @@ -79704,12 +79360,12 @@ module.exports = (source, destination, { /***/ }), -/* 708 */ +/* 700 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pMap = __webpack_require__(709); +const pMap = __webpack_require__(701); module.exports = (iterable, options) => pMap(iterable, element => element(), options); // TODO: Remove this for the next major release @@ -79717,7 +79373,7 @@ module.exports.default = module.exports; /***/ }), -/* 709 */ +/* 701 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79796,7 +79452,7 @@ module.exports.default = pMap; /***/ }), -/* 710 */ +/* 702 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79826,17 +79482,17 @@ module.exports = arrify; /***/ }), -/* 711 */ +/* 703 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(23); -const arrayUnion = __webpack_require__(712); -const glob = __webpack_require__(714); -const fastGlob = __webpack_require__(719); -const dirGlob = __webpack_require__(919); -const gitignore = __webpack_require__(922); +const fs = __webpack_require__(349); +const arrayUnion = __webpack_require__(704); +const glob = __webpack_require__(706); +const fastGlob = __webpack_require__(711); +const dirGlob = __webpack_require__(911); +const gitignore = __webpack_require__(914); const DEFAULT_FILTER = () => false; @@ -79981,12 +79637,12 @@ module.exports.gitignore = gitignore; /***/ }), -/* 712 */ +/* 704 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var arrayUniq = __webpack_require__(713); +var arrayUniq = __webpack_require__(705); module.exports = function () { return arrayUniq([].concat.apply([], arguments)); @@ -79994,7 +79650,7 @@ module.exports = function () { /***/ }), -/* 713 */ +/* 705 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80063,7 +79719,7 @@ if ('Set' in global) { /***/ }), -/* 714 */ +/* 706 */ /***/ (function(module, exports, __webpack_require__) { // Approach: @@ -80108,27 +79764,27 @@ if ('Set' in global) { module.exports = glob -var fs = __webpack_require__(23) +var fs = __webpack_require__(349) var rp = __webpack_require__(504) var minimatch = __webpack_require__(506) var Minimatch = minimatch.Minimatch -var inherits = __webpack_require__(715) -var EE = __webpack_require__(399).EventEmitter -var path = __webpack_require__(16) -var assert = __webpack_require__(30) +var inherits = __webpack_require__(707) +var EE = __webpack_require__(373).EventEmitter +var path = __webpack_require__(4) +var assert = __webpack_require__(371) var isAbsolute = __webpack_require__(512) -var globSync = __webpack_require__(717) -var common = __webpack_require__(718) +var globSync = __webpack_require__(709) +var common = __webpack_require__(710) var alphasort = common.alphasort var alphasorti = common.alphasorti var setopts = common.setopts var ownProp = common.ownProp var inflight = __webpack_require__(515) -var util = __webpack_require__(29) +var util = __webpack_require__(397) var childrenIgnored = common.childrenIgnored var isIgnored = common.isIgnored -var once = __webpack_require__(404) +var once = __webpack_require__(378) function glob (pattern, options, cb) { if (typeof options === 'function') cb = options, options = {} @@ -80859,22 +80515,22 @@ Glob.prototype._stat2 = function (f, abs, er, stat, cb) { /***/ }), -/* 715 */ +/* 707 */ /***/ (function(module, exports, __webpack_require__) { try { - var util = __webpack_require__(29); + var util = __webpack_require__(397); /* istanbul ignore next */ if (typeof util.inherits !== 'function') throw ''; module.exports = util.inherits; } catch (e) { /* istanbul ignore next */ - module.exports = __webpack_require__(716); + module.exports = __webpack_require__(708); } /***/ }), -/* 716 */ +/* 708 */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { @@ -80907,22 +80563,22 @@ if (typeof Object.create === 'function') { /***/ }), -/* 717 */ +/* 709 */ /***/ (function(module, exports, __webpack_require__) { module.exports = globSync globSync.GlobSync = GlobSync -var fs = __webpack_require__(23) +var fs = __webpack_require__(349) var rp = __webpack_require__(504) var minimatch = __webpack_require__(506) var Minimatch = minimatch.Minimatch -var Glob = __webpack_require__(714).Glob -var util = __webpack_require__(29) -var path = __webpack_require__(16) -var assert = __webpack_require__(30) +var Glob = __webpack_require__(706).Glob +var util = __webpack_require__(397) +var path = __webpack_require__(4) +var assert = __webpack_require__(371) var isAbsolute = __webpack_require__(512) -var common = __webpack_require__(718) +var common = __webpack_require__(710) var alphasort = common.alphasort var alphasorti = common.alphasorti var setopts = common.setopts @@ -81399,7 +81055,7 @@ GlobSync.prototype._makeAbs = function (f) { /***/ }), -/* 718 */ +/* 710 */ /***/ (function(module, exports, __webpack_require__) { exports.alphasort = alphasort @@ -81416,7 +81072,7 @@ function ownProp (obj, field) { return Object.prototype.hasOwnProperty.call(obj, field) } -var path = __webpack_require__(16) +var path = __webpack_require__(4) var minimatch = __webpack_require__(506) var isAbsolute = __webpack_require__(512) var Minimatch = minimatch.Minimatch @@ -81645,10 +81301,10 @@ function childrenIgnored (self, path) { /***/ }), -/* 719 */ +/* 711 */ /***/ (function(module, exports, __webpack_require__) { -const pkg = __webpack_require__(720); +const pkg = __webpack_require__(712); module.exports = pkg.async; module.exports.default = pkg.async; @@ -81661,19 +81317,19 @@ module.exports.generateTasks = pkg.generateTasks; /***/ }), -/* 720 */ +/* 712 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var optionsManager = __webpack_require__(721); -var taskManager = __webpack_require__(722); -var reader_async_1 = __webpack_require__(890); -var reader_stream_1 = __webpack_require__(914); -var reader_sync_1 = __webpack_require__(915); -var arrayUtils = __webpack_require__(917); -var streamUtils = __webpack_require__(918); +var optionsManager = __webpack_require__(713); +var taskManager = __webpack_require__(714); +var reader_async_1 = __webpack_require__(882); +var reader_stream_1 = __webpack_require__(906); +var reader_sync_1 = __webpack_require__(907); +var arrayUtils = __webpack_require__(909); +var streamUtils = __webpack_require__(910); /** * Synchronous API. */ @@ -81739,7 +81395,7 @@ function isString(source) { /***/ }), -/* 721 */ +/* 713 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81777,13 +81433,13 @@ exports.prepare = prepare; /***/ }), -/* 722 */ +/* 714 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var patternUtils = __webpack_require__(723); +var patternUtils = __webpack_require__(715); /** * Generate tasks based on parent directory of each pattern. */ @@ -81874,16 +81530,16 @@ exports.convertPatternGroupToTask = convertPatternGroupToTask; /***/ }), -/* 723 */ +/* 715 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var path = __webpack_require__(16); -var globParent = __webpack_require__(724); -var isGlob = __webpack_require__(727); -var micromatch = __webpack_require__(728); +var path = __webpack_require__(4); +var globParent = __webpack_require__(716); +var isGlob = __webpack_require__(719); +var micromatch = __webpack_require__(720); var GLOBSTAR = '**'; /** * Return true for static pattern. @@ -82029,16 +81685,16 @@ exports.matchAny = matchAny; /***/ }), -/* 724 */ +/* 716 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var path = __webpack_require__(16); -var isglob = __webpack_require__(725); -var pathDirname = __webpack_require__(726); -var isWin32 = __webpack_require__(11).platform() === 'win32'; +var path = __webpack_require__(4); +var isglob = __webpack_require__(717); +var pathDirname = __webpack_require__(718); +var isWin32 = __webpack_require__(364).platform() === 'win32'; module.exports = function globParent(str) { // flip windows path separators @@ -82060,7 +81716,7 @@ module.exports = function globParent(str) { /***/ }), -/* 725 */ +/* 717 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -82070,7 +81726,7 @@ module.exports = function globParent(str) { * Licensed under the MIT License. */ -var isExtglob = __webpack_require__(606); +var isExtglob = __webpack_require__(601); module.exports = function isGlob(str) { if (typeof str !== 'string' || str === '') { @@ -82091,14 +81747,14 @@ module.exports = function isGlob(str) { /***/ }), -/* 726 */ +/* 718 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var path = __webpack_require__(16); -var inspect = __webpack_require__(29).inspect; +var path = __webpack_require__(4); +var inspect = __webpack_require__(397).inspect; function assertPath(path) { if (typeof path !== 'string') { @@ -82241,7 +81897,7 @@ module.exports.win32 = win32; /***/ }), -/* 727 */ +/* 719 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -82251,7 +81907,7 @@ module.exports.win32 = win32; * Released under the MIT License. */ -var isExtglob = __webpack_require__(606); +var isExtglob = __webpack_require__(601); var chars = { '{': '}', '(': ')', '[': ']'}; module.exports = function isGlob(str, options) { @@ -82293,7 +81949,7 @@ module.exports = function isGlob(str, options) { /***/ }), -/* 728 */ +/* 720 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82303,19 +81959,19 @@ module.exports = function isGlob(str, options) { * Module dependencies */ -var util = __webpack_require__(29); -var braces = __webpack_require__(729); -var toRegex = __webpack_require__(842); -var extend = __webpack_require__(850); +var util = __webpack_require__(397); +var braces = __webpack_require__(721); +var toRegex = __webpack_require__(834); +var extend = __webpack_require__(842); /** * Local dependencies */ -var compilers = __webpack_require__(853); -var parsers = __webpack_require__(886); -var cache = __webpack_require__(887); -var utils = __webpack_require__(888); +var compilers = __webpack_require__(845); +var parsers = __webpack_require__(878); +var cache = __webpack_require__(879); +var utils = __webpack_require__(880); var MAX_LENGTH = 1024 * 64; /** @@ -83177,7 +82833,7 @@ module.exports = micromatch; /***/ }), -/* 729 */ +/* 721 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83187,18 +82843,18 @@ module.exports = micromatch; * Module dependencies */ -var toRegex = __webpack_require__(730); -var unique = __webpack_require__(744); -var extend = __webpack_require__(739); +var toRegex = __webpack_require__(722); +var unique = __webpack_require__(736); +var extend = __webpack_require__(731); /** * Local dependencies */ -var compilers = __webpack_require__(745); -var parsers = __webpack_require__(762); -var Braces = __webpack_require__(772); -var utils = __webpack_require__(746); +var compilers = __webpack_require__(737); +var parsers = __webpack_require__(754); +var Braces = __webpack_require__(764); +var utils = __webpack_require__(738); var MAX_LENGTH = 1024 * 64; var cache = {}; @@ -83502,15 +83158,15 @@ module.exports = braces; /***/ }), -/* 730 */ +/* 722 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(731); -var extend = __webpack_require__(739); -var not = __webpack_require__(741); +var define = __webpack_require__(723); +var extend = __webpack_require__(731); +var not = __webpack_require__(733); var MAX_LENGTH = 1024 * 64; /** @@ -83657,7 +83313,7 @@ module.exports.makeRe = makeRe; /***/ }), -/* 731 */ +/* 723 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83670,7 +83326,7 @@ module.exports.makeRe = makeRe; -var isDescriptor = __webpack_require__(732); +var isDescriptor = __webpack_require__(724); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -83695,7 +83351,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 732 */ +/* 724 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83708,9 +83364,9 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(733); -var isAccessor = __webpack_require__(734); -var isData = __webpack_require__(737); +var typeOf = __webpack_require__(725); +var isAccessor = __webpack_require__(726); +var isData = __webpack_require__(729); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -83724,7 +83380,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 733 */ +/* 725 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -83877,7 +83533,7 @@ function isBuffer(val) { /***/ }), -/* 734 */ +/* 726 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83890,7 +83546,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(735); +var typeOf = __webpack_require__(727); // accessor descriptor properties var accessor = { @@ -83953,10 +83609,10 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 735 */ +/* 727 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(736); +var isBuffer = __webpack_require__(728); var toString = Object.prototype.toString; /** @@ -84075,7 +83731,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 736 */ +/* 728 */ /***/ (function(module, exports) { /*! @@ -84102,7 +83758,7 @@ function isSlowBuffer (obj) { /***/ }), -/* 737 */ +/* 729 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84115,7 +83771,7 @@ function isSlowBuffer (obj) { -var typeOf = __webpack_require__(738); +var typeOf = __webpack_require__(730); // data descriptor properties var data = { @@ -84164,10 +83820,10 @@ module.exports = isDataDescriptor; /***/ }), -/* 738 */ +/* 730 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(736); +var isBuffer = __webpack_require__(728); var toString = Object.prototype.toString; /** @@ -84286,13 +83942,13 @@ module.exports = function kindOf(val) { /***/ }), -/* 739 */ +/* 731 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(740); +var isObject = __webpack_require__(732); module.exports = function extend(o/*, objects*/) { if (!isObject(o)) { o = {}; } @@ -84326,7 +83982,7 @@ function hasOwn(obj, key) { /***/ }), -/* 740 */ +/* 732 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84346,13 +84002,13 @@ module.exports = function isExtendable(val) { /***/ }), -/* 741 */ +/* 733 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(742); +var extend = __webpack_require__(734); /** * The main export is a function that takes a `pattern` string and an `options` object. @@ -84419,13 +84075,13 @@ module.exports = toRegex; /***/ }), -/* 742 */ +/* 734 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(743); +var isObject = __webpack_require__(735); module.exports = function extend(o/*, objects*/) { if (!isObject(o)) { o = {}; } @@ -84459,7 +84115,7 @@ function hasOwn(obj, key) { /***/ }), -/* 743 */ +/* 735 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84479,7 +84135,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 744 */ +/* 736 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84529,13 +84185,13 @@ module.exports.immutable = function uniqueImmutable(arr) { /***/ }), -/* 745 */ +/* 737 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(746); +var utils = __webpack_require__(738); module.exports = function(braces, options) { braces.compiler @@ -84818,25 +84474,25 @@ function hasQueue(node) { /***/ }), -/* 746 */ +/* 738 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var splitString = __webpack_require__(747); +var splitString = __webpack_require__(739); var utils = module.exports; /** * Module dependencies */ -utils.extend = __webpack_require__(739); -utils.flatten = __webpack_require__(753); -utils.isObject = __webpack_require__(751); -utils.fillRange = __webpack_require__(754); -utils.repeat = __webpack_require__(761); -utils.unique = __webpack_require__(744); +utils.extend = __webpack_require__(731); +utils.flatten = __webpack_require__(745); +utils.isObject = __webpack_require__(743); +utils.fillRange = __webpack_require__(746); +utils.repeat = __webpack_require__(753); +utils.unique = __webpack_require__(736); utils.define = function(obj, key, val) { Object.defineProperty(obj, key, { @@ -85168,7 +84824,7 @@ utils.escapeRegex = function(str) { /***/ }), -/* 747 */ +/* 739 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85181,7 +84837,7 @@ utils.escapeRegex = function(str) { -var extend = __webpack_require__(748); +var extend = __webpack_require__(740); module.exports = function(str, options, fn) { if (typeof str !== 'string') { @@ -85346,14 +85002,14 @@ function keepEscaping(opts, str, idx) { /***/ }), -/* 748 */ +/* 740 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(749); -var assignSymbols = __webpack_require__(752); +var isExtendable = __webpack_require__(741); +var assignSymbols = __webpack_require__(744); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -85413,7 +85069,7 @@ function isEnum(obj, key) { /***/ }), -/* 749 */ +/* 741 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85426,7 +85082,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(750); +var isPlainObject = __webpack_require__(742); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -85434,7 +85090,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 750 */ +/* 742 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85447,7 +85103,7 @@ module.exports = function isExtendable(val) { -var isObject = __webpack_require__(751); +var isObject = __webpack_require__(743); function isObjectObject(o) { return isObject(o) === true @@ -85478,7 +85134,7 @@ module.exports = function isPlainObject(o) { /***/ }), -/* 751 */ +/* 743 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85497,7 +85153,7 @@ module.exports = function isObject(val) { /***/ }), -/* 752 */ +/* 744 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85544,7 +85200,7 @@ module.exports = function(receiver, objects) { /***/ }), -/* 753 */ +/* 745 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85573,7 +85229,7 @@ function flat(arr, res) { /***/ }), -/* 754 */ +/* 746 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85586,11 +85242,11 @@ function flat(arr, res) { -var util = __webpack_require__(29); -var isNumber = __webpack_require__(755); -var extend = __webpack_require__(757); -var repeat = __webpack_require__(759); -var toRegex = __webpack_require__(760); +var util = __webpack_require__(397); +var isNumber = __webpack_require__(747); +var extend = __webpack_require__(749); +var repeat = __webpack_require__(751); +var toRegex = __webpack_require__(752); /** * Return a range of numbers or letters. @@ -85788,7 +85444,7 @@ module.exports = fillRange; /***/ }), -/* 755 */ +/* 747 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85801,7 +85457,7 @@ module.exports = fillRange; -var typeOf = __webpack_require__(756); +var typeOf = __webpack_require__(748); module.exports = function isNumber(num) { var type = typeOf(num); @@ -85817,10 +85473,10 @@ module.exports = function isNumber(num) { /***/ }), -/* 756 */ +/* 748 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(736); +var isBuffer = __webpack_require__(728); var toString = Object.prototype.toString; /** @@ -85939,13 +85595,13 @@ module.exports = function kindOf(val) { /***/ }), -/* 757 */ +/* 749 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(758); +var isObject = __webpack_require__(750); module.exports = function extend(o/*, objects*/) { if (!isObject(o)) { o = {}; } @@ -85979,7 +85635,7 @@ function hasOwn(obj, key) { /***/ }), -/* 758 */ +/* 750 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85999,7 +85655,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 759 */ +/* 751 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -86076,7 +85732,7 @@ function repeat(str, num) { /***/ }), -/* 760 */ +/* 752 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -86089,8 +85745,8 @@ function repeat(str, num) { -var repeat = __webpack_require__(759); -var isNumber = __webpack_require__(755); +var repeat = __webpack_require__(751); +var isNumber = __webpack_require__(747); var cache = {}; function toRegexRange(min, max, options) { @@ -86377,7 +86033,7 @@ module.exports = toRegexRange; /***/ }), -/* 761 */ +/* 753 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -86402,14 +86058,14 @@ module.exports = function repeat(ele, num) { /***/ }), -/* 762 */ +/* 754 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var Node = __webpack_require__(763); -var utils = __webpack_require__(746); +var Node = __webpack_require__(755); +var utils = __webpack_require__(738); /** * Braces parsers @@ -86769,15 +86425,15 @@ function concatNodes(pos, node, parent, options) { /***/ }), -/* 763 */ +/* 755 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(751); -var define = __webpack_require__(764); -var utils = __webpack_require__(771); +var isObject = __webpack_require__(743); +var define = __webpack_require__(756); +var utils = __webpack_require__(763); var ownNames; /** @@ -87268,7 +86924,7 @@ exports = module.exports = Node; /***/ }), -/* 764 */ +/* 756 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -87281,7 +86937,7 @@ exports = module.exports = Node; -var isDescriptor = __webpack_require__(765); +var isDescriptor = __webpack_require__(757); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -87306,7 +86962,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 765 */ +/* 757 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -87319,9 +86975,9 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(766); -var isAccessor = __webpack_require__(767); -var isData = __webpack_require__(769); +var typeOf = __webpack_require__(758); +var isAccessor = __webpack_require__(759); +var isData = __webpack_require__(761); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -87335,7 +86991,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 766 */ +/* 758 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -87470,7 +87126,7 @@ function isBuffer(val) { /***/ }), -/* 767 */ +/* 759 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -87483,7 +87139,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(768); +var typeOf = __webpack_require__(760); // accessor descriptor properties var accessor = { @@ -87546,7 +87202,7 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 768 */ +/* 760 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -87681,7 +87337,7 @@ function isBuffer(val) { /***/ }), -/* 769 */ +/* 761 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -87694,7 +87350,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(770); +var typeOf = __webpack_require__(762); module.exports = function isDataDescriptor(obj, prop) { // data descriptor properties @@ -87737,7 +87393,7 @@ module.exports = function isDataDescriptor(obj, prop) { /***/ }), -/* 770 */ +/* 762 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -87872,13 +87528,13 @@ function isBuffer(val) { /***/ }), -/* 771 */ +/* 763 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var typeOf = __webpack_require__(756); +var typeOf = __webpack_require__(748); var utils = module.exports; /** @@ -88898,17 +88554,17 @@ function assert(val, message) { /***/ }), -/* 772 */ +/* 764 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(739); -var Snapdragon = __webpack_require__(773); -var compilers = __webpack_require__(745); -var parsers = __webpack_require__(762); -var utils = __webpack_require__(746); +var extend = __webpack_require__(731); +var Snapdragon = __webpack_require__(765); +var compilers = __webpack_require__(737); +var parsers = __webpack_require__(754); +var utils = __webpack_require__(738); /** * Customize Snapdragon parser and renderer @@ -89009,17 +88665,17 @@ module.exports = Braces; /***/ }), -/* 773 */ +/* 765 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var Base = __webpack_require__(774); -var define = __webpack_require__(800); -var Compiler = __webpack_require__(810); -var Parser = __webpack_require__(839); -var utils = __webpack_require__(819); +var Base = __webpack_require__(766); +var define = __webpack_require__(792); +var Compiler = __webpack_require__(802); +var Parser = __webpack_require__(831); +var utils = __webpack_require__(811); var regexCache = {}; var cache = {}; @@ -89190,20 +88846,20 @@ module.exports.Parser = Parser; /***/ }), -/* 774 */ +/* 766 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var util = __webpack_require__(29); -var define = __webpack_require__(775); -var CacheBase = __webpack_require__(776); -var Emitter = __webpack_require__(777); -var isObject = __webpack_require__(751); -var merge = __webpack_require__(794); -var pascal = __webpack_require__(797); -var cu = __webpack_require__(798); +var util = __webpack_require__(397); +var define = __webpack_require__(767); +var CacheBase = __webpack_require__(768); +var Emitter = __webpack_require__(769); +var isObject = __webpack_require__(743); +var merge = __webpack_require__(786); +var pascal = __webpack_require__(789); +var cu = __webpack_require__(790); /** * Optionally define a custom `cache` namespace to use. @@ -89632,7 +89288,7 @@ module.exports.namespace = namespace; /***/ }), -/* 775 */ +/* 767 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -89645,7 +89301,7 @@ module.exports.namespace = namespace; -var isDescriptor = __webpack_require__(765); +var isDescriptor = __webpack_require__(757); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -89670,21 +89326,21 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 776 */ +/* 768 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(751); -var Emitter = __webpack_require__(777); -var visit = __webpack_require__(778); -var toPath = __webpack_require__(781); -var union = __webpack_require__(782); -var del = __webpack_require__(786); -var get = __webpack_require__(784); -var has = __webpack_require__(791); -var set = __webpack_require__(785); +var isObject = __webpack_require__(743); +var Emitter = __webpack_require__(769); +var visit = __webpack_require__(770); +var toPath = __webpack_require__(773); +var union = __webpack_require__(774); +var del = __webpack_require__(778); +var get = __webpack_require__(776); +var has = __webpack_require__(783); +var set = __webpack_require__(777); /** * Create a `Cache` constructor that when instantiated will @@ -89938,7 +89594,7 @@ module.exports.namespace = namespace; /***/ }), -/* 777 */ +/* 769 */ /***/ (function(module, exports, __webpack_require__) { @@ -90107,7 +89763,7 @@ Emitter.prototype.hasListeners = function(event){ /***/ }), -/* 778 */ +/* 770 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90120,8 +89776,8 @@ Emitter.prototype.hasListeners = function(event){ -var visit = __webpack_require__(779); -var mapVisit = __webpack_require__(780); +var visit = __webpack_require__(771); +var mapVisit = __webpack_require__(772); module.exports = function(collection, method, val) { var result; @@ -90144,7 +89800,7 @@ module.exports = function(collection, method, val) { /***/ }), -/* 779 */ +/* 771 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90157,7 +89813,7 @@ module.exports = function(collection, method, val) { -var isObject = __webpack_require__(751); +var isObject = __webpack_require__(743); module.exports = function visit(thisArg, method, target, val) { if (!isObject(thisArg) && typeof thisArg !== 'function') { @@ -90184,14 +89840,14 @@ module.exports = function visit(thisArg, method, target, val) { /***/ }), -/* 780 */ +/* 772 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var util = __webpack_require__(29); -var visit = __webpack_require__(779); +var util = __webpack_require__(397); +var visit = __webpack_require__(771); /** * Map `visit` over an array of objects. @@ -90228,7 +89884,7 @@ function isObject(val) { /***/ }), -/* 781 */ +/* 773 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90241,7 +89897,7 @@ function isObject(val) { -var typeOf = __webpack_require__(756); +var typeOf = __webpack_require__(748); module.exports = function toPath(args) { if (typeOf(args) !== 'arguments') { @@ -90268,16 +89924,16 @@ function filter(arr) { /***/ }), -/* 782 */ +/* 774 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(743); -var union = __webpack_require__(783); -var get = __webpack_require__(784); -var set = __webpack_require__(785); +var isObject = __webpack_require__(735); +var union = __webpack_require__(775); +var get = __webpack_require__(776); +var set = __webpack_require__(777); module.exports = function unionValue(obj, prop, value) { if (!isObject(obj)) { @@ -90305,7 +89961,7 @@ function arrayify(val) { /***/ }), -/* 783 */ +/* 775 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90341,7 +89997,7 @@ module.exports = function union(init) { /***/ }), -/* 784 */ +/* 776 */ /***/ (function(module, exports) { /*! @@ -90397,7 +90053,7 @@ function toString(val) { /***/ }), -/* 785 */ +/* 777 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90410,10 +90066,10 @@ function toString(val) { -var split = __webpack_require__(747); -var extend = __webpack_require__(742); -var isPlainObject = __webpack_require__(750); -var isObject = __webpack_require__(743); +var split = __webpack_require__(739); +var extend = __webpack_require__(734); +var isPlainObject = __webpack_require__(742); +var isObject = __webpack_require__(735); module.exports = function(obj, prop, val) { if (!isObject(obj)) { @@ -90459,7 +90115,7 @@ function isValidKey(key) { /***/ }), -/* 786 */ +/* 778 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90472,8 +90128,8 @@ function isValidKey(key) { -var isObject = __webpack_require__(751); -var has = __webpack_require__(787); +var isObject = __webpack_require__(743); +var has = __webpack_require__(779); module.exports = function unset(obj, prop) { if (!isObject(obj)) { @@ -90498,7 +90154,7 @@ module.exports = function unset(obj, prop) { /***/ }), -/* 787 */ +/* 779 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90511,9 +90167,9 @@ module.exports = function unset(obj, prop) { -var isObject = __webpack_require__(788); -var hasValues = __webpack_require__(790); -var get = __webpack_require__(784); +var isObject = __webpack_require__(780); +var hasValues = __webpack_require__(782); +var get = __webpack_require__(776); module.exports = function(obj, prop, noZero) { if (isObject(obj)) { @@ -90524,7 +90180,7 @@ module.exports = function(obj, prop, noZero) { /***/ }), -/* 788 */ +/* 780 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90537,7 +90193,7 @@ module.exports = function(obj, prop, noZero) { -var isArray = __webpack_require__(789); +var isArray = __webpack_require__(781); module.exports = function isObject(val) { return val != null && typeof val === 'object' && isArray(val) === false; @@ -90545,7 +90201,7 @@ module.exports = function isObject(val) { /***/ }), -/* 789 */ +/* 781 */ /***/ (function(module, exports) { var toString = {}.toString; @@ -90556,7 +90212,7 @@ module.exports = Array.isArray || function (arr) { /***/ }), -/* 790 */ +/* 782 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90599,7 +90255,7 @@ module.exports = function hasValue(o, noZero) { /***/ }), -/* 791 */ +/* 783 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90612,9 +90268,9 @@ module.exports = function hasValue(o, noZero) { -var isObject = __webpack_require__(751); -var hasValues = __webpack_require__(792); -var get = __webpack_require__(784); +var isObject = __webpack_require__(743); +var hasValues = __webpack_require__(784); +var get = __webpack_require__(776); module.exports = function(val, prop) { return hasValues(isObject(val) && prop ? get(val, prop) : val); @@ -90622,7 +90278,7 @@ module.exports = function(val, prop) { /***/ }), -/* 792 */ +/* 784 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90635,8 +90291,8 @@ module.exports = function(val, prop) { -var typeOf = __webpack_require__(793); -var isNumber = __webpack_require__(755); +var typeOf = __webpack_require__(785); +var isNumber = __webpack_require__(747); module.exports = function hasValue(val) { // is-number checks for NaN and other edge cases @@ -90689,10 +90345,10 @@ module.exports = function hasValue(val) { /***/ }), -/* 793 */ +/* 785 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(736); +var isBuffer = __webpack_require__(728); var toString = Object.prototype.toString; /** @@ -90814,14 +90470,14 @@ module.exports = function kindOf(val) { /***/ }), -/* 794 */ +/* 786 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(795); -var forIn = __webpack_require__(796); +var isExtendable = __webpack_require__(787); +var forIn = __webpack_require__(788); function mixinDeep(target, objects) { var len = arguments.length, i = 0; @@ -90885,7 +90541,7 @@ module.exports = mixinDeep; /***/ }), -/* 795 */ +/* 787 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90898,7 +90554,7 @@ module.exports = mixinDeep; -var isPlainObject = __webpack_require__(750); +var isPlainObject = __webpack_require__(742); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -90906,7 +90562,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 796 */ +/* 788 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90929,7 +90585,7 @@ module.exports = function forIn(obj, fn, thisArg) { /***/ }), -/* 797 */ +/* 789 */ /***/ (function(module, exports) { /*! @@ -90956,14 +90612,14 @@ module.exports = pascalcase; /***/ }), -/* 798 */ +/* 790 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var util = __webpack_require__(29); -var utils = __webpack_require__(799); +var util = __webpack_require__(397); +var utils = __webpack_require__(791); /** * Expose class utils @@ -91328,7 +90984,7 @@ cu.bubble = function(Parent, events) { /***/ }), -/* 799 */ +/* 791 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -91342,10 +90998,10 @@ var utils = {}; * Lazily required module dependencies */ -utils.union = __webpack_require__(783); -utils.define = __webpack_require__(800); -utils.isObj = __webpack_require__(751); -utils.staticExtend = __webpack_require__(807); +utils.union = __webpack_require__(775); +utils.define = __webpack_require__(792); +utils.isObj = __webpack_require__(743); +utils.staticExtend = __webpack_require__(799); /** @@ -91356,7 +91012,7 @@ module.exports = utils; /***/ }), -/* 800 */ +/* 792 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -91369,7 +91025,7 @@ module.exports = utils; -var isDescriptor = __webpack_require__(801); +var isDescriptor = __webpack_require__(793); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -91394,7 +91050,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 801 */ +/* 793 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -91407,9 +91063,9 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(802); -var isAccessor = __webpack_require__(803); -var isData = __webpack_require__(805); +var typeOf = __webpack_require__(794); +var isAccessor = __webpack_require__(795); +var isData = __webpack_require__(797); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -91423,7 +91079,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 802 */ +/* 794 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -91576,7 +91232,7 @@ function isBuffer(val) { /***/ }), -/* 803 */ +/* 795 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -91589,7 +91245,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(804); +var typeOf = __webpack_require__(796); // accessor descriptor properties var accessor = { @@ -91652,10 +91308,10 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 804 */ +/* 796 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(736); +var isBuffer = __webpack_require__(728); var toString = Object.prototype.toString; /** @@ -91774,7 +91430,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 805 */ +/* 797 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -91787,7 +91443,7 @@ module.exports = function kindOf(val) { -var typeOf = __webpack_require__(806); +var typeOf = __webpack_require__(798); // data descriptor properties var data = { @@ -91836,10 +91492,10 @@ module.exports = isDataDescriptor; /***/ }), -/* 806 */ +/* 798 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(736); +var isBuffer = __webpack_require__(728); var toString = Object.prototype.toString; /** @@ -91958,7 +91614,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 807 */ +/* 799 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -91971,9 +91627,9 @@ module.exports = function kindOf(val) { -var copy = __webpack_require__(808); -var define = __webpack_require__(800); -var util = __webpack_require__(29); +var copy = __webpack_require__(800); +var define = __webpack_require__(792); +var util = __webpack_require__(397); /** * Returns a function for extending the static properties, @@ -92055,15 +91711,15 @@ module.exports = extend; /***/ }), -/* 808 */ +/* 800 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var typeOf = __webpack_require__(756); -var copyDescriptor = __webpack_require__(809); -var define = __webpack_require__(800); +var typeOf = __webpack_require__(748); +var copyDescriptor = __webpack_require__(801); +var define = __webpack_require__(792); /** * Copy static properties, prototype properties, and descriptors from one object to another. @@ -92236,7 +91892,7 @@ module.exports.has = has; /***/ }), -/* 809 */ +/* 801 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -92324,16 +91980,16 @@ function isObject(val) { /***/ }), -/* 810 */ +/* 802 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(811); -var define = __webpack_require__(800); -var debug = __webpack_require__(813)('snapdragon:compiler'); -var utils = __webpack_require__(819); +var use = __webpack_require__(803); +var define = __webpack_require__(792); +var debug = __webpack_require__(805)('snapdragon:compiler'); +var utils = __webpack_require__(811); /** * Create a new `Compiler` with the given `options`. @@ -92487,7 +92143,7 @@ Compiler.prototype = { // source map support if (opts.sourcemap) { - var sourcemaps = __webpack_require__(838); + var sourcemaps = __webpack_require__(830); sourcemaps(this); this.mapVisit(this.ast.nodes); this.applySourceMaps(); @@ -92508,7 +92164,7 @@ module.exports = Compiler; /***/ }), -/* 811 */ +/* 803 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -92521,7 +92177,7 @@ module.exports = Compiler; -var utils = __webpack_require__(812); +var utils = __webpack_require__(804); module.exports = function base(app, opts) { if (!utils.isObject(app) && typeof app !== 'function') { @@ -92636,7 +92292,7 @@ module.exports = function base(app, opts) { /***/ }), -/* 812 */ +/* 804 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -92650,8 +92306,8 @@ var utils = {}; * Lazily required module dependencies */ -utils.define = __webpack_require__(800); -utils.isObject = __webpack_require__(751); +utils.define = __webpack_require__(792); +utils.isObject = __webpack_require__(743); utils.isString = function(val) { @@ -92666,7 +92322,7 @@ module.exports = utils; /***/ }), -/* 813 */ +/* 805 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -92675,14 +92331,14 @@ module.exports = utils; */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(814); + module.exports = __webpack_require__(806); } else { - module.exports = __webpack_require__(817); + module.exports = __webpack_require__(809); } /***/ }), -/* 814 */ +/* 806 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -92691,7 +92347,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(815); +exports = module.exports = __webpack_require__(807); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -92873,7 +92529,7 @@ function localstorage() { /***/ }), -/* 815 */ +/* 807 */ /***/ (function(module, exports, __webpack_require__) { @@ -92889,7 +92545,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(816); +exports.humanize = __webpack_require__(808); /** * The currently active debug mode names, and names to skip. @@ -93081,7 +92737,7 @@ function coerce(val) { /***/ }), -/* 816 */ +/* 808 */ /***/ (function(module, exports) { /** @@ -93239,15 +92895,15 @@ function plural(ms, n, name) { /***/ }), -/* 817 */ +/* 809 */ /***/ (function(module, exports, __webpack_require__) { /** * Module dependencies. */ -var tty = __webpack_require__(484); -var util = __webpack_require__(29); +var tty = __webpack_require__(471); +var util = __webpack_require__(397); /** * This is the Node.js implementation of `debug()`. @@ -93255,7 +92911,7 @@ var util = __webpack_require__(29); * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(815); +exports = module.exports = __webpack_require__(807); exports.init = init; exports.log = log; exports.formatArgs = formatArgs; @@ -93427,14 +93083,14 @@ function createWritableStdioStream (fd) { break; case 'FILE': - var fs = __webpack_require__(23); + var fs = __webpack_require__(349); stream = new fs.SyncWriteStream(fd, { autoClose: false }); stream._type = 'fs'; break; case 'PIPE': case 'TCP': - var net = __webpack_require__(818); + var net = __webpack_require__(810); stream = new net.Socket({ fd: fd, readable: false, @@ -93493,13 +93149,13 @@ exports.enable(load()); /***/ }), -/* 818 */ +/* 810 */ /***/ (function(module, exports) { module.exports = require("net"); /***/ }), -/* 819 */ +/* 811 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -93509,9 +93165,9 @@ module.exports = require("net"); * Module dependencies */ -exports.extend = __webpack_require__(742); -exports.SourceMap = __webpack_require__(820); -exports.sourceMapResolve = __webpack_require__(831); +exports.extend = __webpack_require__(734); +exports.SourceMap = __webpack_require__(812); +exports.sourceMapResolve = __webpack_require__(823); /** * Convert backslash in the given string to forward slashes @@ -93554,7 +93210,7 @@ exports.last = function(arr, n) { /***/ }), -/* 820 */ +/* 812 */ /***/ (function(module, exports, __webpack_require__) { /* @@ -93562,13 +93218,13 @@ exports.last = function(arr, n) { * Licensed under the New BSD license. See LICENSE.txt or: * http://opensource.org/licenses/BSD-3-Clause */ -exports.SourceMapGenerator = __webpack_require__(821).SourceMapGenerator; -exports.SourceMapConsumer = __webpack_require__(827).SourceMapConsumer; -exports.SourceNode = __webpack_require__(830).SourceNode; +exports.SourceMapGenerator = __webpack_require__(813).SourceMapGenerator; +exports.SourceMapConsumer = __webpack_require__(819).SourceMapConsumer; +exports.SourceNode = __webpack_require__(822).SourceNode; /***/ }), -/* 821 */ +/* 813 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -93578,10 +93234,10 @@ exports.SourceNode = __webpack_require__(830).SourceNode; * http://opensource.org/licenses/BSD-3-Clause */ -var base64VLQ = __webpack_require__(822); -var util = __webpack_require__(824); -var ArraySet = __webpack_require__(825).ArraySet; -var MappingList = __webpack_require__(826).MappingList; +var base64VLQ = __webpack_require__(814); +var util = __webpack_require__(816); +var ArraySet = __webpack_require__(817).ArraySet; +var MappingList = __webpack_require__(818).MappingList; /** * An instance of the SourceMapGenerator represents a source map which is @@ -93990,7 +93646,7 @@ exports.SourceMapGenerator = SourceMapGenerator; /***/ }), -/* 822 */ +/* 814 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -94030,7 +93686,7 @@ exports.SourceMapGenerator = SourceMapGenerator; * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -var base64 = __webpack_require__(823); +var base64 = __webpack_require__(815); // A single base 64 digit can contain 6 bits of data. For the base 64 variable // length quantities we use in the source map spec, the first bit is the sign, @@ -94136,7 +93792,7 @@ exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { /***/ }), -/* 823 */ +/* 815 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -94209,7 +93865,7 @@ exports.decode = function (charCode) { /***/ }), -/* 824 */ +/* 816 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -94632,7 +94288,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate /***/ }), -/* 825 */ +/* 817 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -94642,7 +94298,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(824); +var util = __webpack_require__(816); var has = Object.prototype.hasOwnProperty; var hasNativeMap = typeof Map !== "undefined"; @@ -94759,7 +94415,7 @@ exports.ArraySet = ArraySet; /***/ }), -/* 826 */ +/* 818 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -94769,7 +94425,7 @@ exports.ArraySet = ArraySet; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(824); +var util = __webpack_require__(816); /** * Determine whether mappingB is after mappingA with respect to generated @@ -94844,7 +94500,7 @@ exports.MappingList = MappingList; /***/ }), -/* 827 */ +/* 819 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -94854,11 +94510,11 @@ exports.MappingList = MappingList; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(824); -var binarySearch = __webpack_require__(828); -var ArraySet = __webpack_require__(825).ArraySet; -var base64VLQ = __webpack_require__(822); -var quickSort = __webpack_require__(829).quickSort; +var util = __webpack_require__(816); +var binarySearch = __webpack_require__(820); +var ArraySet = __webpack_require__(817).ArraySet; +var base64VLQ = __webpack_require__(814); +var quickSort = __webpack_require__(821).quickSort; function SourceMapConsumer(aSourceMap) { var sourceMap = aSourceMap; @@ -95932,7 +95588,7 @@ exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; /***/ }), -/* 828 */ +/* 820 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -96049,7 +95705,7 @@ exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { /***/ }), -/* 829 */ +/* 821 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -96169,7 +95825,7 @@ exports.quickSort = function (ary, comparator) { /***/ }), -/* 830 */ +/* 822 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -96179,8 +95835,8 @@ exports.quickSort = function (ary, comparator) { * http://opensource.org/licenses/BSD-3-Clause */ -var SourceMapGenerator = __webpack_require__(821).SourceMapGenerator; -var util = __webpack_require__(824); +var SourceMapGenerator = __webpack_require__(813).SourceMapGenerator; +var util = __webpack_require__(816); // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other // operating systems these days (capturing the result). @@ -96588,17 +96244,17 @@ exports.SourceNode = SourceNode; /***/ }), -/* 831 */ +/* 823 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014, 2015, 2016, 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var sourceMappingURL = __webpack_require__(832) -var resolveUrl = __webpack_require__(833) -var decodeUriComponent = __webpack_require__(834) -var urix = __webpack_require__(836) -var atob = __webpack_require__(837) +var sourceMappingURL = __webpack_require__(824) +var resolveUrl = __webpack_require__(825) +var decodeUriComponent = __webpack_require__(826) +var urix = __webpack_require__(828) +var atob = __webpack_require__(829) @@ -96896,7 +96552,7 @@ module.exports = { /***/ }), -/* 832 */ +/* 824 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;// Copyright 2014 Simon Lydell @@ -96959,13 +96615,13 @@ void (function(root, factory) { /***/ }), -/* 833 */ +/* 825 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var url = __webpack_require__(452) +var url = __webpack_require__(439) function resolveUrl(/* ...urls */) { return Array.prototype.reduce.call(arguments, function(resolved, nextUrl) { @@ -96977,13 +96633,13 @@ module.exports = resolveUrl /***/ }), -/* 834 */ +/* 826 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var decodeUriComponent = __webpack_require__(835) +var decodeUriComponent = __webpack_require__(827) function customDecodeUriComponent(string) { // `decodeUriComponent` turns `+` into ` `, but that's not wanted. @@ -96994,7 +96650,7 @@ module.exports = customDecodeUriComponent /***/ }), -/* 835 */ +/* 827 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -97095,13 +96751,13 @@ module.exports = function (encodedURI) { /***/ }), -/* 836 */ +/* 828 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var path = __webpack_require__(16) +var path = __webpack_require__(4) "use strict" @@ -97118,7 +96774,7 @@ module.exports = urix /***/ }), -/* 837 */ +/* 829 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -97132,16 +96788,16 @@ module.exports = atob.atob = atob; /***/ }), -/* 838 */ +/* 830 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var fs = __webpack_require__(23); -var path = __webpack_require__(16); -var define = __webpack_require__(800); -var utils = __webpack_require__(819); +var fs = __webpack_require__(349); +var path = __webpack_require__(4); +var define = __webpack_require__(792); +var utils = __webpack_require__(811); /** * Expose `mixin()`. @@ -97284,19 +96940,19 @@ exports.comment = function(node) { /***/ }), -/* 839 */ +/* 831 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(811); -var util = __webpack_require__(29); -var Cache = __webpack_require__(840); -var define = __webpack_require__(800); -var debug = __webpack_require__(813)('snapdragon:parser'); -var Position = __webpack_require__(841); -var utils = __webpack_require__(819); +var use = __webpack_require__(803); +var util = __webpack_require__(397); +var Cache = __webpack_require__(832); +var define = __webpack_require__(792); +var debug = __webpack_require__(805)('snapdragon:parser'); +var Position = __webpack_require__(833); +var utils = __webpack_require__(811); /** * Create a new `Parser` with the given `input` and `options`. @@ -97824,7 +97480,7 @@ module.exports = Parser; /***/ }), -/* 840 */ +/* 832 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -97931,13 +97587,13 @@ MapCache.prototype.del = function mapDelete(key) { /***/ }), -/* 841 */ +/* 833 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(800); +var define = __webpack_require__(792); /** * Store position for a node @@ -97952,16 +97608,16 @@ module.exports = function Position(start, parser) { /***/ }), -/* 842 */ +/* 834 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var safe = __webpack_require__(843); -var define = __webpack_require__(849); -var extend = __webpack_require__(850); -var not = __webpack_require__(852); +var safe = __webpack_require__(835); +var define = __webpack_require__(841); +var extend = __webpack_require__(842); +var not = __webpack_require__(844); var MAX_LENGTH = 1024 * 64; /** @@ -98114,10 +97770,10 @@ module.exports.makeRe = makeRe; /***/ }), -/* 843 */ +/* 835 */ /***/ (function(module, exports, __webpack_require__) { -var parse = __webpack_require__(844); +var parse = __webpack_require__(836); var types = parse.types; module.exports = function (re, opts) { @@ -98163,13 +97819,13 @@ function isRegExp (x) { /***/ }), -/* 844 */ +/* 836 */ /***/ (function(module, exports, __webpack_require__) { -var util = __webpack_require__(845); -var types = __webpack_require__(846); -var sets = __webpack_require__(847); -var positions = __webpack_require__(848); +var util = __webpack_require__(837); +var types = __webpack_require__(838); +var sets = __webpack_require__(839); +var positions = __webpack_require__(840); module.exports = function(regexpStr) { @@ -98451,11 +98107,11 @@ module.exports.types = types; /***/ }), -/* 845 */ +/* 837 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(846); -var sets = __webpack_require__(847); +var types = __webpack_require__(838); +var sets = __webpack_require__(839); // All of these are private and only used by randexp. @@ -98568,7 +98224,7 @@ exports.error = function(regexp, msg) { /***/ }), -/* 846 */ +/* 838 */ /***/ (function(module, exports) { module.exports = { @@ -98584,10 +98240,10 @@ module.exports = { /***/ }), -/* 847 */ +/* 839 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(846); +var types = __webpack_require__(838); var INTS = function() { return [{ type: types.RANGE , from: 48, to: 57 }]; @@ -98672,10 +98328,10 @@ exports.anyChar = function() { /***/ }), -/* 848 */ +/* 840 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(846); +var types = __webpack_require__(838); exports.wordBoundary = function() { return { type: types.POSITION, value: 'b' }; @@ -98695,7 +98351,7 @@ exports.end = function() { /***/ }), -/* 849 */ +/* 841 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -98708,8 +98364,8 @@ exports.end = function() { -var isobject = __webpack_require__(751); -var isDescriptor = __webpack_require__(765); +var isobject = __webpack_require__(743); +var isDescriptor = __webpack_require__(757); var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) ? Reflect.defineProperty : Object.defineProperty; @@ -98740,14 +98396,14 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 850 */ +/* 842 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(851); -var assignSymbols = __webpack_require__(752); +var isExtendable = __webpack_require__(843); +var assignSymbols = __webpack_require__(744); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -98807,7 +98463,7 @@ function isEnum(obj, key) { /***/ }), -/* 851 */ +/* 843 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -98820,7 +98476,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(750); +var isPlainObject = __webpack_require__(742); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -98828,14 +98484,14 @@ module.exports = function isExtendable(val) { /***/ }), -/* 852 */ +/* 844 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(850); -var safe = __webpack_require__(843); +var extend = __webpack_require__(842); +var safe = __webpack_require__(835); /** * The main export is a function that takes a `pattern` string and an `options` object. @@ -98907,14 +98563,14 @@ module.exports = toRegex; /***/ }), -/* 853 */ +/* 845 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var nanomatch = __webpack_require__(854); -var extglob = __webpack_require__(870); +var nanomatch = __webpack_require__(846); +var extglob = __webpack_require__(862); module.exports = function(snapdragon) { var compilers = snapdragon.compiler.compilers; @@ -98991,7 +98647,7 @@ function escapeExtglobs(compiler) { /***/ }), -/* 854 */ +/* 846 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -99001,18 +98657,18 @@ function escapeExtglobs(compiler) { * Module dependencies */ -var util = __webpack_require__(29); -var toRegex = __webpack_require__(855); -var extend = __webpack_require__(856); +var util = __webpack_require__(397); +var toRegex = __webpack_require__(847); +var extend = __webpack_require__(848); /** * Local dependencies */ -var compilers = __webpack_require__(858); -var parsers = __webpack_require__(859); -var cache = __webpack_require__(862); -var utils = __webpack_require__(864); +var compilers = __webpack_require__(850); +var parsers = __webpack_require__(851); +var cache = __webpack_require__(854); +var utils = __webpack_require__(856); var MAX_LENGTH = 1024 * 64; /** @@ -99836,15 +99492,15 @@ module.exports = nanomatch; /***/ }), -/* 855 */ +/* 847 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(800); -var extend = __webpack_require__(742); -var not = __webpack_require__(741); +var define = __webpack_require__(792); +var extend = __webpack_require__(734); +var not = __webpack_require__(733); var MAX_LENGTH = 1024 * 64; /** @@ -99991,14 +99647,14 @@ module.exports.makeRe = makeRe; /***/ }), -/* 856 */ +/* 848 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(857); -var assignSymbols = __webpack_require__(752); +var isExtendable = __webpack_require__(849); +var assignSymbols = __webpack_require__(744); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -100058,7 +99714,7 @@ function isEnum(obj, key) { /***/ }), -/* 857 */ +/* 849 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -100071,7 +99727,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(750); +var isPlainObject = __webpack_require__(742); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -100079,7 +99735,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 858 */ +/* 850 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -100425,15 +100081,15 @@ module.exports = function(nanomatch, options) { /***/ }), -/* 859 */ +/* 851 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regexNot = __webpack_require__(741); -var toRegex = __webpack_require__(855); -var isOdd = __webpack_require__(860); +var regexNot = __webpack_require__(733); +var toRegex = __webpack_require__(847); +var isOdd = __webpack_require__(852); /** * Characters to use in negation regex (we want to "not" match @@ -100819,7 +100475,7 @@ module.exports.not = NOT_REGEX; /***/ }), -/* 860 */ +/* 852 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -100832,7 +100488,7 @@ module.exports.not = NOT_REGEX; -var isNumber = __webpack_require__(861); +var isNumber = __webpack_require__(853); module.exports = function isOdd(i) { if (!isNumber(i)) { @@ -100846,7 +100502,7 @@ module.exports = function isOdd(i) { /***/ }), -/* 861 */ +/* 853 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -100874,14 +100530,14 @@ module.exports = function isNumber(num) { /***/ }), -/* 862 */ +/* 854 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(863))(); +module.exports = new (__webpack_require__(855))(); /***/ }), -/* 863 */ +/* 855 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -100894,7 +100550,7 @@ module.exports = new (__webpack_require__(863))(); -var MapCache = __webpack_require__(840); +var MapCache = __webpack_require__(832); /** * Create a new `FragmentCache` with an optional object to use for `caches`. @@ -101016,27 +100672,27 @@ exports = module.exports = FragmentCache; /***/ }), -/* 864 */ +/* 856 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var utils = module.exports; -var path = __webpack_require__(16); +var path = __webpack_require__(4); /** * Module dependencies */ -var isWindows = __webpack_require__(865)(); -var Snapdragon = __webpack_require__(773); -utils.define = __webpack_require__(866); -utils.diff = __webpack_require__(867); -utils.extend = __webpack_require__(856); -utils.pick = __webpack_require__(868); -utils.typeOf = __webpack_require__(869); -utils.unique = __webpack_require__(744); +var isWindows = __webpack_require__(857)(); +var Snapdragon = __webpack_require__(765); +utils.define = __webpack_require__(858); +utils.diff = __webpack_require__(859); +utils.extend = __webpack_require__(848); +utils.pick = __webpack_require__(860); +utils.typeOf = __webpack_require__(861); +utils.unique = __webpack_require__(736); /** * Returns true if the given value is effectively an empty string @@ -101402,7 +101058,7 @@ utils.unixify = function(options) { /***/ }), -/* 865 */ +/* 857 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! @@ -101430,7 +101086,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ /***/ }), -/* 866 */ +/* 858 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -101443,8 +101099,8 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ -var isobject = __webpack_require__(751); -var isDescriptor = __webpack_require__(765); +var isobject = __webpack_require__(743); +var isDescriptor = __webpack_require__(757); var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) ? Reflect.defineProperty : Object.defineProperty; @@ -101475,7 +101131,7 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 867 */ +/* 859 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -101529,7 +101185,7 @@ function diffArray(one, two) { /***/ }), -/* 868 */ +/* 860 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -101542,7 +101198,7 @@ function diffArray(one, two) { -var isObject = __webpack_require__(751); +var isObject = __webpack_require__(743); module.exports = function pick(obj, keys) { if (!isObject(obj) && typeof obj !== 'function') { @@ -101571,7 +101227,7 @@ module.exports = function pick(obj, keys) { /***/ }), -/* 869 */ +/* 861 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -101706,7 +101362,7 @@ function isBuffer(val) { /***/ }), -/* 870 */ +/* 862 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -101716,18 +101372,18 @@ function isBuffer(val) { * Module dependencies */ -var extend = __webpack_require__(742); -var unique = __webpack_require__(744); -var toRegex = __webpack_require__(855); +var extend = __webpack_require__(734); +var unique = __webpack_require__(736); +var toRegex = __webpack_require__(847); /** * Local dependencies */ -var compilers = __webpack_require__(871); -var parsers = __webpack_require__(882); -var Extglob = __webpack_require__(885); -var utils = __webpack_require__(884); +var compilers = __webpack_require__(863); +var parsers = __webpack_require__(874); +var Extglob = __webpack_require__(877); +var utils = __webpack_require__(876); var MAX_LENGTH = 1024 * 64; /** @@ -102044,13 +101700,13 @@ module.exports = extglob; /***/ }), -/* 871 */ +/* 863 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(872); +var brackets = __webpack_require__(864); /** * Extglob compilers @@ -102220,7 +101876,7 @@ module.exports = function(extglob) { /***/ }), -/* 872 */ +/* 864 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -102230,17 +101886,17 @@ module.exports = function(extglob) { * Local dependencies */ -var compilers = __webpack_require__(873); -var parsers = __webpack_require__(875); +var compilers = __webpack_require__(865); +var parsers = __webpack_require__(867); /** * Module dependencies */ -var debug = __webpack_require__(877)('expand-brackets'); -var extend = __webpack_require__(742); -var Snapdragon = __webpack_require__(773); -var toRegex = __webpack_require__(855); +var debug = __webpack_require__(869)('expand-brackets'); +var extend = __webpack_require__(734); +var Snapdragon = __webpack_require__(765); +var toRegex = __webpack_require__(847); /** * Parses the given POSIX character class `pattern` and returns a @@ -102438,13 +102094,13 @@ module.exports = brackets; /***/ }), -/* 873 */ +/* 865 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var posix = __webpack_require__(874); +var posix = __webpack_require__(866); module.exports = function(brackets) { brackets.compiler @@ -102532,7 +102188,7 @@ module.exports = function(brackets) { /***/ }), -/* 874 */ +/* 866 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -102561,14 +102217,14 @@ module.exports = { /***/ }), -/* 875 */ +/* 867 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(876); -var define = __webpack_require__(800); +var utils = __webpack_require__(868); +var define = __webpack_require__(792); /** * Text regex @@ -102787,14 +102443,14 @@ module.exports.TEXT_REGEX = TEXT_REGEX; /***/ }), -/* 876 */ +/* 868 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var toRegex = __webpack_require__(855); -var regexNot = __webpack_require__(741); +var toRegex = __webpack_require__(847); +var regexNot = __webpack_require__(733); var cached; /** @@ -102828,7 +102484,7 @@ exports.createRegex = function(pattern, include) { /***/ }), -/* 877 */ +/* 869 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -102837,14 +102493,14 @@ exports.createRegex = function(pattern, include) { */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(878); + module.exports = __webpack_require__(870); } else { - module.exports = __webpack_require__(881); + module.exports = __webpack_require__(873); } /***/ }), -/* 878 */ +/* 870 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -102853,7 +102509,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(879); +exports = module.exports = __webpack_require__(871); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -103035,7 +102691,7 @@ function localstorage() { /***/ }), -/* 879 */ +/* 871 */ /***/ (function(module, exports, __webpack_require__) { @@ -103051,7 +102707,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(880); +exports.humanize = __webpack_require__(872); /** * The currently active debug mode names, and names to skip. @@ -103243,7 +102899,7 @@ function coerce(val) { /***/ }), -/* 880 */ +/* 872 */ /***/ (function(module, exports) { /** @@ -103401,15 +103057,15 @@ function plural(ms, n, name) { /***/ }), -/* 881 */ +/* 873 */ /***/ (function(module, exports, __webpack_require__) { /** * Module dependencies. */ -var tty = __webpack_require__(484); -var util = __webpack_require__(29); +var tty = __webpack_require__(471); +var util = __webpack_require__(397); /** * This is the Node.js implementation of `debug()`. @@ -103417,7 +103073,7 @@ var util = __webpack_require__(29); * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(879); +exports = module.exports = __webpack_require__(871); exports.init = init; exports.log = log; exports.formatArgs = formatArgs; @@ -103589,14 +103245,14 @@ function createWritableStdioStream (fd) { break; case 'FILE': - var fs = __webpack_require__(23); + var fs = __webpack_require__(349); stream = new fs.SyncWriteStream(fd, { autoClose: false }); stream._type = 'fs'; break; case 'PIPE': case 'TCP': - var net = __webpack_require__(818); + var net = __webpack_require__(810); stream = new net.Socket({ fd: fd, readable: false, @@ -103655,15 +103311,15 @@ exports.enable(load()); /***/ }), -/* 882 */ +/* 874 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(872); -var define = __webpack_require__(883); -var utils = __webpack_require__(884); +var brackets = __webpack_require__(864); +var define = __webpack_require__(875); +var utils = __webpack_require__(876); /** * Characters to use in text regex (we want to "not" match @@ -103818,7 +103474,7 @@ module.exports = parsers; /***/ }), -/* 883 */ +/* 875 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -103831,7 +103487,7 @@ module.exports = parsers; -var isDescriptor = __webpack_require__(765); +var isDescriptor = __webpack_require__(757); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -103856,14 +103512,14 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 884 */ +/* 876 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regex = __webpack_require__(741); -var Cache = __webpack_require__(863); +var regex = __webpack_require__(733); +var Cache = __webpack_require__(855); /** * Utils @@ -103932,7 +103588,7 @@ utils.createRegex = function(str) { /***/ }), -/* 885 */ +/* 877 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -103942,16 +103598,16 @@ utils.createRegex = function(str) { * Module dependencies */ -var Snapdragon = __webpack_require__(773); -var define = __webpack_require__(883); -var extend = __webpack_require__(742); +var Snapdragon = __webpack_require__(765); +var define = __webpack_require__(875); +var extend = __webpack_require__(734); /** * Local dependencies */ -var compilers = __webpack_require__(871); -var parsers = __webpack_require__(882); +var compilers = __webpack_require__(863); +var parsers = __webpack_require__(874); /** * Customize Snapdragon parser and renderer @@ -104017,16 +103673,16 @@ module.exports = Extglob; /***/ }), -/* 886 */ +/* 878 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extglob = __webpack_require__(870); -var nanomatch = __webpack_require__(854); -var regexNot = __webpack_require__(741); -var toRegex = __webpack_require__(842); +var extglob = __webpack_require__(862); +var nanomatch = __webpack_require__(846); +var regexNot = __webpack_require__(733); +var toRegex = __webpack_require__(834); var not; /** @@ -104107,33 +103763,33 @@ function textRegex(pattern) { /***/ }), -/* 887 */ +/* 879 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(863))(); +module.exports = new (__webpack_require__(855))(); /***/ }), -/* 888 */ +/* 880 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var utils = module.exports; -var path = __webpack_require__(16); +var path = __webpack_require__(4); /** * Module dependencies */ -var Snapdragon = __webpack_require__(773); -utils.define = __webpack_require__(849); -utils.diff = __webpack_require__(867); -utils.extend = __webpack_require__(850); -utils.pick = __webpack_require__(868); -utils.typeOf = __webpack_require__(889); -utils.unique = __webpack_require__(744); +var Snapdragon = __webpack_require__(765); +utils.define = __webpack_require__(841); +utils.diff = __webpack_require__(859); +utils.extend = __webpack_require__(842); +utils.pick = __webpack_require__(860); +utils.typeOf = __webpack_require__(881); +utils.unique = __webpack_require__(736); /** * Returns true if the platform is windows, or `path.sep` is `\\`. @@ -104430,7 +104086,7 @@ utils.unixify = function(options) { /***/ }), -/* 889 */ +/* 881 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -104565,7 +104221,7 @@ function isBuffer(val) { /***/ }), -/* 890 */ +/* 882 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -104584,9 +104240,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(891); -var reader_1 = __webpack_require__(904); -var fs_stream_1 = __webpack_require__(908); +var readdir = __webpack_require__(883); +var reader_1 = __webpack_require__(896); +var fs_stream_1 = __webpack_require__(900); var ReaderAsync = /** @class */ (function (_super) { __extends(ReaderAsync, _super); function ReaderAsync() { @@ -104647,15 +104303,15 @@ exports.default = ReaderAsync; /***/ }), -/* 891 */ +/* 883 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const readdirSync = __webpack_require__(892); -const readdirAsync = __webpack_require__(900); -const readdirStream = __webpack_require__(903); +const readdirSync = __webpack_require__(884); +const readdirAsync = __webpack_require__(892); +const readdirStream = __webpack_require__(895); module.exports = exports = readdirAsyncPath; exports.readdir = exports.readdirAsync = exports.async = readdirAsyncPath; @@ -104739,7 +104395,7 @@ function readdirStreamStat (dir, options) { /***/ }), -/* 892 */ +/* 884 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -104747,11 +104403,11 @@ function readdirStreamStat (dir, options) { module.exports = readdirSync; -const DirectoryReader = __webpack_require__(893); +const DirectoryReader = __webpack_require__(885); let syncFacade = { - fs: __webpack_require__(898), - forEach: __webpack_require__(899), + fs: __webpack_require__(890), + forEach: __webpack_require__(891), sync: true }; @@ -104780,18 +104436,18 @@ function readdirSync (dir, options, internalOptions) { /***/ }), -/* 893 */ +/* 885 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const Readable = __webpack_require__(27).Readable; -const EventEmitter = __webpack_require__(399).EventEmitter; -const path = __webpack_require__(16); -const normalizeOptions = __webpack_require__(894); -const stat = __webpack_require__(896); -const call = __webpack_require__(897); +const Readable = __webpack_require__(382).Readable; +const EventEmitter = __webpack_require__(373).EventEmitter; +const path = __webpack_require__(4); +const normalizeOptions = __webpack_require__(886); +const stat = __webpack_require__(888); +const call = __webpack_require__(889); /** * Asynchronously reads the contents of a directory and streams the results @@ -105167,14 +104823,14 @@ module.exports = DirectoryReader; /***/ }), -/* 894 */ +/* 886 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const path = __webpack_require__(16); -const globToRegExp = __webpack_require__(895); +const path = __webpack_require__(4); +const globToRegExp = __webpack_require__(887); module.exports = normalizeOptions; @@ -105351,7 +105007,7 @@ function normalizeOptions (options, internalOptions) { /***/ }), -/* 895 */ +/* 887 */ /***/ (function(module, exports) { module.exports = function (glob, opts) { @@ -105488,13 +105144,13 @@ module.exports = function (glob, opts) { /***/ }), -/* 896 */ +/* 888 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const call = __webpack_require__(897); +const call = __webpack_require__(889); module.exports = stat; @@ -105569,7 +105225,7 @@ function symlinkStat (fs, path, lstats, callback) { /***/ }), -/* 897 */ +/* 889 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105630,14 +105286,14 @@ function callOnce (fn) { /***/ }), -/* 898 */ +/* 890 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(23); -const call = __webpack_require__(897); +const fs = __webpack_require__(349); +const call = __webpack_require__(889); /** * A facade around {@link fs.readdirSync} that allows it to be called @@ -105701,7 +105357,7 @@ exports.lstat = function (path, callback) { /***/ }), -/* 899 */ +/* 891 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105730,7 +105386,7 @@ function syncForEach (array, iterator, done) { /***/ }), -/* 900 */ +/* 892 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105738,12 +105394,12 @@ function syncForEach (array, iterator, done) { module.exports = readdirAsync; -const maybe = __webpack_require__(901); -const DirectoryReader = __webpack_require__(893); +const maybe = __webpack_require__(893); +const DirectoryReader = __webpack_require__(885); let asyncFacade = { - fs: __webpack_require__(23), - forEach: __webpack_require__(902), + fs: __webpack_require__(349), + forEach: __webpack_require__(894), async: true }; @@ -105785,7 +105441,7 @@ function readdirAsync (dir, options, callback, internalOptions) { /***/ }), -/* 901 */ +/* 893 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105812,7 +105468,7 @@ module.exports = function maybe (cb, promise) { /***/ }), -/* 902 */ +/* 894 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105848,7 +105504,7 @@ function asyncForEach (array, iterator, done) { /***/ }), -/* 903 */ +/* 895 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105856,11 +105512,11 @@ function asyncForEach (array, iterator, done) { module.exports = readdirStream; -const DirectoryReader = __webpack_require__(893); +const DirectoryReader = __webpack_require__(885); let streamFacade = { - fs: __webpack_require__(23), - forEach: __webpack_require__(902), + fs: __webpack_require__(349), + forEach: __webpack_require__(894), async: true }; @@ -105880,16 +105536,16 @@ function readdirStream (dir, options, internalOptions) { /***/ }), -/* 904 */ +/* 896 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var path = __webpack_require__(16); -var deep_1 = __webpack_require__(905); -var entry_1 = __webpack_require__(907); -var pathUtil = __webpack_require__(906); +var path = __webpack_require__(4); +var deep_1 = __webpack_require__(897); +var entry_1 = __webpack_require__(899); +var pathUtil = __webpack_require__(898); var Reader = /** @class */ (function () { function Reader(options) { this.options = options; @@ -105955,14 +105611,14 @@ exports.default = Reader; /***/ }), -/* 905 */ +/* 897 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(906); -var patternUtils = __webpack_require__(723); +var pathUtils = __webpack_require__(898); +var patternUtils = __webpack_require__(715); var DeepFilter = /** @class */ (function () { function DeepFilter(options, micromatchOptions) { this.options = options; @@ -106045,13 +105701,13 @@ exports.default = DeepFilter; /***/ }), -/* 906 */ +/* 898 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var path = __webpack_require__(16); +var path = __webpack_require__(4); /** * Returns «true» if the last partial of the path starting with a period. */ @@ -106076,14 +105732,14 @@ exports.makeAbsolute = makeAbsolute; /***/ }), -/* 907 */ +/* 899 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(906); -var patternUtils = __webpack_require__(723); +var pathUtils = __webpack_require__(898); +var patternUtils = __webpack_require__(715); var EntryFilter = /** @class */ (function () { function EntryFilter(options, micromatchOptions) { this.options = options; @@ -106168,7 +105824,7 @@ exports.default = EntryFilter; /***/ }), -/* 908 */ +/* 900 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -106187,9 +105843,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var stream = __webpack_require__(27); -var fsStat = __webpack_require__(909); -var fs_1 = __webpack_require__(913); +var stream = __webpack_require__(382); +var fsStat = __webpack_require__(901); +var fs_1 = __webpack_require__(905); var FileSystemStream = /** @class */ (function (_super) { __extends(FileSystemStream, _super); function FileSystemStream() { @@ -106239,14 +105895,14 @@ exports.default = FileSystemStream; /***/ }), -/* 909 */ +/* 901 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const optionsManager = __webpack_require__(910); -const statProvider = __webpack_require__(912); +const optionsManager = __webpack_require__(902); +const statProvider = __webpack_require__(904); /** * Asynchronous API. */ @@ -106277,13 +105933,13 @@ exports.statSync = statSync; /***/ }), -/* 910 */ +/* 902 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsAdapter = __webpack_require__(911); +const fsAdapter = __webpack_require__(903); function prepare(opts) { const options = Object.assign({ fs: fsAdapter.getFileSystemAdapter(opts ? opts.fs : undefined), @@ -106296,13 +105952,13 @@ exports.prepare = prepare; /***/ }), -/* 911 */ +/* 903 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(23); +const fs = __webpack_require__(349); exports.FILE_SYSTEM_ADAPTER = { lstat: fs.lstat, stat: fs.stat, @@ -106319,7 +105975,7 @@ exports.getFileSystemAdapter = getFileSystemAdapter; /***/ }), -/* 912 */ +/* 904 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -106371,13 +106027,13 @@ exports.isFollowedSymlink = isFollowedSymlink; /***/ }), -/* 913 */ +/* 905 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var path = __webpack_require__(16); +var path = __webpack_require__(4); var FileSystem = /** @class */ (function () { function FileSystem(options) { this.options = options; @@ -106402,7 +106058,7 @@ exports.default = FileSystem; /***/ }), -/* 914 */ +/* 906 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -106421,10 +106077,10 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var stream = __webpack_require__(27); -var readdir = __webpack_require__(891); -var reader_1 = __webpack_require__(904); -var fs_stream_1 = __webpack_require__(908); +var stream = __webpack_require__(382); +var readdir = __webpack_require__(883); +var reader_1 = __webpack_require__(896); +var fs_stream_1 = __webpack_require__(900); var TransformStream = /** @class */ (function (_super) { __extends(TransformStream, _super); function TransformStream(reader) { @@ -106492,7 +106148,7 @@ exports.default = ReaderStream; /***/ }), -/* 915 */ +/* 907 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -106511,9 +106167,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(891); -var reader_1 = __webpack_require__(904); -var fs_sync_1 = __webpack_require__(916); +var readdir = __webpack_require__(883); +var reader_1 = __webpack_require__(896); +var fs_sync_1 = __webpack_require__(908); var ReaderSync = /** @class */ (function (_super) { __extends(ReaderSync, _super); function ReaderSync() { @@ -106573,7 +106229,7 @@ exports.default = ReaderSync; /***/ }), -/* 916 */ +/* 908 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -106592,8 +106248,8 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var fsStat = __webpack_require__(909); -var fs_1 = __webpack_require__(913); +var fsStat = __webpack_require__(901); +var fs_1 = __webpack_require__(905); var FileSystemSync = /** @class */ (function (_super) { __extends(FileSystemSync, _super); function FileSystemSync() { @@ -106639,7 +106295,7 @@ exports.default = FileSystemSync; /***/ }), -/* 917 */ +/* 909 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -106655,13 +106311,13 @@ exports.flatten = flatten; /***/ }), -/* 918 */ +/* 910 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var merge2 = __webpack_require__(590); +var merge2 = __webpack_require__(585); /** * Merge multiple streams and propagate their errors into one stream in parallel. */ @@ -106676,13 +106332,13 @@ exports.merge = merge; /***/ }), -/* 919 */ +/* 911 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const path = __webpack_require__(16); -const pathType = __webpack_require__(920); +const path = __webpack_require__(4); +const pathType = __webpack_require__(912); const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; @@ -106748,13 +106404,13 @@ module.exports.sync = (input, opts) => { /***/ }), -/* 920 */ +/* 912 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(23); -const pify = __webpack_require__(921); +const fs = __webpack_require__(349); +const pify = __webpack_require__(913); function type(fn, fn2, fp) { if (typeof fp !== 'string') { @@ -106797,7 +106453,7 @@ exports.symlinkSync = typeSync.bind(null, 'lstatSync', 'isSymbolicLink'); /***/ }), -/* 921 */ +/* 913 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -106888,17 +106544,17 @@ module.exports = (obj, opts) => { /***/ }), -/* 922 */ +/* 914 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(23); -const path = __webpack_require__(16); -const fastGlob = __webpack_require__(719); -const gitIgnore = __webpack_require__(923); -const pify = __webpack_require__(924); -const slash = __webpack_require__(925); +const fs = __webpack_require__(349); +const path = __webpack_require__(4); +const fastGlob = __webpack_require__(711); +const gitIgnore = __webpack_require__(915); +const pify = __webpack_require__(916); +const slash = __webpack_require__(917); const DEFAULT_IGNORE = [ '**/node_modules/**', @@ -106996,7 +106652,7 @@ module.exports.sync = options => { /***/ }), -/* 923 */ +/* 915 */ /***/ (function(module, exports) { // A simple implementation of make-array @@ -107465,7 +107121,7 @@ module.exports = options => new IgnoreBase(options) /***/ }), -/* 924 */ +/* 916 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -107540,7 +107196,7 @@ module.exports = (input, options) => { /***/ }), -/* 925 */ +/* 917 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -107558,17 +107214,17 @@ module.exports = input => { /***/ }), -/* 926 */ +/* 918 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const path = __webpack_require__(16); -const {constants: fsConstants} = __webpack_require__(23); -const pEvent = __webpack_require__(927); -const CpFileError = __webpack_require__(930); -const fs = __webpack_require__(934); -const ProgressEmitter = __webpack_require__(937); +const path = __webpack_require__(4); +const {constants: fsConstants} = __webpack_require__(349); +const pEvent = __webpack_require__(919); +const CpFileError = __webpack_require__(922); +const fs = __webpack_require__(926); +const ProgressEmitter = __webpack_require__(929); const cpFileAsync = async (source, destination, options, progressEmitter) => { let readError; @@ -107682,12 +107338,12 @@ module.exports.sync = (source, destination, options) => { /***/ }), -/* 927 */ +/* 919 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pTimeout = __webpack_require__(928); +const pTimeout = __webpack_require__(920); const symbolAsyncIterator = Symbol.asyncIterator || '@@asyncIterator'; @@ -107978,12 +107634,12 @@ module.exports.iterator = (emitter, event, options) => { /***/ }), -/* 928 */ +/* 920 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pFinally = __webpack_require__(929); +const pFinally = __webpack_require__(921); class TimeoutError extends Error { constructor(message) { @@ -108029,7 +107685,7 @@ module.exports.TimeoutError = TimeoutError; /***/ }), -/* 929 */ +/* 921 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -108051,12 +107707,12 @@ module.exports = (promise, onFinally) => { /***/ }), -/* 930 */ +/* 922 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(931); +const NestedError = __webpack_require__(923); class CpFileError extends NestedError { constructor(message, nested) { @@ -108070,10 +107726,10 @@ module.exports = CpFileError; /***/ }), -/* 931 */ +/* 923 */ /***/ (function(module, exports, __webpack_require__) { -var inherits = __webpack_require__(932); +var inherits = __webpack_require__(924); var NestedError = function (message, nested) { this.nested = nested; @@ -108124,20 +107780,20 @@ module.exports = NestedError; /***/ }), -/* 932 */ +/* 924 */ /***/ (function(module, exports, __webpack_require__) { try { - var util = __webpack_require__(29); + var util = __webpack_require__(397); if (typeof util.inherits !== 'function') throw ''; module.exports = util.inherits; } catch (e) { - module.exports = __webpack_require__(933); + module.exports = __webpack_require__(925); } /***/ }), -/* 933 */ +/* 925 */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { @@ -108166,16 +107822,16 @@ if (typeof Object.create === 'function') { /***/ }), -/* 934 */ +/* 926 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const {promisify} = __webpack_require__(29); -const fs = __webpack_require__(22); -const makeDir = __webpack_require__(935); -const pEvent = __webpack_require__(927); -const CpFileError = __webpack_require__(930); +const {promisify} = __webpack_require__(397); +const fs = __webpack_require__(493); +const makeDir = __webpack_require__(927); +const pEvent = __webpack_require__(919); +const CpFileError = __webpack_require__(922); const stat = promisify(fs.stat); const lstat = promisify(fs.lstat); @@ -108272,15 +107928,15 @@ exports.copyFileSync = (source, destination, flags) => { /***/ }), -/* 935 */ +/* 927 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(23); -const path = __webpack_require__(16); -const {promisify} = __webpack_require__(29); -const semver = __webpack_require__(936); +const fs = __webpack_require__(349); +const path = __webpack_require__(4); +const {promisify} = __webpack_require__(397); +const semver = __webpack_require__(928); const defaults = { mode: 0o777 & (~process.umask()), @@ -108429,7 +108085,7 @@ module.exports.sync = (input, options) => { /***/ }), -/* 936 */ +/* 928 */ /***/ (function(module, exports) { exports = module.exports = SemVer @@ -110031,12 +109687,12 @@ function coerce (version, options) { /***/ }), -/* 937 */ +/* 929 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const EventEmitter = __webpack_require__(399); +const EventEmitter = __webpack_require__(373); const written = new WeakMap(); @@ -110072,7 +109728,7 @@ module.exports = ProgressEmitter; /***/ }), -/* 938 */ +/* 930 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -110118,12 +109774,12 @@ exports.default = module.exports; /***/ }), -/* 939 */ +/* 931 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(940); +const NestedError = __webpack_require__(932); class CpyError extends NestedError { constructor(message, nested) { @@ -110137,10 +109793,10 @@ module.exports = CpyError; /***/ }), -/* 940 */ +/* 932 */ /***/ (function(module, exports, __webpack_require__) { -var inherits = __webpack_require__(29).inherits; +var inherits = __webpack_require__(397).inherits; var NestedError = function (message, nested) { this.nested = nested; @@ -110193,7 +109849,7 @@ module.exports = NestedError; /***/ }), -/* 941 */ +/* 933 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; diff --git a/packages/kbn-pm/package.json b/packages/kbn-pm/package.json index 234877e9ae626..301d9653cda2b 100644 --- a/packages/kbn-pm/package.json +++ b/packages/kbn-pm/package.json @@ -22,7 +22,6 @@ "@types/glob": "^5.0.35", "@types/globby": "^6.1.0", "@types/has-ansi": "^3.0.0", - "@types/indent-string": "^3.0.0", "@types/lodash.clonedeepwith": "^4.5.3", "@types/log-symbols": "^2.0.0", "@types/ncp": "^2.0.1", @@ -32,7 +31,6 @@ "@types/strip-ansi": "^3.0.0", "@types/strong-log-transformer": "^1.0.0", "@types/tempy": "^0.2.0", - "@types/wrap-ansi": "^2.0.15", "@types/write-pkg": "^3.1.0", "@kbn/dev-utils": "1.0.0", "@yarnpkg/lockfile": "^1.1.0", @@ -42,12 +40,11 @@ "cpy": "^8.0.0", "dedent": "^0.7.0", "del": "^5.1.0", - "execa": "^4.0.0", + "execa": "^4.0.2", "getopts": "^2.2.4", "glob": "^7.1.2", "globby": "^8.0.1", "has-ansi": "^3.0.0", - "indent-string": "^3.2.0", "is-path-inside": "^3.0.2", "lodash.clonedeepwith": "^4.5.0", "log-symbols": "^2.2.0", @@ -66,7 +63,6 @@ "unlazy-loader": "^0.1.3", "webpack": "^4.41.5", "webpack-cli": "^3.3.10", - "wrap-ansi": "^3.0.1", "write-pkg": "^4.0.0" }, "dependencies": { diff --git a/packages/kbn-pm/src/cli.ts b/packages/kbn-pm/src/cli.ts index 94f348e1835ed..b72e9ae8690aa 100644 --- a/packages/kbn-pm/src/cli.ts +++ b/packages/kbn-pm/src/cli.ts @@ -17,46 +17,58 @@ * under the License. */ -import chalk from 'chalk'; import dedent from 'dedent'; import getopts from 'getopts'; import { resolve } from 'path'; +import { pickLevelFromFlags } from '@kbn/dev-utils'; import { commands } from './commands'; import { runCommand } from './run'; import { log } from './utils/log'; function help() { - const availableCommands = Object.keys(commands) - .map((commandName) => commands[commandName]) - .map((command) => `${command.name} - ${command.description}`); - - log.write(dedent` - usage: kbn [] - - By default commands are run for Kibana itself, all packages in the 'packages/' - folder and for all plugins in './plugins' and '../kibana-extra'. - - Available commands: - - ${availableCommands.join('\n ')} - - Global options: - - -e, --exclude Exclude specified project. Can be specified multiple times to exclude multiple projects, e.g. '-e kibana -e @kbn/pm'. - -i, --include Include only specified projects. If left unspecified, it defaults to including all projects. - --oss Do not include the x-pack when running command. - --skip-kibana-plugins Filter all plugins in ./plugins and ../kibana-extra when running command. - --no-cache Disable the bootstrap cache - `); + log.info( + dedent` + usage: kbn [] + + By default commands are run for Kibana itself, all packages in the 'packages/' + folder and for all plugins in './plugins' and '../kibana-extra'. + + Available commands: + + ${Object.values(commands) + .map((command) => `${command.name} - ${command.description}`) + .join('\n ')} + + Global options: + + -e, --exclude Exclude specified project. Can be specified multiple times to exclude multiple projects, e.g. '-e kibana -e @kbn/pm'. + -i, --include Include only specified projects. If left unspecified, it defaults to including all projects. + --oss Do not include the x-pack when running command. + --skip-kibana-plugins Filter all plugins in ./plugins and ../kibana-extra when running command. + --no-cache Disable the bootstrap cache + --verbose Set log level to verbose + --debug Set log level to debug + --quiet Set log level to error + --silent Disable log output + ` + '\n' + ); } export async function run(argv: string[]) { + log.setLogLevel( + pickLevelFromFlags( + getopts(argv, { + boolean: ['verbose', 'debug', 'quiet', 'silent'], + }) + ) + ); + // We can simplify this setup (and remove this extra handling) once Yarn // starts forwarding the `--` directly to this script, see // https://github.com/yarnpkg/yarn/blob/b2d3e1a8fe45ef376b716d597cc79b38702a9320/src/cli/index.js#L174-L182 if (argv.includes('--')) { - log.write(chalk.red(`Using "--" is not allowed, as it doesn't work with 'yarn kbn'.`)); + log.error(`Using "--" is not allowed, as it doesn't work with 'yarn kbn'.`); process.exit(1); } @@ -90,7 +102,7 @@ export async function run(argv: string[]) { const command = commands[commandName]; if (command === undefined) { - log.write(chalk.red(`[${commandName}] is not a valid command, see 'kbn --help'`)); + log.error(`[${commandName}] is not a valid command, see 'kbn --help'`); process.exit(1); } diff --git a/packages/kbn-pm/src/commands/__snapshots__/bootstrap.test.ts.snap b/packages/kbn-pm/src/commands/__snapshots__/bootstrap.test.ts.snap index c0505710f5670..be146d710c87a 100644 --- a/packages/kbn-pm/src/commands/__snapshots__/bootstrap.test.ts.snap +++ b/packages/kbn-pm/src/commands/__snapshots__/bootstrap.test.ts.snap @@ -90,29 +90,32 @@ Array [ exports[`calls "kbn:bootstrap" scripts and links executables after installing deps: script 1`] = ` Array [ Array [ - "kbn:bootstrap", - Array [], - Project { - "allDependencies": Object {}, - "devDependencies": Object {}, - "isWorkspaceProject": false, - "isWorkspaceRoot": false, - "json": Object { - "name": "bar", + Object { + "args": Array [], + "debug": undefined, + "pkg": Project { + "allDependencies": Object {}, + "devDependencies": Object {}, + "isWorkspaceProject": false, + "isWorkspaceRoot": false, + "json": Object { + "name": "bar", + "scripts": Object { + "kbn:bootstrap": "node ./bar.js", + }, + "version": "1.0.0", + }, + "nodeModulesLocation": "/packages/kbn-pm/src/commands/packages/bar/node_modules", + "packageJsonLocation": "/packages/kbn-pm/src/commands/packages/bar/package.json", + "path": "/packages/kbn-pm/src/commands/packages/bar", + "productionDependencies": Object {}, "scripts": Object { "kbn:bootstrap": "node ./bar.js", }, + "targetLocation": "/packages/kbn-pm/src/commands/packages/bar/target", "version": "1.0.0", }, - "nodeModulesLocation": "/packages/kbn-pm/src/commands/packages/bar/node_modules", - "packageJsonLocation": "/packages/kbn-pm/src/commands/packages/bar/package.json", - "path": "/packages/kbn-pm/src/commands/packages/bar", - "productionDependencies": Object {}, - "scripts": Object { - "kbn:bootstrap": "node ./bar.js", - }, - "targetLocation": "/packages/kbn-pm/src/commands/packages/bar/target", - "version": "1.0.0", + "script": "kbn:bootstrap", }, ], ] @@ -127,36 +130,6 @@ Array [ ] `; -exports[`does not run installer if no deps in package: logs 1`] = ` -Array [ - Array [ - " -Running installs in topological order:", - ], - Array [ - " - -Installing dependencies in [kibana]: -", - ], - Array [ - " -Installs completed, linking package executables: -", - ], - Array [ - " -Linking executables completed, running \`kbn:bootstrap\` scripts -", - ], - Array [ - " -Bootstrapping completed! -", - ], -] -`; - exports[`handles "frozen-lockfile": install in dir 1`] = ` Array [ Array [ @@ -184,45 +157,3 @@ Array [ ], ] `; - -exports[`handles dependencies of dependencies: logs 1`] = ` -Array [ - Array [ - " -Running installs in topological order:", - ], - Array [ - " - -Installing dependencies in [kibana]: -", - ], - Array [ - " - -Installing dependencies in [bar]: -", - ], - Array [ - " - -Installing dependencies in [foo]: -", - ], - Array [ - " -Installs completed, linking package executables: -", - ], - Array [ - " -Linking executables completed, running \`kbn:bootstrap\` scripts -", - ], - Array [ - " -Bootstrapping completed! -", - ], -] -`; diff --git a/packages/kbn-pm/src/commands/bootstrap.test.ts b/packages/kbn-pm/src/commands/bootstrap.test.ts index 072f34611f8fc..d6a30f0ef33d6 100644 --- a/packages/kbn-pm/src/commands/bootstrap.test.ts +++ b/packages/kbn-pm/src/commands/bootstrap.test.ts @@ -22,6 +22,8 @@ jest.mock('../utils/link_project_executables'); import { resolve } from 'path'; +import { ToolingLogCollectingWriter } from '@kbn/dev-utils'; + import { absolutePathSnapshotSerializer, stripAnsiSnapshotSerializer } from '../test_helpers'; import { linkProjectExecutables } from '../utils/link_project_executables'; import { IPackageJson } from '../utils/package_json'; @@ -30,12 +32,20 @@ import { buildProjectGraph } from '../utils/projects'; import { installInDir, runScriptInPackageStreaming, yarnWorkspacesInfo } from '../utils/scripts'; import { BootstrapCommand } from './bootstrap'; import { Kibana } from '../utils/kibana'; +import { log } from '../utils/log'; const mockInstallInDir = installInDir as jest.Mock; const mockRunScriptInPackageStreaming = runScriptInPackageStreaming as jest.Mock; const mockLinkProjectExecutables = linkProjectExecutables as jest.Mock; const mockYarnWorkspacesInfo = yarnWorkspacesInfo as jest.Mock; +const logWriter = new ToolingLogCollectingWriter('debug'); +log.setLogLevel('silent'); +log.setWriters([logWriter]); +beforeEach(() => { + logWriter.messages.length = 0; +}); + const createProject = (packageJson: IPackageJson, path = '.') => { const project = new Project( { @@ -55,10 +65,6 @@ const createProject = (packageJson: IPackageJson, path = '.') => { expect.addSnapshotSerializer(absolutePathSnapshotSerializer); expect.addSnapshotSerializer(stripAnsiSnapshotSerializer); -const noop = () => { - // noop -}; - beforeEach(() => { mockYarnWorkspacesInfo.mockResolvedValue({}); }); @@ -111,8 +117,6 @@ test('handles dependencies of dependencies', async () => { const kbn = new Kibana(projects); const projectGraph = buildProjectGraph(projects); - const logMock = jest.spyOn(console, 'log').mockImplementation(noop); - await BootstrapCommand.run(projects, projectGraph, { extraArgs: [], options: {}, @@ -121,7 +125,19 @@ test('handles dependencies of dependencies', async () => { }); expect(mockInstallInDir.mock.calls).toMatchSnapshot('install in dir'); - expect(logMock.mock.calls).toMatchSnapshot('logs'); + expect(logWriter.messages).toMatchInlineSnapshot(` + Array [ + " info [kibana] running yarn", + "", + "", + " info [bar] running yarn", + "", + "", + " info [foo] running yarn", + "", + "", + ] + `); }); test('does not run installer if no deps in package', async () => { @@ -148,8 +164,6 @@ test('does not run installer if no deps in package', async () => { const kbn = new Kibana(projects); const projectGraph = buildProjectGraph(projects); - const logMock = jest.spyOn(console, 'log').mockImplementation(noop); - await BootstrapCommand.run(projects, projectGraph, { extraArgs: [], options: {}, @@ -158,7 +172,13 @@ test('does not run installer if no deps in package', async () => { }); expect(mockInstallInDir.mock.calls).toMatchSnapshot('install in dir'); - expect(logMock.mock.calls).toMatchSnapshot('logs'); + expect(logWriter.messages).toMatchInlineSnapshot(` + Array [ + " info [kibana] running yarn", + "", + "", + ] + `); }); test('handles "frozen-lockfile"', async () => { @@ -175,8 +195,6 @@ test('handles "frozen-lockfile"', async () => { const kbn = new Kibana(projects); const projectGraph = buildProjectGraph(projects); - jest.spyOn(console, 'log').mockImplementation(noop); - await BootstrapCommand.run(projects, projectGraph, { extraArgs: [], options: { @@ -215,8 +233,6 @@ test('calls "kbn:bootstrap" scripts and links executables after installing deps' const kbn = new Kibana(projects); const projectGraph = buildProjectGraph(projects); - jest.spyOn(console, 'log').mockImplementation(noop); - await BootstrapCommand.run(projects, projectGraph, { extraArgs: [], options: {}, diff --git a/packages/kbn-pm/src/commands/bootstrap.ts b/packages/kbn-pm/src/commands/bootstrap.ts index 6146aeab21db4..80ccc5daecc56 100644 --- a/packages/kbn-pm/src/commands/bootstrap.ts +++ b/packages/kbn-pm/src/commands/bootstrap.ts @@ -17,12 +17,11 @@ * under the License. */ -import chalk from 'chalk'; - import { linkProjectExecutables } from '../utils/link_project_executables'; import { log } from '../utils/log'; import { parallelizeBatches } from '../utils/parallelize'; import { topologicallyBatchProjects } from '../utils/projects'; +import { Project } from '../utils/project'; import { ICommand } from './'; import { getAllChecksums } from '../utils/project_checksums'; import { BootstrapCacheFile } from '../utils/bootstrap_cache_file'; @@ -42,12 +41,10 @@ export const BootstrapCommand: ICommand = { ...(options['prefer-offline'] === true ? ['--prefer-offline'] : []), ]; - log.write(chalk.bold('\nRunning installs in topological order:')); - for (const batch of batchedProjectsByWorkspace) { for (const project of batch) { if (project.isWorkspaceProject) { - log.write(`Skipping workspace project: ${project.name}`); + log.verbose(`Skipping workspace project: ${project.name}`); continue; } @@ -57,7 +54,6 @@ export const BootstrapCommand: ICommand = { } } - log.write(chalk.bold('\nInstalls completed, linking package executables:\n')); await linkProjectExecutables(projects, projectGraph); /** @@ -66,22 +62,38 @@ export const BootstrapCommand: ICommand = { * transpiled before they can be used. Ideally we shouldn't do this unless we * have to, as it will slow down the bootstrapping process. */ - log.write(chalk.bold('\nLinking executables completed, running `kbn:bootstrap` scripts\n')); - const checksums = options.cache ? await getAllChecksums(kbn, log) : false; - await parallelizeBatches(batchedProjects, async (project) => { + const checksums = await getAllChecksums(kbn, log); + const caches = new Map(); + let cachedProjectCount = 0; + + for (const project of projects.values()) { if (project.hasScript('kbn:bootstrap')) { - const cacheFile = new BootstrapCacheFile(kbn, project, checksums); - if (cacheFile.isValid()) { - log.success(`[${project.name}] cache up to date`); - } else { - cacheFile.delete(); - await project.runScriptStreaming('kbn:bootstrap'); - cacheFile.write(); + const file = new BootstrapCacheFile(kbn, project, checksums); + const valid = options.cache && file.isValid(); + + if (valid) { + log.debug(`[${project.name}] cache up to date`); } + + caches.set(project, { file, valid }); + cachedProjectCount += 1; } - }); + } + + if (cachedProjectCount > 0) { + log.success(`${cachedProjectCount} bootsrap builds are cached`); + } - log.write(chalk.green.bold('\nBootstrapping completed!\n')); + await parallelizeBatches(batchedProjects, async (project) => { + const cache = caches.get(project); + if (cache && !cache.valid) { + log.info(`[${project.name}] running [kbn:bootstrap] script`); + cache.file.delete(); + await project.runScriptStreaming('kbn:bootstrap'); + cache.file.write(); + log.success(`[${project.name}] bootstrap complete`); + } + }); }, }; diff --git a/packages/kbn-pm/src/commands/clean.ts b/packages/kbn-pm/src/commands/clean.ts index b3d433e22bd79..26d6897992501 100644 --- a/packages/kbn-pm/src/commands/clean.ts +++ b/packages/kbn-pm/src/commands/clean.ts @@ -17,7 +17,6 @@ * under the License. */ -import chalk from 'chalk'; import del from 'del'; import ora from 'ora'; import { join, relative } from 'path'; @@ -57,10 +56,8 @@ export const CleanCommand: ICommand = { } if (toDelete.length === 0) { - log.write(chalk.bold.green('\n\nNothing to delete')); + log.success('Nothing to delete'); } else { - log.write(chalk.bold.red('\n\nDeleting:\n')); - /** * In order to avoid patterns like `/build` in packages from accidentally * impacting files outside the package we use `process.chdir()` to change @@ -75,7 +72,11 @@ export const CleanCommand: ICommand = { for (const { pattern, cwd } of toDelete) { process.chdir(cwd); const promise = del(pattern); - ora.promise(promise, relative(originalCwd, join(cwd, String(pattern)))); + + if (log.wouldLogLevel('info')) { + ora.promise(promise, relative(originalCwd, join(cwd, String(pattern)))); + } + await promise; } } finally { diff --git a/packages/kbn-pm/src/commands/run.ts b/packages/kbn-pm/src/commands/run.ts index 989bfef19c380..1c6760ed6f3ee 100644 --- a/packages/kbn-pm/src/commands/run.ts +++ b/packages/kbn-pm/src/commands/run.ts @@ -17,8 +17,7 @@ * under the License. */ -import chalk from 'chalk'; - +import { CliError } from '../utils/errors'; import { log } from '../utils/log'; import { parallelizeBatches } from '../utils/parallelize'; import { topologicallyBatchProjects } from '../utils/projects'; @@ -32,20 +31,19 @@ export const RunCommand: ICommand = { const batchedProjects = topologicallyBatchProjects(projects, projectGraph); if (extraArgs.length === 0) { - log.write(chalk.red.bold('\nNo script specified')); - process.exit(1); + throw new CliError('No script specified'); } const scriptName = extraArgs[0]; const scriptArgs = extraArgs.slice(1); - log.write( - chalk.bold(`\nRunning script [${chalk.green(scriptName)}] in batched topological order\n`) - ); - - await parallelizeBatches(batchedProjects, async (pkg) => { - if (pkg.hasScript(scriptName)) { - await pkg.runScriptStreaming(scriptName, scriptArgs); + await parallelizeBatches(batchedProjects, async (project) => { + if (project.hasScript(scriptName)) { + log.info(`[${project.name}] running "${scriptName}" script`); + await project.runScriptStreaming(scriptName, { + args: scriptArgs, + }); + log.success(`[${project.name}] complete`); } }); }, diff --git a/packages/kbn-pm/src/commands/watch.ts b/packages/kbn-pm/src/commands/watch.ts index 2e18b02a1c860..6775f728c1494 100644 --- a/packages/kbn-pm/src/commands/watch.ts +++ b/packages/kbn-pm/src/commands/watch.ts @@ -17,7 +17,7 @@ * under the License. */ -import chalk from 'chalk'; +import { CliError } from '../utils/errors'; import { log } from '../utils/log'; import { parallelizeBatches } from '../utils/parallelize'; import { ProjectMap, topologicallyBatchProjects } from '../utils/projects'; @@ -58,20 +58,13 @@ export const WatchCommand: ICommand = { } if (projectsToWatch.size === 0) { - log.write( - chalk.red( - `\nThere are no projects to watch found. Make sure that projects define 'kbn:watch' script in 'package.json'.\n` - ) + throw new CliError( + `There are no projects to watch found. Make sure that projects define 'kbn:watch' script in 'package.json'.` ); - return; } const projectNames = Array.from(projectsToWatch.keys()); - log.write( - chalk.bold( - chalk.green(`Running ${watchScriptName} scripts for [${projectNames.join(', ')}].`) - ) - ); + log.info(`Running ${watchScriptName} scripts for [${projectNames.join(', ')}].`); // Kibana should always be run the last, so we don't rely on automatic // topological batching and push it to the last one-entry batch manually. @@ -85,12 +78,12 @@ export const WatchCommand: ICommand = { await parallelizeBatches(batchedProjects, async (pkg) => { const completionHint = await waitUntilWatchIsReady( - pkg.runScriptStreaming(watchScriptName).stdout + pkg.runScriptStreaming(watchScriptName, { + debug: false, + }).stdout ); - log.write( - chalk.bold(`[${chalk.green(pkg.name)}] Initial build completed (${completionHint}).`) - ); + log.success(`[${pkg.name}] Initial build completed (${completionHint}).`); }); }, }; diff --git a/packages/kbn-pm/src/production/build_production_projects.ts b/packages/kbn-pm/src/production/build_production_projects.ts index 689bf51cd7bdf..f5c59fd582c59 100644 --- a/packages/kbn-pm/src/production/build_production_projects.ts +++ b/packages/kbn-pm/src/production/build_production_projects.ts @@ -47,7 +47,7 @@ export async function buildProductionProjects({ const batchedProjects = topologicallyBatchProjects(projects, projectGraph); const projectNames = [...projects.values()].map((project) => project.name); - log.write(`Preparing production build for [${projectNames.join(', ')}]`); + log.info(`Preparing production build for [${projectNames.join(', ')}]`); for (const batch of batchedProjects) { for (const project of batch) { diff --git a/packages/kbn-pm/src/run.test.ts b/packages/kbn-pm/src/run.test.ts index ff0dc2666afea..b2479af3809c4 100644 --- a/packages/kbn-pm/src/run.test.ts +++ b/packages/kbn-pm/src/run.test.ts @@ -18,9 +18,13 @@ */ import { resolve } from 'path'; + import { ICommand, ICommandConfig } from './commands'; import { runCommand } from './run'; import { Project } from './utils/project'; +import { log } from './utils/log'; + +log.setLogLevel('silent'); const rootPath = resolve(`${__dirname}/utils/__fixtures__/kibana`); @@ -51,11 +55,6 @@ beforeEach(() => { options: {}, rootPath, }; - - // Reduce the noise that comes from the run command. - jest.spyOn(console, 'log').mockImplementation(() => { - // noop - }); }); test('passes all found projects to the command if no filter is specified', async () => { diff --git a/packages/kbn-pm/src/run.ts b/packages/kbn-pm/src/run.ts index c3879c701d785..04286590bd821 100644 --- a/packages/kbn-pm/src/run.ts +++ b/packages/kbn-pm/src/run.ts @@ -17,10 +17,6 @@ * under the License. */ -import chalk from 'chalk'; -import indentString from 'indent-string'; -import wrapAnsi from 'wrap-ansi'; - import { ICommand, ICommandConfig } from './commands'; import { CliError } from './utils/errors'; import { log } from './utils/log'; @@ -30,11 +26,7 @@ import { Kibana } from './utils/kibana'; export async function runCommand(command: ICommand, config: Omit) { try { - log.write( - chalk.bold( - `Running [${chalk.green(command.name)}] command from [${chalk.yellow(config.rootPath)}]:\n` - ) - ); + log.debug(`Running [${command.name}] command from [${config.rootPath}]`); const kbn = await Kibana.loadFrom(config.rootPath); const projects = kbn.getFilteredProjects({ @@ -45,42 +37,39 @@ export async function runCommand(command: ICommand, config: Omit 0) { - const metaOutput = keys.map((key) => { - const value = e.meta[key]; - return `${key}: ${value}`; - }); + const metaOutput = Object.entries(error.meta) + .map(([key, value]) => `${key}: ${value}`) + .join('\n'); - log.write('Additional debugging info:\n'); - log.write(indentString(metaOutput.join('\n'), 3)); + if (metaOutput) { + log.info('Additional debugging info:\n'); + log.indent(2); + log.info(metaOutput); + log.indent(-2); } } else { - log.write(e.stack); + log.error(error); } process.exit(1); diff --git a/packages/kbn-pm/src/utils/__snapshots__/link_project_executables.test.ts.snap b/packages/kbn-pm/src/utils/__snapshots__/link_project_executables.test.ts.snap index 62091205b01a4..5bda7b544e201 100644 --- a/packages/kbn-pm/src/utils/__snapshots__/link_project_executables.test.ts.snap +++ b/packages/kbn-pm/src/utils/__snapshots__/link_project_executables.test.ts.snap @@ -68,14 +68,3 @@ Object { "unlink": Array [], } `; - -exports[`bin script points to a file creates a symlink in the project node_modules/.bin directory: logs 1`] = ` -Array [ - Array [ - "[foo] bar -> ../bar/bin/bar.js", - ], - Array [ - "[baz] bar -> ../bar/bin/bar.js", - ], -] -`; diff --git a/packages/kbn-pm/src/utils/child_process.ts b/packages/kbn-pm/src/utils/child_process.ts index 784446924a8dc..bafe2bf57adc2 100644 --- a/packages/kbn-pm/src/utils/child_process.ts +++ b/packages/kbn-pm/src/utils/child_process.ts @@ -17,19 +17,20 @@ * under the License. */ +import { Writable } from 'stream'; + import chalk from 'chalk'; import execa from 'execa'; -import logSymbols from 'log-symbols'; import logTransformer from 'strong-log-transformer'; -function generateColors() { - const colorWheel = [chalk.cyan, chalk.magenta, chalk.blue, chalk.yellow, chalk.green]; - - const count = colorWheel.length; - let children = 0; +import { log } from './log'; - return () => colorWheel[children++ % count]; -} +const colorWheel = [chalk.cyan, chalk.magenta, chalk.blue, chalk.yellow, chalk.green]; +const getColor = () => { + const color = colorWheel.shift()!; + colorWheel.push(color); + return color; +}; export function spawn(command: string, args: string[], opts: execa.Options) { return execa(command, args, { @@ -39,13 +40,26 @@ export function spawn(command: string, args: string[], opts: execa.Options) { }); } -const nextColor = generateColors(); +function streamToLog(debug: boolean = true) { + return new Writable({ + objectMode: true, + write(line, _, cb) { + if (line.endsWith('\n')) { + log[debug ? 'debug' : 'write'](line.slice(0, -1)); + } else { + log[debug ? 'debug' : 'write'](line); + } + + cb(); + }, + }); +} export function spawnStreaming( command: string, args: string[], opts: execa.Options, - { prefix }: { prefix: string } + { prefix, debug }: { prefix: string; debug?: boolean } ) { const spawned = execa(command, args, { stdio: ['ignore', 'pipe', 'pipe'], @@ -53,15 +67,12 @@ export function spawnStreaming( ...opts, }); - const color = nextColor(); - const prefixedStdout = logTransformer({ tag: `${color.bold(prefix)}:` }); - const prefixedStderr = logTransformer({ - mergeMultiline: true, - tag: `${logSymbols.error} ${color.bold(prefix)}:`, - }); + const color = getColor(); + const prefixedStdout = logTransformer({ tag: color.bold(prefix) }); + const prefixedStderr = logTransformer({ mergeMultiline: true, tag: color.bold(prefix) }); - spawned.stdout.pipe(prefixedStdout).pipe(process.stdout); - spawned.stderr.pipe(prefixedStderr).pipe(process.stderr); + spawned.stdout.pipe(prefixedStdout).pipe(streamToLog(debug)); + spawned.stderr.pipe(prefixedStderr).pipe(streamToLog(debug)); return spawned; } diff --git a/packages/kbn-pm/src/utils/link_project_executables.test.ts b/packages/kbn-pm/src/utils/link_project_executables.test.ts index a19e1fd66f334..887c474a12eca 100644 --- a/packages/kbn-pm/src/utils/link_project_executables.test.ts +++ b/packages/kbn-pm/src/utils/link_project_executables.test.ts @@ -23,10 +23,19 @@ jest.mock('./fs'); import { resolve } from 'path'; +import { ToolingLogCollectingWriter } from '@kbn/dev-utils'; + import { absolutePathSnapshotSerializer, stripAnsiSnapshotSerializer } from '../test_helpers'; import { linkProjectExecutables } from './link_project_executables'; import { Project } from './project'; import { buildProjectGraph } from './projects'; +import { log } from './log'; + +const logWriter = new ToolingLogCollectingWriter(); +log.setWriters([logWriter]); +beforeEach(() => { + logWriter.messages.length = 0; +}); const projectsByName = new Map([ [ @@ -101,12 +110,15 @@ describe('bin script points to a file', () => { const fs = require('./fs'); fs.isFile.mockReturnValue(true); - const logMock = jest.spyOn(console, 'log').mockImplementation(() => { - // noop - }); await linkProjectExecutables(projectsByName, projectGraph); expect(getFsMockCalls()).toMatchSnapshot('fs module calls'); - expect(logMock.mock.calls).toMatchSnapshot('logs'); + expect(logWriter.messages).toMatchInlineSnapshot(` + Array [ + " debg Linking package executables", + " debg [foo] bar -> ../bar/bin/bar.js", + " debg [baz] bar -> ../bar/bin/bar.js", + ] + `); }); }); diff --git a/packages/kbn-pm/src/utils/link_project_executables.ts b/packages/kbn-pm/src/utils/link_project_executables.ts index b403dfb2ecf2e..f7362788b417d 100644 --- a/packages/kbn-pm/src/utils/link_project_executables.ts +++ b/packages/kbn-pm/src/utils/link_project_executables.ts @@ -19,8 +19,6 @@ import { dirname, relative, resolve, sep } from 'path'; -import chalk from 'chalk'; - import { chmod, createSymlink, isFile, mkdirp } from './fs'; import { log } from './log'; import { ProjectGraph, ProjectMap } from './projects'; @@ -37,6 +35,7 @@ export async function linkProjectExecutables( projectsByName: ProjectMap, projectGraph: ProjectGraph ) { + log.debug(`Linking package executables`); for (const [projectName, projectDeps] of projectGraph) { const project = projectsByName.get(projectName)!; const binsDir = resolve(project.nodeModulesLocation, '.bin'); @@ -57,7 +56,7 @@ export async function linkProjectExecutables( // Get relative project path with normalized path separators. const projectRelativePath = relative(project.path, srcPath).split(sep).join('/'); - log.write(chalk`{dim [${project.name}]} ${name} -> {dim ${projectRelativePath}}`); + log.debug(`[${project.name}] ${name} -> ${projectRelativePath}`); await mkdirp(dirname(dest)); await createSymlink(srcPath, dest, 'exec'); diff --git a/packages/kbn-pm/src/utils/log.ts b/packages/kbn-pm/src/utils/log.ts index 9e5630be5bd19..786ff8b19ef4e 100644 --- a/packages/kbn-pm/src/utils/log.ts +++ b/packages/kbn-pm/src/utils/log.ts @@ -17,27 +17,36 @@ * under the License. */ -import { ToolingLog, ToolingLogCollectingWriter } from '@kbn/dev-utils'; +import { + ToolingLog, + ToolingLogTextWriter, + LogLevel, + parseLogLevel, + ParsedLogLevel, +} from '@kbn/dev-utils'; class Log extends ToolingLog { - testWriter?: ToolingLogCollectingWriter; + private logLevel!: ParsedLogLevel; constructor() { - super({ - level: 'info', - writeTo: process.stdout, - }); + super(); + this.setLogLevel('info'); } - /** - * Log something to the console. Ideally we would use a real logger in - * kbn-pm, but that's a pretty big change for now. - * @param ...args - */ - write(...args: any[]) { - // eslint-disable-next-line no-console - console.log(...args); + setLogLevel(level: LogLevel) { + this.logLevel = parseLogLevel(level); + this.setWriters([ + new ToolingLogTextWriter({ + level: this.logLevel.name, + writeTo: process.stdout, + }), + ]); + } + + wouldLogLevel(level: LogLevel) { + return this.logLevel.flags[level]; } } export const log = new Log(); +export { LogLevel, Log }; diff --git a/packages/kbn-pm/src/utils/project.ts b/packages/kbn-pm/src/utils/project.ts index 91a3a5365b60e..8f45df52c7a2f 100644 --- a/packages/kbn-pm/src/utils/project.ts +++ b/packages/kbn-pm/src/utils/project.ts @@ -17,7 +17,6 @@ * under the License. */ -import chalk from 'chalk'; import fs from 'fs'; import Path from 'path'; import { inspect } from 'util'; @@ -190,16 +189,20 @@ export class Project { } public async runScript(scriptName: string, args: string[] = []) { - log.write( - chalk.bold( - `\n\nRunning script [${chalk.green(scriptName)}] in [${chalk.green(this.name)}]:\n` - ) - ); + log.info(`Running script [${scriptName}] in [${this.name}]:`); return runScriptInPackage(scriptName, args, this); } - public runScriptStreaming(scriptName: string, args: string[] = []) { - return runScriptInPackageStreaming(scriptName, args, this); + public runScriptStreaming( + scriptName: string, + options: { args?: string[]; debug?: boolean } = {} + ) { + return runScriptInPackageStreaming({ + script: scriptName, + args: options.args || [], + pkg: this, + debug: options.debug, + }); } public hasDependencies() { @@ -207,8 +210,12 @@ export class Project { } public async installDependencies({ extraArgs }: { extraArgs: string[] }) { - log.write(chalk.bold(`\n\nInstalling dependencies in [${chalk.green(this.name)}]:\n`)); + log.info(`[${this.name}] running yarn`); + + log.write(''); await installInDir(this.path, extraArgs); + log.write(''); + await this.removeExtraneousNodeModules(); } @@ -239,7 +246,7 @@ export class Project { const isDevDependency = devDependencies && devDependencies.hasOwnProperty(name); if (!isDependency && !isDevDependency && fs.existsSync(nodeModulesPath)) { - log.write(`No dependency on ${name}, removing link in node_modules`); + log.debug(`No dependency on ${name}, removing link in node_modules`); fs.unlinkSync(nodeModulesPath); } }); diff --git a/packages/kbn-pm/src/utils/project_checksums.ts b/packages/kbn-pm/src/utils/project_checksums.ts index 46dde1b32c158..839c44f4f18c4 100644 --- a/packages/kbn-pm/src/utils/project_checksums.ts +++ b/packages/kbn-pm/src/utils/project_checksums.ts @@ -23,12 +23,12 @@ import Crypto from 'crypto'; import { promisify } from 'util'; import execa from 'execa'; -import { ToolingLog } from '@kbn/dev-utils'; import { readYarnLock, YarnLock } from './yarn_lock'; import { ProjectMap } from '../utils/projects'; import { Project } from '../utils/project'; import { Kibana } from '../utils/kibana'; +import { Log } from '../utils/log'; export type ChecksumMap = Map; /** map of [repo relative path to changed file, type of change] */ @@ -38,7 +38,7 @@ const statAsync = promisify(Fs.stat); const projectBySpecificitySorter = (a: Project, b: Project) => b.path.length - a.path.length; /** Get the changed files for a set of projects */ -async function getChangesForProjects(projects: ProjectMap, kbn: Kibana, log: ToolingLog) { +async function getChangesForProjects(projects: ProjectMap, kbn: Kibana, log: Log) { log.verbose('getting changed files'); const { stdout } = await execa( @@ -150,7 +150,7 @@ async function getLatestSha(project: Project, kbn: Kibana) { * in the yarn.lock file, does not include other projects in the workspace * or their dependencies */ -function resolveDepsForProject(project: Project, yarnLock: YarnLock, kbn: Kibana, log: ToolingLog) { +function resolveDepsForProject(project: Project, yarnLock: YarnLock, kbn: Kibana, log: Log) { /** map of [name@range, name@resolved] */ const resolved = new Map(); @@ -198,7 +198,7 @@ async function getChecksum( changes: Changes | undefined, yarnLock: YarnLock, kbn: Kibana, - log: ToolingLog + log: Log ) { const sha = await getLatestSha(project, kbn); if (sha) { @@ -256,7 +256,7 @@ async function getChecksum( * - un-committed changes * - resolved dependencies from yarn.lock referenced by project package.json */ -export async function getAllChecksums(kbn: Kibana, log: ToolingLog) { +export async function getAllChecksums(kbn: Kibana, log: Log) { const projects = kbn.getAllProjects(); const changesByProject = await getChangesForProjects(projects, kbn, log); const yarnLock = await readYarnLock(kbn); diff --git a/packages/kbn-pm/src/utils/scripts.ts b/packages/kbn-pm/src/utils/scripts.ts index 009efa1285c0c..728ac4287b1ce 100644 --- a/packages/kbn-pm/src/utils/scripts.ts +++ b/packages/kbn-pm/src/utils/scripts.ts @@ -56,13 +56,24 @@ export async function runScriptInPackage(script: string, args: string[], pkg: Pr /** * Run script in the given directory */ -export function runScriptInPackageStreaming(script: string, args: string[], pkg: Project) { +export function runScriptInPackageStreaming({ + script, + args, + pkg, + debug, +}: { + script: string; + args: string[]; + pkg: Project; + debug?: boolean; +}) { const execOpts = { cwd: pkg.path, }; return spawnStreaming('yarn', ['run', script, ...args], execOpts, { prefix: pkg.name, + debug, }); } diff --git a/packages/kbn-test/package.json b/packages/kbn-test/package.json index 0ab0048619358..8e2fd1c9182ff 100644 --- a/packages/kbn-test/package.json +++ b/packages/kbn-test/package.json @@ -14,6 +14,7 @@ "@kbn/babel-preset": "1.0.0", "@kbn/dev-utils": "1.0.0", "@types/parse-link-header": "^1.0.0", + "@types/puppeteer": "^3.0.0", "@types/strip-ansi": "^5.2.1", "@types/xml2js": "^0.4.5", "diff": "^4.0.1" @@ -25,6 +26,7 @@ "getopts": "^2.2.4", "glob": "^7.1.2", "parse-link-header": "^1.0.1", + "puppeteer": "^3.3.0", "strip-ansi": "^5.2.0", "rxjs": "^6.5.3", "tar-fs": "^1.16.3", diff --git a/packages/kbn-test/src/index.ts b/packages/kbn-test/src/index.ts index 585ce8181df5f..0bc7cc664df68 100644 --- a/packages/kbn-test/src/index.ts +++ b/packages/kbn-test/src/index.ts @@ -58,3 +58,5 @@ export { runFailedTestsReporterCli } from './failed_tests_reporter'; export { makeJunitReportPath } from './junit_report_path'; export { CI_PARALLEL_PROCESS_PREFIX } from './ci_parallel_process_prefix'; + +export * from './page_load_metrics'; diff --git a/packages/kbn-test/src/page_load_metrics/capture_page_load_metrics.ts b/packages/kbn-test/src/page_load_metrics/capture_page_load_metrics.ts new file mode 100644 index 0000000000000..013d49a29a51c --- /dev/null +++ b/packages/kbn-test/src/page_load_metrics/capture_page_load_metrics.ts @@ -0,0 +1,81 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { ToolingLog } from '@kbn/dev-utils'; +import { NavigationOptions, createUrl, navigateToApps } from './navigation'; + +export async function capturePageLoadMetrics(log: ToolingLog, options: NavigationOptions) { + const responsesByPageView = await navigateToApps(log, options); + + const assetSizeMeasurements = new Map(); + + const numberOfPagesVisited = responsesByPageView.size; + + for (const [, frameResponses] of responsesByPageView) { + for (const [, { url, dataLength }] of frameResponses) { + if (url.length === 0) { + throw new Error('navigateToApps(); failed to identify the url of the request'); + } + if (assetSizeMeasurements.has(url)) { + assetSizeMeasurements.set(url, [dataLength].concat(assetSizeMeasurements.get(url) || [])); + } else { + assetSizeMeasurements.set(url, [dataLength]); + } + } + } + + return Array.from(assetSizeMeasurements.entries()) + .map(([url, measurements]) => { + const baseUrl = createUrl('/', options.appConfig.url); + const relativeUrl = url + // remove the baseUrl (expect the trailing slash) to make url relative + .replace(baseUrl.slice(0, -1), '') + // strip the build number from asset urls + .replace(/^\/\d+\//, '/'); + return [relativeUrl, measurements] as const; + }) + .filter(([url, measurements]) => { + if (measurements.length !== numberOfPagesVisited) { + // ignore urls seen only on some pages + return false; + } + + if (url.startsWith('data:')) { + // ignore data urls since they are already counted by other assets + return false; + } + + if (url.startsWith('/api/') || url.startsWith('/internal/')) { + // ignore api requests since they don't have deterministic sizes + return false; + } + + const allMetricsAreEqual = measurements.every((x, i) => + i === 0 ? true : x === measurements[i - 1] + ); + if (!allMetricsAreEqual) { + throw new Error(`measurements for url [${url}] are not equal [${measurements.join(',')}]`); + } + + return true; + }) + .map(([url, measurements]) => { + return { group: 'page load asset size', id: url, value: measurements[0] }; + }); +} diff --git a/packages/kbn-test/src/page_load_metrics/cli.ts b/packages/kbn-test/src/page_load_metrics/cli.ts new file mode 100644 index 0000000000000..95421384c79cb --- /dev/null +++ b/packages/kbn-test/src/page_load_metrics/cli.ts @@ -0,0 +1,90 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Url from 'url'; + +import { run, createFlagError } from '@kbn/dev-utils'; +import { resolve, basename } from 'path'; +import { capturePageLoadMetrics } from './capture_page_load_metrics'; + +const defaultScreenshotsDir = resolve(__dirname, 'screenshots'); + +export function runPageLoadMetricsCli() { + run( + async ({ flags, log }) => { + const kibanaUrl = flags['kibana-url']; + if (!kibanaUrl || typeof kibanaUrl !== 'string') { + throw createFlagError('Expect --kibana-url to be a string'); + } + + const parsedUrl = Url.parse(kibanaUrl); + + const [username, password] = parsedUrl.auth + ? parsedUrl.auth.split(':') + : [flags.username, flags.password]; + + if (typeof username !== 'string' || typeof password !== 'string') { + throw createFlagError( + 'Mising username and/or password, either specify in --kibana-url or pass --username and --password' + ); + } + + const headless = !flags.head; + + const screenshotsDir = flags.screenshotsDir || defaultScreenshotsDir; + + if (typeof screenshotsDir !== 'string' || screenshotsDir === basename(screenshotsDir)) { + throw createFlagError('Expect screenshotsDir to be valid path string'); + } + + const metrics = await capturePageLoadMetrics(log, { + headless, + appConfig: { + url: kibanaUrl, + username, + password, + }, + screenshotsDir, + }); + for (const metric of metrics) { + log.info(`${metric.id}: ${metric.value}`); + } + }, + { + description: `Loads several pages with Puppeteer to capture the size of assets`, + flags: { + string: ['kibana-url', 'username', 'password', 'screenshotsDir'], + boolean: ['head'], + default: { + username: 'elastic', + password: 'changeme', + debug: true, + screenshotsDir: defaultScreenshotsDir, + }, + help: ` + --kibana-url Url for Kibana we should connect to, can include login info + --head Run puppeteer with graphical user interface + --username Set username, defaults to 'elastic' + --password Set password, defaults to 'changeme' + --screenshotsDir Set screenshots directory, defaults to '${defaultScreenshotsDir}' + `, + }, + } + ); +} diff --git a/packages/kbn-test/src/page_load_metrics/event.ts b/packages/kbn-test/src/page_load_metrics/event.ts new file mode 100644 index 0000000000000..481954bbf672e --- /dev/null +++ b/packages/kbn-test/src/page_load_metrics/event.ts @@ -0,0 +1,34 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export interface ResponseReceivedEvent { + frameId: string; + loaderId: string; + requestId: string; + response: Record; + timestamp: number; + type: string; +} + +export interface DataReceivedEvent { + encodedDataLength: number; + dataLength: number; + requestId: string; + timestamp: number; +} diff --git a/packages/kbn-test/src/page_load_metrics/index.ts b/packages/kbn-test/src/page_load_metrics/index.ts new file mode 100644 index 0000000000000..4309d558518a6 --- /dev/null +++ b/packages/kbn-test/src/page_load_metrics/index.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './cli'; +export { capturePageLoadMetrics } from './capture_page_load_metrics'; diff --git a/packages/kbn-test/src/page_load_metrics/navigation.ts b/packages/kbn-test/src/page_load_metrics/navigation.ts new file mode 100644 index 0000000000000..21dc681951b21 --- /dev/null +++ b/packages/kbn-test/src/page_load_metrics/navigation.ts @@ -0,0 +1,165 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Fs from 'fs'; +import Url from 'url'; +import _ from 'lodash'; +import puppeteer from 'puppeteer'; +import { resolve } from 'path'; +import { ToolingLog } from '@kbn/dev-utils'; +import { ResponseReceivedEvent, DataReceivedEvent } from './event'; + +export interface NavigationOptions { + headless: boolean; + appConfig: { url: string; username: string; password: string }; + screenshotsDir: string; +} + +export type NavigationResults = Map>; + +interface FrameResponse { + url: string; + dataLength: number; +} + +function joinPath(pathA: string, pathB: string) { + return `${pathA.endsWith('/') ? pathA.slice(0, -1) : pathA}/${ + pathB.startsWith('/') ? pathB.slice(1) : pathB + }`; +} + +export function createUrl(path: string, url: string) { + const baseUrl = Url.parse(url); + return Url.format({ + protocol: baseUrl.protocol, + hostname: baseUrl.hostname, + port: baseUrl.port, + pathname: joinPath(baseUrl.pathname || '', path), + }); +} + +async function loginToKibana( + log: ToolingLog, + browser: puppeteer.Browser, + options: NavigationOptions +) { + log.debug(`log in to the app..`); + const page = await browser.newPage(); + const loginUrl = createUrl('/login', options.appConfig.url); + await page.goto(loginUrl, { + waitUntil: 'networkidle0', + }); + await page.type('[data-test-subj="loginUsername"]', options.appConfig.username); + await page.type('[data-test-subj="loginPassword"]', options.appConfig.password); + await page.click('[data-test-subj="loginSubmit"]'); + await page.waitForNavigation({ waitUntil: 'networkidle0' }); + await page.close(); +} + +export async function navigateToApps(log: ToolingLog, options: NavigationOptions) { + const browser = await puppeteer.launch({ headless: options.headless, args: ['--no-sandbox'] }); + const devToolsResponses: NavigationResults = new Map(); + const apps = [ + { path: '/app/discover', locator: '[data-test-subj="discover-sidebar"]' }, + { path: '/app/home', locator: '[data-test-subj="homeApp"]' }, + { path: '/app/canvas', locator: '[data-test-subj="create-workpad-button"]' }, + { path: '/app/maps', locator: '[title="Maps"]' }, + { path: '/app/apm', locator: '[data-test-subj="apmMainContainer"]' }, + ]; + + await loginToKibana(log, browser, options); + + await Promise.all( + apps.map(async (app) => { + const page = await browser.newPage(); + page.setCacheEnabled(false); + page.setDefaultNavigationTimeout(0); + const frameResponses = new Map(); + devToolsResponses.set(app.path, frameResponses); + + const client = await page.target().createCDPSession(); + await client.send('Network.enable'); + + function getRequestData(requestId: string) { + if (!frameResponses.has(requestId)) { + frameResponses.set(requestId, { url: '', dataLength: 0 }); + } + + return frameResponses.get(requestId)!; + } + + client.on('Network.responseReceived', (event: ResponseReceivedEvent) => { + getRequestData(event.requestId).url = event.response.url; + }); + + client.on('Network.dataReceived', (event: DataReceivedEvent) => { + getRequestData(event.requestId).dataLength += event.dataLength; + }); + + const url = createUrl(app.path, options.appConfig.url); + log.debug(`goto ${url}`); + await page.goto(url, { + waitUntil: 'networkidle0', + }); + + let readyAttempt = 0; + let selectorFound = false; + while (!selectorFound) { + readyAttempt += 1; + try { + await page.waitForSelector(app.locator, { timeout: 5000 }); + selectorFound = true; + } catch (error) { + log.error( + `Page '${app.path}' was not loaded properly, unable to find '${ + app.locator + }', url: ${page.url()}` + ); + + if (readyAttempt < 6) { + continue; + } + + const failureDir = resolve(options.screenshotsDir, 'failure'); + const screenshotPath = resolve( + failureDir, + `${app.path.slice(1).split('/').join('_')}_navigation.png` + ); + Fs.mkdirSync(failureDir, { recursive: true }); + + await page.bringToFront(); + await page.screenshot({ + path: screenshotPath, + type: 'png', + fullPage: true, + }); + log.debug(`Saving screenshot to ${screenshotPath}`); + + throw new Error(`Page load timeout: ${app.path} not loaded after 30 seconds`); + } + } + + await page.close(); + }) + ); + + await browser.close(); + + return devToolsResponses; +} diff --git a/packages/kbn-ui-shared-deps/entry.js b/packages/kbn-ui-shared-deps/entry.js index ab044a6723da7..88e84fc87ae53 100644 --- a/packages/kbn-ui-shared-deps/entry.js +++ b/packages/kbn-ui-shared-deps/entry.js @@ -30,8 +30,8 @@ export const KbnI18nReact = require('@kbn/i18n/react'); export const Angular = require('angular'); export const Moment = require('moment'); export const MomentTimezone = require('moment-timezone/moment-timezone'); -export const Monaco = require('./monaco.ts'); -export const MonacoBare = require('monaco-editor/esm/vs/editor/editor.api'); +export const KbnMonaco = require('@kbn/monaco'); +export const MonacoBarePluginApi = require('@kbn/monaco').BarePluginApi; export const React = require('react'); export const ReactDom = require('react-dom'); export const ReactDomServer = require('react-dom/server'); diff --git a/packages/kbn-ui-shared-deps/index.js b/packages/kbn-ui-shared-deps/index.js index eb3add68e2866..301d176555847 100644 --- a/packages/kbn-ui-shared-deps/index.js +++ b/packages/kbn-ui-shared-deps/index.js @@ -42,9 +42,9 @@ exports.externals = { 'react-intl': '__kbnSharedDeps__.ReactIntl', 'react-router': '__kbnSharedDeps__.ReactRouter', 'react-router-dom': '__kbnSharedDeps__.ReactRouterDom', - '@kbn/ui-shared-deps/monaco': '__kbnSharedDeps__.Monaco', + '@kbn/monaco': '__kbnSharedDeps__.KbnMonaco', // this is how plugins/consumers from npm load monaco - 'monaco-editor/esm/vs/editor/editor.api': '__kbnSharedDeps__.MonacoBare', + 'monaco-editor/esm/vs/editor/editor.api': '__kbnSharedDeps__.MonacoBarePluginApi', /** * big deps which are locked to a single version diff --git a/packages/kbn-ui-shared-deps/package.json b/packages/kbn-ui-shared-deps/package.json index 93afa303c8cad..744a656c54a7f 100644 --- a/packages/kbn-ui-shared-deps/package.json +++ b/packages/kbn-ui-shared-deps/package.json @@ -13,6 +13,7 @@ "@elastic/eui": "23.3.1", "@elastic/numeral": "^2.5.0", "@kbn/i18n": "1.0.0", + "@kbn/monaco": "1.0.0", "abortcontroller-polyfill": "^1.4.0", "angular": "^1.7.9", "compression-webpack-plugin": "^3.1.0", @@ -22,7 +23,6 @@ "jquery": "^3.5.0", "moment": "^2.24.0", "moment-timezone": "^0.5.27", - "monaco-editor": "~0.17.0", "react": "^16.12.0", "react-dom": "^16.12.0", "react-intl": "^2.8.0", diff --git a/packages/kbn-ui-shared-deps/tsconfig.json b/packages/kbn-ui-shared-deps/tsconfig.json index 5d981c73f1d21..5aa0f45e4100d 100644 --- a/packages/kbn-ui-shared-deps/tsconfig.json +++ b/packages/kbn-ui-shared-deps/tsconfig.json @@ -1,7 +1,4 @@ { "extends": "../../tsconfig.json", - "include": [ - "index.d.ts", - "monaco.ts" - ] + "include": ["index.d.ts", "./monaco"] } diff --git a/packages/kbn-ui-shared-deps/webpack.config.js b/packages/kbn-ui-shared-deps/webpack.config.js index 7295f2e88c530..523927bd64a20 100644 --- a/packages/kbn-ui-shared-deps/webpack.config.js +++ b/packages/kbn-ui-shared-deps/webpack.config.js @@ -78,17 +78,6 @@ exports.getWebpackConfig = ({ dev = false } = {}) => ({ test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'], }, - { - include: [require.resolve('./monaco.ts')], - use: [ - { - loader: 'babel-loader', - options: { - presets: [require.resolve('@kbn/babel-preset/webpack_preset')], - }, - }, - ], - }, ], }, @@ -96,6 +85,7 @@ exports.getWebpackConfig = ({ dev = false } = {}) => ({ alias: { moment: MOMENT_SRC, }, + extensions: ['.js', '.ts'], }, optimization: { diff --git a/renovate.json5 b/renovate.json5 index 674c4e0df7904..b4f1441a50d60 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -418,14 +418,6 @@ '@types/history', ], }, - { - groupSlug: 'indent-string', - groupName: 'indent-string related packages', - packageNames: [ - 'indent-string', - '@types/indent-string', - ], - }, { groupSlug: 'inquirer', groupName: 'inquirer related packages', @@ -1067,14 +1059,6 @@ '@types/chokidar', ], }, - { - groupSlug: 'wrap-ansi', - groupName: 'wrap-ansi related packages', - packageNames: [ - 'wrap-ansi', - '@types/wrap-ansi', - ], - }, { groupSlug: 'write-pkg', groupName: 'write-pkg related packages', diff --git a/rfcs/text/0011_global_search.md b/rfcs/text/0011_global_search.md index 5ec368a1c2f02..3b2120283d06a 100644 --- a/rfcs/text/0011_global_search.md +++ b/rfcs/text/0011_global_search.md @@ -194,7 +194,7 @@ Notes: ### Plugin API -#### server API +#### Common types ```ts /** @@ -208,6 +208,21 @@ type GlobalSearchResult = Omit & { url: string; }; + +/** + * Response returned from the {@link GlobalSearchServiceStart | global search service}'s `find` API + */ +type GlobalSearchBatchedResults = { + /** + * Results for this batch + */ + results: GlobalSearchResult[]; +}; +``` + +#### server API + +```ts /** * Options for the server-side {@link GlobalSearchServiceStart.find | find API} */ @@ -226,16 +241,6 @@ interface GlobalSearchFindOptions { aborted$?: Observable; } -/** - * Response returned from the server-side {@link GlobalSearchServiceStart | global search service}'s `find` API - */ -type GlobalSearchBatchedResults = { - /** - * Results for this batch - */ - results: GlobalSearchResult[]; -}; - /** @public */ interface GlobalSearchPluginSetup { registerResultProvider(provider: GlobalSearchResultProvider); @@ -265,28 +270,6 @@ interface GlobalSearchFindOptions { aborted$?: Observable; } -/** - * Enhanced {@link GlobalSearchResult | result type} for the client-side, - * to allow navigating to a given result. - */ -interface NavigableGlobalSearchResult extends GlobalSearchResult { - /** - * Navigate to this result's associated url. If the result is on this kibana instance, user will be redirected to it - * in a SPA friendly way using `application.navigateToApp`, else, a full page refresh will be performed. - */ - navigate: () => Promise; -} - -/** - * Response returned from the client-side {@link GlobalSearchServiceStart | global search service}'s `find` API - */ -type GlobalSearchBatchedResults = { - /** - * Results for this batch - */ - results: NavigableGlobalSearchResult[]; -}; - /** @public */ interface GlobalSearchPluginSetup { registerResultProvider(provider: GlobalSearchResultProvider); @@ -304,9 +287,6 @@ Notes: - The `registerResultProvider` setup APIs share the same signature, however the input `GlobalSearchResultProvider` types are different on the client and server. - The `find` start API signature got a `KibanaRequest` for `server`, when this parameter is not present for `public`. -- The `find` API returns a observable of `NavigableGlobalSearchResult` instead of plain `GlobalSearchResult`. This type - is here to enhance results with a `navigate` method to let the `GlobalSearch` plugin handle the navigation logic, which is - non-trivial. See the [Redirecting to a result](#redirecting-to-a-result) section for more info. #### http API @@ -395,14 +375,11 @@ In current specification, the only conversion step is to transform the `result.u #### redirecting to a result -Parsing a relative or absolute result url to perform SPA navigation can be non trivial, and should remains the responsibility -of the GlobalSearch plugin API. - -This is why `NavigableGlobalSearchResult.navigate` has been introduced on the client-side version of the `find` API +Parsing a relative or absolute result url to perform SPA navigation can be non trivial. This is why `ApplicationService.navigateToUrl` has been introduced on the client-side core API -When using `navigate` from a result instance, the following logic will be executed: +When using `navigateToUrl` with the url of a result instance, the following logic will be executed: -If all these criteria are true for `result.url`: +If all these criteria are true for `url`: - (only for absolute URLs) The origin of the URL matches the origin of the browser's current location - The pathname of the URL starts with the current basePath (eg. /mybasepath/s/my-space) diff --git a/scripts/page_load_metrics.js b/scripts/page_load_metrics.js new file mode 100644 index 0000000000000..37500c26e0b20 --- /dev/null +++ b/scripts/page_load_metrics.js @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +require('../src/setup_node_env'); +require('@kbn/test').runPageLoadMetricsCli(); diff --git a/src/cli/cluster/cluster_manager.ts b/src/cli/cluster/cluster_manager.ts index dec16b63d78f0..09f9bb2333dbe 100644 --- a/src/cli/cluster/cluster_manager.ts +++ b/src/cli/cluster/cluster_manager.ts @@ -262,7 +262,7 @@ export class ClusterManager { ...pluginInternalDirsIgnore, fromRoot('src/legacy/server/sass/__tmp__'), fromRoot('x-pack/plugins/reporting/.chromium'), - fromRoot('x-pack/plugins/siem/cypress'), + fromRoot('x-pack/plugins/security_solution/cypress'), fromRoot('x-pack/plugins/apm/e2e'), fromRoot('x-pack/plugins/apm/scripts'), fromRoot('x-pack/plugins/canvas/canvas_plugin_src'), // prevents server from restarting twice for Canvas plugin changes, diff --git a/src/core/public/application/application_service.mock.ts b/src/core/public/application/application_service.mock.ts index 300b09e17d15d..47a8a01d917eb 100644 --- a/src/core/public/application/application_service.mock.ts +++ b/src/core/public/application/application_service.mock.ts @@ -17,6 +17,7 @@ * under the License. */ +import { History } from 'history'; import { BehaviorSubject, Subject } from 'rxjs'; import { capabilitiesServiceMock } from './capabilities/capabilities_service.mock'; @@ -57,6 +58,28 @@ const createStartContractMock = (): jest.Mocked => { }; }; +const createHistoryMock = (): jest.Mocked => { + return { + block: jest.fn(), + createHref: jest.fn(), + go: jest.fn(), + goBack: jest.fn(), + goForward: jest.fn(), + listen: jest.fn(), + push: jest.fn(), + replace: jest.fn(), + action: 'PUSH', + length: 1, + location: { + pathname: '/', + search: '', + hash: '', + key: '', + state: undefined, + }, + }; +}; + const createInternalStartContractMock = (): jest.Mocked => { const currentAppId$ = new Subject(); @@ -69,6 +92,7 @@ const createInternalStartContractMock = (): jest.Mocked currentAppId$.next(appId)), navigateToUrl: jest.fn(), registerMountContext: jest.fn(), + history: createHistoryMock(), }; }; diff --git a/src/core/public/application/application_service.tsx b/src/core/public/application/application_service.tsx index 2224f72e2bd91..850422a61bde7 100644 --- a/src/core/public/application/application_service.tsx +++ b/src/core/public/application/application_service.tsx @@ -301,6 +301,7 @@ export class ApplicationService { distinctUntilChanged(), takeUntil(this.stop$) ), + history: this.history, registerMountContext: this.mountContext.registerContext, getUrlForApp: ( appId, diff --git a/src/core/public/application/index.ts b/src/core/public/application/index.ts index d51a4c0d69d42..74356cbd88b34 100644 --- a/src/core/public/application/index.ts +++ b/src/core/public/application/index.ts @@ -43,5 +43,6 @@ export { PublicAppInfo, PublicLegacyAppInfo, // Internal types + InternalApplicationSetup, InternalApplicationStart, } from './types'; diff --git a/src/core/public/application/types.ts b/src/core/public/application/types.ts index 8006ec846138f..7c83c684ac73d 100644 --- a/src/core/public/application/types.ts +++ b/src/core/public/application/types.ts @@ -18,6 +18,7 @@ */ import { Observable } from 'rxjs'; +import { History } from 'history'; import { Capabilities } from './capabilities'; import { ChromeStart } from '../chrome'; @@ -766,6 +767,12 @@ export interface InternalApplicationStart extends Omit | undefined; } /** @internal */ diff --git a/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap b/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap index b563c6d2a4ec4..305a4b2ed5b30 100644 --- a/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap +++ b/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap @@ -42,6 +42,25 @@ exports[`Header renders 1`] = ` }, "getComponent": [MockFunction], "getUrlForApp": [MockFunction], + "history": Object { + "action": "PUSH", + "block": [MockFunction], + "createHref": [MockFunction], + "go": [MockFunction], + "goBack": [MockFunction], + "goForward": [MockFunction], + "length": 1, + "listen": [MockFunction], + "location": Object { + "hash": "", + "key": "", + "pathname": "/", + "search": "", + "state": undefined, + }, + "push": [MockFunction], + "replace": [MockFunction], + }, "navigateToApp": [MockFunction], "navigateToUrl": [MockFunction], "registerMountContext": [MockFunction], @@ -657,6 +676,25 @@ exports[`Header renders 2`] = ` }, "getComponent": [MockFunction], "getUrlForApp": [MockFunction], + "history": Object { + "action": "PUSH", + "block": [MockFunction], + "createHref": [MockFunction], + "go": [MockFunction], + "goBack": [MockFunction], + "goForward": [MockFunction], + "length": 1, + "listen": [MockFunction], + "location": Object { + "hash": "", + "key": "", + "pathname": "/", + "search": "", + "state": undefined, + }, + "push": [MockFunction], + "replace": [MockFunction], + }, "navigateToApp": [MockFunction], "navigateToUrl": [MockFunction], "registerMountContext": [MockFunction], @@ -4741,6 +4779,25 @@ exports[`Header renders 3`] = ` }, "getComponent": [MockFunction], "getUrlForApp": [MockFunction], + "history": Object { + "action": "PUSH", + "block": [MockFunction], + "createHref": [MockFunction], + "go": [MockFunction], + "goBack": [MockFunction], + "goForward": [MockFunction], + "length": 1, + "listen": [MockFunction], + "location": Object { + "hash": "", + "key": "", + "pathname": "/", + "search": "", + "state": undefined, + }, + "push": [MockFunction], + "replace": [MockFunction], + }, "navigateToApp": [MockFunction], "navigateToUrl": [MockFunction], "registerMountContext": [MockFunction], @@ -9897,6 +9954,25 @@ exports[`Header renders 4`] = ` }, "getComponent": [MockFunction], "getUrlForApp": [MockFunction], + "history": Object { + "action": "PUSH", + "block": [MockFunction], + "createHref": [MockFunction], + "go": [MockFunction], + "goBack": [MockFunction], + "goForward": [MockFunction], + "length": 1, + "listen": [MockFunction], + "location": Object { + "hash": "", + "key": "", + "pathname": "/", + "search": "", + "state": undefined, + }, + "push": [MockFunction], + "replace": [MockFunction], + }, "navigateToApp": [MockFunction], "navigateToUrl": [MockFunction], "registerMountContext": [MockFunction], diff --git a/src/core/public/core_app/core_app.mock.ts b/src/core/public/core_app/core_app.mock.ts new file mode 100644 index 0000000000000..b0e3871a40bf5 --- /dev/null +++ b/src/core/public/core_app/core_app.mock.ts @@ -0,0 +1,31 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { CoreApp } from './core_app'; + +type CoreAppContract = PublicMethodsOf; +const createMock = (): jest.Mocked => ({ + setup: jest.fn(), + start: jest.fn(), + stop: jest.fn(), +}); + +export const coreAppMock = { + create: createMock, +}; diff --git a/src/core/public/core_app/core_app.ts b/src/core/public/core_app/core_app.ts new file mode 100644 index 0000000000000..04d58b7c3c65c --- /dev/null +++ b/src/core/public/core_app/core_app.ts @@ -0,0 +1,83 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { UnregisterCallback } from 'history'; +import { + InternalApplicationSetup, + InternalApplicationStart, + AppNavLinkStatus, + AppMountParameters, +} from '../application'; +import { HttpSetup, HttpStart } from '../http'; +import { CoreContext } from '../core_system'; +import { renderApp, setupUrlOverflowDetection } from './errors'; +import { NotificationsStart } from '../notifications'; +import { IUiSettingsClient } from '../ui_settings'; + +interface SetupDeps { + application: InternalApplicationSetup; + http: HttpSetup; +} + +interface StartDeps { + application: InternalApplicationStart; + http: HttpStart; + notifications: NotificationsStart; + uiSettings: IUiSettingsClient; +} + +export class CoreApp { + private stopHistoryListening?: UnregisterCallback; + + constructor(private readonly coreContext: CoreContext) {} + + public setup({ http, application }: SetupDeps) { + application.register(this.coreContext.coreId, { + id: 'error', + title: 'App Error', + navLinkStatus: AppNavLinkStatus.hidden, + mount(params: AppMountParameters) { + // Do not use an async import here in order to ensure that network failures + // cannot prevent the error UI from displaying. This UI is tiny so an async + // import here is probably not useful anyways. + return renderApp(params, { basePath: http.basePath }); + }, + }); + } + + public start({ application, http, notifications, uiSettings }: StartDeps) { + if (!application.history) { + return; + } + + this.stopHistoryListening = setupUrlOverflowDetection({ + basePath: http.basePath, + history: application.history, + toasts: notifications.toasts, + uiSettings, + }); + } + + public stop() { + if (this.stopHistoryListening) { + this.stopHistoryListening(); + this.stopHistoryListening = undefined; + } + } +} diff --git a/src/core/public/core_app/errors/error_application.test.ts b/src/core/public/core_app/errors/error_application.test.ts new file mode 100644 index 0000000000000..ec3992330008f --- /dev/null +++ b/src/core/public/core_app/errors/error_application.test.ts @@ -0,0 +1,61 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { act } from 'react-dom/test-utils'; +import { History, createMemoryHistory } from 'history'; +import { IBasePath } from '../../http'; +import { BasePath } from '../../http/base_path'; + +import { renderApp } from './error_application'; + +describe('renderApp', () => { + let basePath: IBasePath; + let element: HTMLDivElement; + let history: History; + let unmount: any; + + beforeEach(() => { + basePath = new BasePath(); + element = document.createElement('div'); + history = createMemoryHistory(); + unmount = renderApp({ element, history } as any, { basePath }); + }); + + afterEach(() => unmount()); + + it('renders generic errors', () => { + act(() => { + history.push('/app/error'); + }); + // innerText not working in jsdom, so use innerHTML + expect(element.querySelector('.euiTitle')!.innerHTML).toMatchInlineSnapshot( + `"Application error"` + ); + }); + + it('renders urlOverflow errors', () => { + act(() => { + history.push('/app/error?errorType=urlOverflow'); + }); + expect(element.querySelector('.euiTitle')!.innerHTML).toMatchInlineSnapshot( + `"The URL for this object is too long, and we can't display it"` + ); + expect(element.innerHTML).toMatch('Things to try'); + }); +}); diff --git a/src/core/public/core_app/errors/error_application.tsx b/src/core/public/core_app/errors/error_application.tsx new file mode 100644 index 0000000000000..7124776d7086a --- /dev/null +++ b/src/core/public/core_app/errors/error_application.tsx @@ -0,0 +1,102 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React, { ReactChild, useState, useLayoutEffect } from 'react'; +import ReactDOM from 'react-dom'; +import { History } from 'history'; +import { i18n } from '@kbn/i18n'; +import { I18nProvider } from '@kbn/i18n/react'; + +import { EuiEmptyPrompt, EuiPage, EuiPageBody, EuiPageContent } from '@elastic/eui'; +import { UrlOverflowUi } from './url_overflow_ui'; +import { IBasePath } from '../../http'; +import { AppMountParameters } from '../../application'; + +interface Props { + title?: string; + children?: ReactChild; +} + +const ErrorPage: React.FC = ({ title, children }) => { + title = + title ?? + i18n.translate('core.application.appRenderError.defaultTitle', { + defaultMessage: 'Application error', + }); + + return ( + + + + {title}} + body={children} + /> + + + + ); +}; + +const ErrorApp: React.FC<{ basePath: IBasePath; history: History }> = ({ basePath, history }) => { + const [currentLocation, setCurrentLocation] = useState(history.location); + useLayoutEffect(() => { + return history.listen((location) => setCurrentLocation(location)); + }, [history]); + + const searchParams = new URLSearchParams(currentLocation.search); + const errorType = searchParams.get('errorType'); + + if (errorType === 'urlOverflow') { + return ( + + + + ); + } + + return ; +}; + +interface Deps { + basePath: IBasePath; +} + +/** + * Renders UI for displaying error messages. + * @internal + */ +export const renderApp = ({ element, history }: AppMountParameters, { basePath }: Deps) => { + ReactDOM.render( + + + , + element + ); + + return () => { + ReactDOM.unmountComponentAtNode(element); + }; +}; diff --git a/src/core/public/core_app/errors/index.ts b/src/core/public/core_app/errors/index.ts new file mode 100644 index 0000000000000..a8da0d98b3962 --- /dev/null +++ b/src/core/public/core_app/errors/index.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { renderApp } from './error_application'; +export { setupUrlOverflowDetection, URL_MAX_LENGTH } from './url_overflow'; diff --git a/src/core/public/core_app/errors/url_overflow.test.ts b/src/core/public/core_app/errors/url_overflow.test.ts new file mode 100644 index 0000000000000..115bf53aa2a84 --- /dev/null +++ b/src/core/public/core_app/errors/url_overflow.test.ts @@ -0,0 +1,127 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { createMemoryHistory, History } from 'history'; + +import { BasePath } from '../../http/base_path'; +import { notificationServiceMock } from '../../notifications/notifications_service.mock'; +import { uiSettingsServiceMock } from '../../ui_settings/ui_settings_service.mock'; +import { IBasePath } from '../../http'; +import { IToasts } from '../../notifications'; +import { IUiSettingsClient } from '../../ui_settings'; + +import { setupUrlOverflowDetection, URL_MAX_LENGTH, URL_WARNING_LENGTH } from './url_overflow'; + +const longUrl = '/' + 'a'.repeat(URL_MAX_LENGTH); + +describe('url overflow detection', () => { + let basePath: IBasePath; + let history: History; + let toasts: jest.Mocked; + let uiSettings: jest.Mocked; + let assignSpy: jest.SpyInstance; + let unlisten: any; + + beforeEach(() => { + basePath = new BasePath('/test-123'); + history = createMemoryHistory(); + toasts = notificationServiceMock.createStartContract().toasts; + uiSettings = uiSettingsServiceMock.createStartContract(); + + // No-op mock impl to avoid jsdom warning about navigation not being implemented + assignSpy = jest.spyOn(window.location, 'assign').mockImplementation(() => {}); + + unlisten = setupUrlOverflowDetection({ + basePath, + history, + toasts, + uiSettings, + }); + }); + + afterEach(() => { + unlisten(); + assignSpy.mockRestore(); + }); + + it('redirects to error page when URL is too long', () => { + history.push(longUrl); + expect(assignSpy).toHaveBeenCalledWith('/app/error?errorType=urlOverflow'); + }); + + it('displays a toast if URL exceeds warning threshold', () => { + const warningUrl = '/' + 'a'.repeat(URL_WARNING_LENGTH); + history.push(warningUrl); + expect(history.location.pathname).toEqual(warningUrl); + expect(assignSpy).not.toHaveBeenCalled(); + expect(toasts.addWarning).toHaveBeenCalledWith( + expect.objectContaining({ + title: 'The URL is big and Kibana might stop working', + text: expect.any(Function), + }) + ); + + // Verify toast can be rendered correctly + const { text: mountToast } = toasts.addWarning.mock.calls[0][0] as any; + const element = document.createElement('div'); + const unmount = mountToast(element); + expect(element).toMatchInlineSnapshot(` +

+ Either enable the + + state:storeInSessionStorage + + option in + + advanced settings + + or simplify the onscreen visuals. +
+ `); + unmount(); + }); + + it('does not redirect or show warning if URL is not too long', () => { + history.push('/regular-length-url'); + expect(history.location.pathname).toEqual('/regular-length-url'); + expect(assignSpy).not.toHaveBeenCalled(); + expect(toasts.addWarning).not.toHaveBeenCalled(); + }); + + it('does not redirect or show warning if state:storeInSessionStorage is set', () => { + uiSettings.get.mockReturnValue(true); + history.push(longUrl); + expect(history.location.pathname).toEqual(longUrl); + expect(assignSpy).not.toHaveBeenCalled(); + expect(toasts.addWarning).not.toHaveBeenCalled(); + }); + + it('does not redirect or show warning if already on the error page', () => { + history.push('/app/error'); + const longQueryParam = 'a'.repeat(URL_MAX_LENGTH); + const longErrorUrl = `/app/error?q=${longQueryParam}`; + history.push(longErrorUrl); + expect(history.location.pathname).toEqual('/app/error'); + expect(history.location.search).toEqual(`?q=${longQueryParam}`); + expect(assignSpy).not.toHaveBeenCalled(); + expect(toasts.addWarning).not.toHaveBeenCalled(); + }); +}); diff --git a/src/core/public/core_app/errors/url_overflow.tsx b/src/core/public/core_app/errors/url_overflow.tsx new file mode 100644 index 0000000000000..da287a74d09ae --- /dev/null +++ b/src/core/public/core_app/errors/url_overflow.tsx @@ -0,0 +1,96 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { History, Location } from 'history'; + +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { mountReactNode } from '../../utils'; +import { IToasts } from '../../notifications'; +import { IBasePath } from '../../http'; +import { IUiSettingsClient } from '../../ui_settings'; + +const IE_REGEX = /(; ?MSIE |Edge\/\d|Trident\/[\d+\.]+;.*rv:*11\.\d+)/; +export const IS_IE = IE_REGEX.test(window.navigator.userAgent); +/** + * The max URL length allowed by the current browser. Should be used to display warnings to users when query parameters + * cause URL to exceed this limit. + * @public + */ +export const URL_MAX_LENGTH = IS_IE ? 2000 : 25000; +export const URL_WARNING_LENGTH = IS_IE ? 1000 : 24000; +const ERROR_ROUTE = '/app/error'; + +interface Deps { + basePath: IBasePath; + history: History; + toasts: IToasts; + uiSettings: IUiSettingsClient; +} + +export const setupUrlOverflowDetection = ({ basePath, history, toasts, uiSettings }: Deps) => + history.listen((location: Location) => { + // Bail if storeInSessionStorage is set or we're already on the error page + if ( + uiSettings.get('state:storeInSessionStorage') || + history.location.pathname.startsWith(ERROR_ROUTE) + ) { + return; + } + + const absUrl = history.createHref(location); + const absUrlLength = absUrl.length; + + if (absUrlLength > URL_MAX_LENGTH) { + const href = history.createHref({ + pathname: ERROR_ROUTE, + search: `errorType=urlOverflow`, + }); + // Force the browser to reload so that any potentially unstable state is unloaded + window.location.assign(href); + // window.location.href = href; + // window.location.reload(); + } else if (absUrlLength >= URL_WARNING_LENGTH) { + toasts.addWarning({ + title: i18n.translate('core.ui.errorUrlOverflow.bigUrlWarningNotificationTitle', { + defaultMessage: 'The URL is big and Kibana might stop working', + }), + text: mountReactNode( + state:storeInSessionStorage, + advancedSettingsLink: ( + + + + ), + }} + /> + ), + }); + } + }); diff --git a/src/core/public/core_app/errors/url_overflow_ui.tsx b/src/core/public/core_app/errors/url_overflow_ui.tsx new file mode 100644 index 0000000000000..30ee0f4ac41e5 --- /dev/null +++ b/src/core/public/core_app/errors/url_overflow_ui.tsx @@ -0,0 +1,73 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; + +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiText } from '@elastic/eui'; + +import { IBasePath } from '../../http'; +import { IS_IE } from './url_overflow'; + +export const UrlOverflowUi: React.FC<{ basePath: IBasePath }> = ({ basePath }) => { + return ( + +

+ +

+ +
    +
  • + state:storeInSessionStorage, + kibanaSettingsLink: ( + + + + ), + }} + /> +
  • +
  • + +
  • + {IS_IE && ( +
  • + +
  • + )} +
+
+ ); +}; diff --git a/src/core/public/core_app/index.ts b/src/core/public/core_app/index.ts new file mode 100644 index 0000000000000..9876be1575ffd --- /dev/null +++ b/src/core/public/core_app/index.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { CoreApp } from './core_app'; +export { URL_MAX_LENGTH } from './errors'; diff --git a/src/core/public/core_system.test.mocks.ts b/src/core/public/core_system.test.mocks.ts index 75ab6cdb628f7..b5b99418b44b4 100644 --- a/src/core/public/core_system.test.mocks.ts +++ b/src/core/public/core_system.test.mocks.ts @@ -32,6 +32,7 @@ import { docLinksServiceMock } from './doc_links/doc_links_service.mock'; import { renderingServiceMock } from './rendering/rendering_service.mock'; import { contextServiceMock } from './context/context_service.mock'; import { integrationsServiceMock } from './integrations/integrations_service.mock'; +import { coreAppMock } from './core_app/core_app.mock'; export const MockLegacyPlatformService = legacyPlatformServiceMock.create(); export const LegacyPlatformServiceConstructor = jest @@ -136,3 +137,9 @@ export const IntegrationsServiceConstructor = jest jest.doMock('./integrations', () => ({ IntegrationsService: IntegrationsServiceConstructor, })); + +export const MockCoreApp = coreAppMock.create(); +export const CoreAppConstructor = jest.fn().mockImplementation(() => MockCoreApp); +jest.doMock('./core_app', () => ({ + CoreApp: CoreAppConstructor, +})); diff --git a/src/core/public/core_system.test.ts b/src/core/public/core_system.test.ts index 2979dd7661e59..4c1993c90a2e1 100644 --- a/src/core/public/core_system.test.ts +++ b/src/core/public/core_system.test.ts @@ -44,6 +44,8 @@ import { MockContextService, IntegrationsServiceConstructor, MockIntegrationsService, + CoreAppConstructor, + MockCoreApp, } from './core_system.test.mocks'; import { CoreSystem } from './core_system'; @@ -88,6 +90,7 @@ describe('constructor', () => { expect(OverlayServiceConstructor).toHaveBeenCalledTimes(1); expect(RenderingServiceConstructor).toHaveBeenCalledTimes(1); expect(IntegrationsServiceConstructor).toHaveBeenCalledTimes(1); + expect(CoreAppConstructor).toHaveBeenCalledTimes(1); }); it('passes injectedMetadata param to InjectedMetadataService', () => { @@ -231,6 +234,11 @@ describe('#setup()', () => { await setupCore(); expect(MockIntegrationsService.setup).toHaveBeenCalledTimes(1); }); + + it('calls coreApp#setup()', async () => { + await setupCore(); + expect(MockCoreApp.setup).toHaveBeenCalledTimes(1); + }); }); describe('#start()', () => { @@ -315,10 +323,15 @@ describe('#start()', () => { }); }); - it('calls start#setup()', async () => { + it('calls integrations#start()', async () => { await startCore(); expect(MockIntegrationsService.start).toHaveBeenCalledTimes(1); }); + + it('calls coreApp#start()', async () => { + await startCore(); + expect(MockCoreApp.start).toHaveBeenCalledTimes(1); + }); }); describe('#stop()', () => { @@ -377,6 +390,14 @@ describe('#stop()', () => { expect(MockIntegrationsService.stop).toHaveBeenCalled(); }); + it('calls coreApp.stop()', () => { + const coreSystem = createCoreSystem(); + + expect(MockCoreApp.stop).not.toHaveBeenCalled(); + coreSystem.stop(); + expect(MockCoreApp.stop).toHaveBeenCalled(); + }); + it('clears the rootDomElement', async () => { const rootDomElement = document.createElement('div'); const coreSystem = createCoreSystem({ diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 46e1ecb83e9e4..aa52212344f4d 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -43,6 +43,7 @@ import { SavedObjectsService } from './saved_objects'; import { ContextService } from './context'; import { IntegrationsService } from './integrations'; import { InternalApplicationSetup, InternalApplicationStart } from './application/types'; +import { CoreApp } from './core_app'; interface Params { rootDomElement: HTMLElement; @@ -99,6 +100,7 @@ export class CoreSystem { private readonly rendering: RenderingService; private readonly context: ContextService; private readonly integrations: IntegrationsService; + private readonly coreApp: CoreApp; private readonly rootDomElement: HTMLElement; private readonly coreContext: CoreContext; @@ -142,6 +144,7 @@ export class CoreSystem { this.context = new ContextService(this.coreContext); this.plugins = new PluginsService(this.coreContext, injectedMetadata.uiPlugins); + this.coreApp = new CoreApp(this.coreContext); this.legacy = new LegacyPlatformService({ requireLegacyFiles, @@ -177,6 +180,7 @@ export class CoreSystem { ]), }); const application = this.application.setup({ context, http, injectedMetadata }); + this.coreApp.setup({ application, http }); const core: InternalCoreSetup = { application, @@ -245,6 +249,8 @@ export class CoreSystem { uiSettings, }); + this.coreApp.start({ application, http, notifications, uiSettings }); + application.registerMountContext(this.coreContext.coreId, 'core', () => ({ application: pick(application, ['capabilities', 'navigateToApp']), chrome, @@ -308,6 +314,7 @@ export class CoreSystem { public stop() { this.legacy.stop(); this.plugins.stop(); + this.coreApp.stop(); this.notifications.stop(); this.http.stop(); this.integrations.stop(); diff --git a/src/core/public/index.ts b/src/core/public/index.ts index bd275ca1d4565..40f614ebc3bea 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -191,6 +191,8 @@ export { export { MountPoint, UnmountCallback, PublicUiSettingsParams } from './types'; +export { URL_MAX_LENGTH } from './core_app'; + /** * Core services exposed to the `Plugin` setup lifecycle * diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 74c41d010ca8d..b44eb48b9ffa9 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -1424,6 +1424,9 @@ export type UiSettingsType = 'undefined' | 'json' | 'markdown' | 'number' | 'sel // @public export type UnmountCallback = () => void; +// @public +export const URL_MAX_LENGTH: number; + // @public export interface URLMeaningfulParts { // (undocumented) diff --git a/src/core/server/plugins/plugin_context.ts b/src/core/server/plugins/plugin_context.ts index 7afb607192cae..f0db3a25e313d 100644 --- a/src/core/server/plugins/plugin_context.ts +++ b/src/core/server/plugins/plugin_context.ts @@ -17,7 +17,7 @@ * under the License. */ -import { map } from 'rxjs/operators'; +import { map, shareReplay } from 'rxjs/operators'; import { combineLatest } from 'rxjs'; import { CoreContext } from '../core_context'; import { PluginWrapper } from './plugin'; @@ -107,8 +107,8 @@ export function createPluginInitializerContext( * @param ConfigClass A class (not an instance of a class) that contains a * static `schema` that we validate the config at the given `path` against. */ - create() { - return coreContext.configService.atPath(pluginManifest.configPath); + create() { + return coreContext.configService.atPath(pluginManifest.configPath).pipe(shareReplay(1)); }, createIfExists() { return coreContext.configService.optionalAtPath(pluginManifest.configPath); diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts index 4f69d45c192e9..69b57a498936e 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts @@ -74,6 +74,7 @@ export class KibanaMigrator { private readonly status$ = new BehaviorSubject({ status: 'waiting', }); + private readonly activeMappings: IndexMapping; /** * Creates an instance of KibanaMigrator. @@ -100,6 +101,9 @@ export class KibanaMigrator { validateDoc: docValidator(savedObjectValidations || {}), log: this.log, }); + // Building the active mappings (and associated md5sums) is an expensive + // operation so we cache the result + this.activeMappings = buildActiveMappings(this.mappingProperties); } /** @@ -172,7 +176,7 @@ export class KibanaMigrator { * */ public getActiveMappings(): IndexMapping { - return buildActiveMappings(this.mappingProperties); + return this.activeMappings; } /** diff --git a/src/core/server/saved_objects/routes/integration_tests/bulk_create.test.ts b/src/core/server/saved_objects/routes/integration_tests/bulk_create.test.ts index 5b52665b6268e..28afdefe1413f 100644 --- a/src/core/server/saved_objects/routes/integration_tests/bulk_create.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/bulk_create.test.ts @@ -21,7 +21,7 @@ import supertest from 'supertest'; import { UnwrapPromise } from '@kbn/utility-types'; import { registerBulkCreateRoute } from '../bulk_create'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; -import { setupServer } from './test_utils'; +import { setupServer } from '../test_utils'; type setupServerReturn = UnwrapPromise>; diff --git a/src/core/server/saved_objects/routes/integration_tests/bulk_get.test.ts b/src/core/server/saved_objects/routes/integration_tests/bulk_get.test.ts index 845bae47b41f2..521e62e16b1d8 100644 --- a/src/core/server/saved_objects/routes/integration_tests/bulk_get.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/bulk_get.test.ts @@ -21,7 +21,7 @@ import supertest from 'supertest'; import { UnwrapPromise } from '@kbn/utility-types'; import { registerBulkGetRoute } from '../bulk_get'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; -import { setupServer } from './test_utils'; +import { setupServer } from '../test_utils'; type setupServerReturn = UnwrapPromise>; diff --git a/src/core/server/saved_objects/routes/integration_tests/bulk_update.test.ts b/src/core/server/saved_objects/routes/integration_tests/bulk_update.test.ts index 6356fc787a8d8..9c888406b0c96 100644 --- a/src/core/server/saved_objects/routes/integration_tests/bulk_update.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/bulk_update.test.ts @@ -21,7 +21,7 @@ import supertest from 'supertest'; import { UnwrapPromise } from '@kbn/utility-types'; import { registerBulkUpdateRoute } from '../bulk_update'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; -import { setupServer } from './test_utils'; +import { setupServer } from '../test_utils'; type setupServerReturn = UnwrapPromise>; diff --git a/src/core/server/saved_objects/routes/integration_tests/create.test.ts b/src/core/server/saved_objects/routes/integration_tests/create.test.ts index 5a53a30209281..ba3d620f8fdb5 100644 --- a/src/core/server/saved_objects/routes/integration_tests/create.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/create.test.ts @@ -21,7 +21,7 @@ import supertest from 'supertest'; import { UnwrapPromise } from '@kbn/utility-types'; import { registerCreateRoute } from '../create'; import { savedObjectsClientMock } from '../../service/saved_objects_client.mock'; -import { setupServer } from './test_utils'; +import { setupServer } from '../test_utils'; type setupServerReturn = UnwrapPromise>; diff --git a/src/core/server/saved_objects/routes/integration_tests/delete.test.ts b/src/core/server/saved_objects/routes/integration_tests/delete.test.ts index d4ce4d421dde1..652d267f08fe7 100644 --- a/src/core/server/saved_objects/routes/integration_tests/delete.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/delete.test.ts @@ -21,7 +21,7 @@ import supertest from 'supertest'; import { UnwrapPromise } from '@kbn/utility-types'; import { registerDeleteRoute } from '../delete'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; -import { setupServer } from './test_utils'; +import { setupServer } from '../test_utils'; type setupServerReturn = UnwrapPromise>; diff --git a/src/core/server/saved_objects/routes/integration_tests/export.test.ts b/src/core/server/saved_objects/routes/integration_tests/export.test.ts index bdb2e23f0826d..7b342dde2febe 100644 --- a/src/core/server/saved_objects/routes/integration_tests/export.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/export.test.ts @@ -27,7 +27,7 @@ import supertest from 'supertest'; import { UnwrapPromise } from '@kbn/utility-types'; import { SavedObjectConfig } from '../../saved_objects_config'; import { registerExportRoute } from '../export'; -import { setupServer, createExportableType } from './test_utils'; +import { setupServer, createExportableType } from '../test_utils'; type setupServerReturn = UnwrapPromise>; const exportSavedObjectsToStream = exportMock.exportSavedObjectsToStream as jest.Mock; diff --git a/src/core/server/saved_objects/routes/integration_tests/find.test.ts b/src/core/server/saved_objects/routes/integration_tests/find.test.ts index 7916100e46831..31bda1d6b9cbd 100644 --- a/src/core/server/saved_objects/routes/integration_tests/find.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/find.test.ts @@ -23,7 +23,7 @@ import querystring from 'querystring'; import { UnwrapPromise } from '@kbn/utility-types'; import { registerFindRoute } from '../find'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; -import { setupServer } from './test_utils'; +import { setupServer } from '../test_utils'; type setupServerReturn = UnwrapPromise>; diff --git a/src/core/server/saved_objects/routes/integration_tests/import.test.ts b/src/core/server/saved_objects/routes/integration_tests/import.test.ts index c4a03a0e2e7d2..c4e304a3f892f 100644 --- a/src/core/server/saved_objects/routes/integration_tests/import.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/import.test.ts @@ -22,7 +22,7 @@ import { UnwrapPromise } from '@kbn/utility-types'; import { registerImportRoute } from '../import'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; import { SavedObjectConfig } from '../../saved_objects_config'; -import { setupServer, createExportableType } from './test_utils'; +import { setupServer, createExportableType } from '../test_utils'; type setupServerReturn = UnwrapPromise>; diff --git a/src/core/server/saved_objects/routes/integration_tests/log_legacy_import.test.ts b/src/core/server/saved_objects/routes/integration_tests/log_legacy_import.test.ts index 4bbe3271e0232..0fe07245dda20 100644 --- a/src/core/server/saved_objects/routes/integration_tests/log_legacy_import.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/log_legacy_import.test.ts @@ -21,7 +21,7 @@ import supertest from 'supertest'; import { UnwrapPromise } from '@kbn/utility-types'; import { registerLogLegacyImportRoute } from '../log_legacy_import'; import { loggingServiceMock } from '../../../logging/logging_service.mock'; -import { setupServer } from './test_utils'; +import { setupServer } from '../test_utils'; type setupServerReturn = UnwrapPromise>; diff --git a/src/core/server/saved_objects/routes/integration_tests/resolve_import_errors.test.ts b/src/core/server/saved_objects/routes/integration_tests/resolve_import_errors.test.ts index a36f246f9dbc5..27750ec692e5a 100644 --- a/src/core/server/saved_objects/routes/integration_tests/resolve_import_errors.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/resolve_import_errors.test.ts @@ -21,7 +21,7 @@ import supertest from 'supertest'; import { UnwrapPromise } from '@kbn/utility-types'; import { registerResolveImportErrorsRoute } from '../resolve_import_errors'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; -import { setupServer, createExportableType } from './test_utils'; +import { setupServer, createExportableType } from '../test_utils'; import { SavedObjectConfig } from '../../saved_objects_config'; type setupServerReturn = UnwrapPromise>; diff --git a/src/core/server/saved_objects/routes/integration_tests/update.test.ts b/src/core/server/saved_objects/routes/integration_tests/update.test.ts index b0c3d68090db6..eb6eb1cdb6bd9 100644 --- a/src/core/server/saved_objects/routes/integration_tests/update.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/update.test.ts @@ -21,7 +21,7 @@ import supertest from 'supertest'; import { UnwrapPromise } from '@kbn/utility-types'; import { registerUpdateRoute } from '../update'; import { savedObjectsClientMock } from '../../../../../core/server/mocks'; -import { setupServer } from './test_utils'; +import { setupServer } from '../test_utils'; type setupServerReturn = UnwrapPromise>; diff --git a/src/core/server/saved_objects/routes/integration_tests/test_utils.ts b/src/core/server/saved_objects/routes/test_utils.ts similarity index 83% rename from src/core/server/saved_objects/routes/integration_tests/test_utils.ts rename to src/core/server/saved_objects/routes/test_utils.ts index 23e0285201dc7..a2227a8033dbd 100644 --- a/src/core/server/saved_objects/routes/integration_tests/test_utils.ts +++ b/src/core/server/saved_objects/routes/test_utils.ts @@ -17,14 +17,14 @@ * under the License. */ -import { ContextService } from '../../../context'; -import { createHttpServer, createCoreContext } from '../../../http/test_utils'; -import { coreMock } from '../../../mocks'; -import { SavedObjectsType } from '../../types'; +import { ContextService } from '../../context'; +import { createHttpServer, createCoreContext } from '../../http/test_utils'; +import { coreMock } from '../../mocks'; +import { SavedObjectsType } from '../types'; -const coreId = Symbol('core'); +const defaultCoreId = Symbol('core'); -export const setupServer = async () => { +export const setupServer = async (coreId: symbol = defaultCoreId) => { const coreContext = createCoreContext({ coreId }); const contextService = new ContextService(coreContext); diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index e23f8dec5927c..b093fe779cab7 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -136,7 +136,7 @@ export class SavedObjectsRepository { injectedConstructor: any = SavedObjectsRepository ): ISavedObjectsRepository { const mappings = migrator.getActiveMappings(); - const allTypes = Object.keys(getRootPropertiesObjects(mappings)); + const allTypes = typeRegistry.getAllTypes().map((t) => t.name); const serializer = new SavedObjectsSerializer(typeRegistry); const visibleTypes = allTypes.filter((type) => !typeRegistry.isHidden(type)); diff --git a/src/core/server/test_utils.ts b/src/core/server/test_utils.ts index f7e6fbcd0c131..6b16fe3bdef61 100644 --- a/src/core/server/test_utils.ts +++ b/src/core/server/test_utils.ts @@ -19,3 +19,4 @@ export { createHttpServer } from './http/test_utils'; export { ServiceStatusLevelSnapshotSerializer } from './status/test_utils'; +export { setupServer } from './saved_objects/routes/test_utils'; diff --git a/src/core/types/index.ts b/src/core/types/index.ts index 346b4cfce70c1..07d7789d235ec 100644 --- a/src/core/types/index.ts +++ b/src/core/types/index.ts @@ -26,3 +26,4 @@ export * from './capabilities'; export * from './app_category'; export * from './ui_settings'; export * from './saved_objects'; +export * from './serializable'; diff --git a/src/core/types/serializable.ts b/src/core/types/serializable.ts new file mode 100644 index 0000000000000..9e8ea123bea91 --- /dev/null +++ b/src/core/types/serializable.ts @@ -0,0 +1,32 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export type Serializable = + | string + | number + | boolean + | null + | SerializableArray + | SerializableRecord; + +// we need interfaces instead of types here to allow cyclic references +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface SerializableArray extends Array {} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface SerializableRecord extends Record {} diff --git a/src/dev/build/build_distributables.js b/src/dev/build/build_distributables.js index 3a8709893565d..66f0c0355c2d9 100644 --- a/src/dev/build/build_distributables.js +++ b/src/dev/build/build_distributables.js @@ -30,6 +30,7 @@ import { CleanTypescriptTask, CleanNodeBuildsTask, CleanTask, + CopyBinScriptsTask, CopySourceTask, CreateArchivesSourcesTask, CreateArchivesTask, @@ -110,6 +111,7 @@ export async function buildDistributables(options) { * run platform-generic build tasks */ await run(CopySourceTask); + await run(CopyBinScriptsTask); await run(CreateEmptyDirsAndFilesTask); await run(CreateReadmeTask); await run(TranspileBabelTask); diff --git a/src/dev/build/tasks/bin/copy_bin_scripts_task.js b/src/dev/build/tasks/bin/copy_bin_scripts_task.js new file mode 100644 index 0000000000000..f620f12b17d88 --- /dev/null +++ b/src/dev/build/tasks/bin/copy_bin_scripts_task.js @@ -0,0 +1,31 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { copyAll } from '../../lib'; + +export const CopyBinScriptsTask = { + description: 'Copying bin scripts into platform-generic build directory', + + async run(config, log, build) { + await copyAll( + config.resolveFromRepo('src/dev/build/tasks/bin/scripts'), + build.resolvePath('bin') + ); + }, +}; diff --git a/src/legacy/ui/public/error_url_overflow/index.js b/src/dev/build/tasks/bin/index.js similarity index 87% rename from src/legacy/ui/public/error_url_overflow/index.js rename to src/dev/build/tasks/bin/index.js index 06a98789349f8..e970ac5ec044b 100644 --- a/src/legacy/ui/public/error_url_overflow/index.js +++ b/src/dev/build/tasks/bin/index.js @@ -17,5 +17,4 @@ * under the License. */ -import './error_url_overflow'; -export { UrlOverflowService } from '../../../../plugins/kibana_legacy/public'; +export { CopyBinScriptsTask } from './copy_bin_scripts_task'; diff --git a/bin/kibana b/src/dev/build/tasks/bin/scripts/kibana similarity index 100% rename from bin/kibana rename to src/dev/build/tasks/bin/scripts/kibana diff --git a/bin/kibana-keystore b/src/dev/build/tasks/bin/scripts/kibana-keystore similarity index 100% rename from bin/kibana-keystore rename to src/dev/build/tasks/bin/scripts/kibana-keystore diff --git a/bin/kibana-keystore.bat b/src/dev/build/tasks/bin/scripts/kibana-keystore.bat similarity index 100% rename from bin/kibana-keystore.bat rename to src/dev/build/tasks/bin/scripts/kibana-keystore.bat diff --git a/bin/kibana-plugin b/src/dev/build/tasks/bin/scripts/kibana-plugin similarity index 100% rename from bin/kibana-plugin rename to src/dev/build/tasks/bin/scripts/kibana-plugin diff --git a/bin/kibana-plugin.bat b/src/dev/build/tasks/bin/scripts/kibana-plugin.bat similarity index 100% rename from bin/kibana-plugin.bat rename to src/dev/build/tasks/bin/scripts/kibana-plugin.bat diff --git a/bin/kibana.bat b/src/dev/build/tasks/bin/scripts/kibana.bat similarity index 100% rename from bin/kibana.bat rename to src/dev/build/tasks/bin/scripts/kibana.bat diff --git a/src/dev/build/tasks/copy_source_task.js b/src/dev/build/tasks/copy_source_task.js index ee9dc159de47f..ddc6d000bca19 100644 --- a/src/dev/build/tasks/copy_source_task.js +++ b/src/dev/build/tasks/copy_source_task.js @@ -42,7 +42,6 @@ export const CopySourceTask = { '!src/es_archiver/**', '!src/functional_test_runner/**', '!src/dev/**', - 'bin/**', 'typings/**', 'webpackShims/**', 'config/kibana.yml', diff --git a/src/dev/build/tasks/index.js b/src/dev/build/tasks/index.js index 8105fa8a7d5d4..bafb5a2fe115e 100644 --- a/src/dev/build/tasks/index.js +++ b/src/dev/build/tasks/index.js @@ -17,6 +17,7 @@ * under the License. */ +export * from './bin'; export * from './build_packages_task'; export * from './clean_tasks'; export * from './copy_source_task'; diff --git a/src/dev/build/tasks/os_packages/run_fpm.js b/src/dev/build/tasks/os_packages/run_fpm.js index c49ff01b24086..0496bcf08fb91 100644 --- a/src/dev/build/tasks/os_packages/run_fpm.js +++ b/src/dev/build/tasks/os_packages/run_fpm.js @@ -123,9 +123,9 @@ export async function runFpm(config, log, build, type, pkgSpecificFlags) { // copy the data directory at /var/lib/kibana `${resolveWithTrailingSlash(fromBuild('data'))}=/var/lib/kibana/`, - // copy the generated pleaserun services for systemd and sysv into /etc/ - `${resolveWithTrailingSlash(__dirname, 'service_templates/sysv/etc')}=/etc/`, - `${resolveWithTrailingSlash(__dirname, 'service_templates/systemd/etc')}=/etc/`, + // copy package configurations + `${resolveWithTrailingSlash(__dirname, 'service_templates/sysv/')}=/`, + `${resolveWithTrailingSlash(__dirname, 'service_templates/systemd/')}=/`, ]; log.debug('calling fpm with args:', args); diff --git a/src/dev/build/tasks/os_packages/service_templates/systemd/usr/lib/tmpfiles.d/kibana.conf b/src/dev/build/tasks/os_packages/service_templates/systemd/usr/lib/tmpfiles.d/kibana.conf new file mode 100644 index 0000000000000..b5422df52fe11 --- /dev/null +++ b/src/dev/build/tasks/os_packages/service_templates/systemd/usr/lib/tmpfiles.d/kibana.conf @@ -0,0 +1 @@ +d /var/run/kibana 0755 kibana kibana - - \ No newline at end of file diff --git a/src/dev/build/tasks/os_packages/service_templates/sysv/etc/init.d/kibana b/src/dev/build/tasks/os_packages/service_templates/sysv/etc/init.d/kibana index ce29fd12b8e3c..d935dc6e31f80 100755 --- a/src/dev/build/tasks/os_packages/service_templates/sysv/etc/init.d/kibana +++ b/src/dev/build/tasks/os_packages/service_templates/sysv/etc/init.d/kibana @@ -17,7 +17,7 @@ name=kibana program=/usr/share/kibana/bin/kibana -pidfile="/var/run/$name.pid" +pidfile="/var/run/kibana/$name.pid" [ -r /etc/default/$name ] && . /etc/default/$name [ -r /etc/sysconfig/$name ] && . /etc/sysconfig/$name @@ -37,17 +37,13 @@ emit() { } start() { - - # Ensure the log directory is setup correctly. [ ! -d "/var/log/kibana/" ] && mkdir "/var/log/kibana/" chown "$user":"$group" "/var/log/kibana/" chmod 755 "/var/log/kibana/" - - # Setup any environmental stuff beforehand - - - # Run the program! + [ ! -d "/var/run/kibana/" ] && mkdir "/var/run/kibana/" + chown "$user":"$group" "/var/run/kibana/" + chmod 755 "/var/run/kibana/" chroot --userspec "$user":"$group" "$chroot" sh -c " diff --git a/src/dev/code_coverage/nyc_config/nyc.functional.config.js b/src/dev/code_coverage/nyc_config/nyc.functional.config.js new file mode 100644 index 0000000000000..20d266ab9e2c3 --- /dev/null +++ b/src/dev/code_coverage/nyc_config/nyc.functional.config.js @@ -0,0 +1,31 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const defaultExclude = require('@istanbuljs/schema/default-exclude'); +const extraExclude = ['data/optimize/**', 'src/core/server/**', '**/test/**']; +const path = require('path'); + +module.exports = { + 'temp-dir': process.env.COVERAGE_TEMP_DIR + ? path.resolve(process.env.COVERAGE_TEMP_DIR, 'functional') + : 'target/kibana-coverage/functional', + 'report-dir': 'target/kibana-coverage/functional-combined', + reporter: ['html', 'json-summary'], + exclude: extraExclude.concat(defaultExclude), +}; diff --git a/src/dev/code_coverage/nyc_config/nyc.jest.config.js b/src/dev/code_coverage/nyc_config/nyc.jest.config.js new file mode 100644 index 0000000000000..1f73347837ab3 --- /dev/null +++ b/src/dev/code_coverage/nyc_config/nyc.jest.config.js @@ -0,0 +1,28 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const path = require('path'); + +module.exports = { + 'temp-dir': process.env.COVERAGE_TEMP_DIR + ? path.resolve(process.env.COVERAGE_TEMP_DIR, 'jest') + : 'target/kibana-coverage/jest', + 'report-dir': 'target/kibana-coverage/jest-combined', + reporter: ['html', 'json-summary'], +}; diff --git a/src/dev/code_coverage/shell_scripts/merge_jest_and_functional.sh b/src/dev/code_coverage/shell_scripts/merge_jest_and_functional.sh index ff9cb36c894f8..707c6de3f88a0 100644 --- a/src/dev/code_coverage/shell_scripts/merge_jest_and_functional.sh +++ b/src/dev/code_coverage/shell_scripts/merge_jest_and_functional.sh @@ -1,10 +1,9 @@ #!/bin/bash -EXTRACT_START_DIR=tmp/extracted_coverage -EXTRACT_END_DIR=target/kibana-coverage -COMBINED_EXTRACT_DIR=/${EXTRACT_START_DIR}/${EXTRACT_END_DIR} +COVERAGE_TEMP_DIR=/tmp/extracted_coverage/target/kibana-coverage/ +export COVERAGE_TEMP_DIR echo "### Merge coverage reports" for x in jest functional; do - yarn nyc report --temp-dir $COMBINED_EXTRACT_DIR/${x} --report-dir $EXTRACT_END_DIR/${x}-combined --reporter=html --reporter=json-summary + yarn nyc report --nycrc-path src/dev/code_coverage/nyc_config/nyc.${x}.config.js done diff --git a/src/dev/jest/config.js b/src/dev/jest/config.js index 497a639ecab56..64db131f5219a 100644 --- a/src/dev/jest/config.js +++ b/src/dev/jest/config.js @@ -64,7 +64,8 @@ export default { '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '/src/dev/jest/mocks/file_mock.js', '\\.(css|less|scss)$': '/src/dev/jest/mocks/style_mock.js', - '\\.ace\\.worker.js$': '/src/dev/jest/mocks/ace_worker_module_mock.js', + '\\.ace\\.worker.js$': '/src/dev/jest/mocks/worker_module_mock.js', + '\\.editor\\.worker.js$': '/src/dev/jest/mocks/worker_module_mock.js', '^(!!)?file-loader!': '/src/dev/jest/mocks/file_mock.js', }, setupFiles: [ diff --git a/src/dev/jest/mocks/ace_worker_module_mock.js b/src/dev/jest/mocks/worker_module_mock.js similarity index 100% rename from src/dev/jest/mocks/ace_worker_module_mock.js rename to src/dev/jest/mocks/worker_module_mock.js diff --git a/src/dev/storybook/aliases.ts b/src/dev/storybook/aliases.ts index 416702c56d852..2f785896da8d5 100644 --- a/src/dev/storybook/aliases.ts +++ b/src/dev/storybook/aliases.ts @@ -18,7 +18,6 @@ */ export const storybookAliases = { - advanced_ui_actions: 'x-pack/plugins/advanced_ui_actions/scripts/storybook.js', apm: 'x-pack/plugins/apm/scripts/storybook.js', canvas: 'x-pack/plugins/canvas/scripts/storybook_new.js', codeeditor: 'src/plugins/kibana_react/public/code_editor/scripts/storybook.ts', @@ -26,5 +25,6 @@ export const storybookAliases = { drilldowns: 'x-pack/plugins/drilldowns/scripts/storybook.js', embeddable: 'src/plugins/embeddable/scripts/storybook.js', infra: 'x-pack/legacy/plugins/infra/scripts/storybook.js', - siem: 'x-pack/plugins/siem/scripts/storybook.js', + security_solution: 'x-pack/plugins/security_solution/scripts/storybook.js', + ui_actions_enhanced: 'x-pack/plugins/ui_actions_enhanced/scripts/storybook.js', }; diff --git a/src/dev/typescript/projects.ts b/src/dev/typescript/projects.ts index b368949cc33e1..1e0b631308d9e 100644 --- a/src/dev/typescript/projects.ts +++ b/src/dev/typescript/projects.ts @@ -27,8 +27,8 @@ export const PROJECTS = [ new Project(resolve(REPO_ROOT, 'test/tsconfig.json'), { name: 'kibana/test' }), new Project(resolve(REPO_ROOT, 'x-pack/tsconfig.json')), new Project(resolve(REPO_ROOT, 'x-pack/test/tsconfig.json'), { name: 'x-pack/test' }), - new Project(resolve(REPO_ROOT, 'x-pack/plugins/siem/cypress/tsconfig.json'), { - name: 'siem/cypress', + new Project(resolve(REPO_ROOT, 'x-pack/plugins/security_solution/cypress/tsconfig.json'), { + name: 'security_solution/cypress', }), new Project(resolve(REPO_ROOT, 'x-pack/plugins/apm/e2e/tsconfig.json'), { name: 'apm/cypress', diff --git a/src/legacy/core_plugins/kibana/server/ui_setting_defaults.js b/src/legacy/core_plugins/kibana/server/ui_setting_defaults.js index 0d1b69778263c..b7af6a73e1bc1 100644 --- a/src/legacy/core_plugins/kibana/server/ui_setting_defaults.js +++ b/src/legacy/core_plugins/kibana/server/ui_setting_defaults.js @@ -18,53 +18,32 @@ */ import moment from 'moment-timezone'; -import numeralLanguages from '@elastic/numeral/languages'; import { i18n } from '@kbn/i18n'; import { schema } from '@kbn/config-schema'; import { isRelativeUrl } from '../../../../core/server'; -import { DEFAULT_QUERY_LANGUAGE } from '../../../../plugins/data/common'; export function getUiSettingDefaults() { const weekdays = moment.weekdays().slice(); const [defaultWeekday] = weekdays; - // We add the `en` key manually here, since that's not a real numeral locale, but the - // default fallback in case the locale is not found. - const numeralLanguageIds = [ - 'en', - ...numeralLanguages.map(function (numeralLanguage) { - return numeralLanguage.id; - }), - ]; - - const luceneQueryLanguageLabel = i18n.translate( - 'kbn.advancedSettings.searchQueryLanguageLucene', - { - defaultMessage: 'Lucene', - } - ); - - const queryLanguageSettingName = i18n.translate('kbn.advancedSettings.searchQueryLanguageTitle', { - defaultMessage: 'Query language', - }); - - const requestPreferenceOptionLabels = { - sessionId: i18n.translate('kbn.advancedSettings.courier.requestPreferenceSessionId', { - defaultMessage: 'Session ID', - }), - custom: i18n.translate('kbn.advancedSettings.courier.requestPreferenceCustom', { - defaultMessage: 'Custom', - }), - none: i18n.translate('kbn.advancedSettings.courier.requestPreferenceNone', { - defaultMessage: 'None', - }), - }; // wrapped in provider so that a new instance is given to each app/test return { buildNum: { readonly: true, }, + 'state:storeInSessionStorage': { + name: i18n.translate('kbn.advancedSettings.storeUrlTitle', { + defaultMessage: 'Store URLs in session storage', + }), + value: false, + description: i18n.translate('kbn.advancedSettings.storeUrlText', { + defaultMessage: + 'The URL can sometimes grow to be too large for some browsers to handle. ' + + 'To counter-act this we are testing if storing parts of the URL in session storage could help. ' + + 'Please let us know how it goes!', + }), + }, defaultRoute: { name: i18n.translate('kbn.advancedSettings.defaultRoute.defaultRouteTitle', { defaultMessage: 'Default route', @@ -89,83 +68,6 @@ export function getUiSettingDefaults() { 'The route must be a relative URL.', }), }, - 'query:queryString:options': { - name: i18n.translate('kbn.advancedSettings.query.queryStringOptionsTitle', { - defaultMessage: 'Query string options', - }), - value: '{ "analyze_wildcard": true }', - description: i18n.translate('kbn.advancedSettings.query.queryStringOptionsText', { - defaultMessage: - '{optionsLink} for the lucene query string parser. Is only used when "{queryLanguage}" is set ' + - 'to {luceneLanguage}.', - description: - 'Part of composite text: kbn.advancedSettings.query.queryStringOptions.optionsLinkText + ' + - 'kbn.advancedSettings.query.queryStringOptionsText', - values: { - optionsLink: - '' + - i18n.translate('kbn.advancedSettings.query.queryStringOptions.optionsLinkText', { - defaultMessage: 'Options', - }) + - '', - luceneLanguage: luceneQueryLanguageLabel, - queryLanguage: queryLanguageSettingName, - }, - }), - type: 'json', - }, - 'query:allowLeadingWildcards': { - name: i18n.translate('kbn.advancedSettings.query.allowWildcardsTitle', { - defaultMessage: 'Allow leading wildcards in query', - }), - value: true, - description: i18n.translate('kbn.advancedSettings.query.allowWildcardsText', { - defaultMessage: - 'When set, * is allowed as the first character in a query clause. ' + - 'Currently only applies when experimental query features are enabled in the query bar. ' + - 'To disallow leading wildcards in basic lucene queries, use {queryStringOptionsPattern}.', - values: { - queryStringOptionsPattern: 'query:queryString:options', - }, - }), - }, - 'search:queryLanguage': { - name: queryLanguageSettingName, - value: DEFAULT_QUERY_LANGUAGE, - description: i18n.translate('kbn.advancedSettings.searchQueryLanguageText', { - defaultMessage: - 'Query language used by the query bar. KQL is a new language built specifically for Kibana.', - }), - type: 'select', - options: ['lucene', 'kuery'], - optionLabels: { - lucene: luceneQueryLanguageLabel, - kuery: i18n.translate('kbn.advancedSettings.searchQueryLanguageKql', { - defaultMessage: 'KQL', - }), - }, - }, - 'sort:options': { - name: i18n.translate('kbn.advancedSettings.sortOptionsTitle', { - defaultMessage: 'Sort options', - }), - value: '{ "unmapped_type": "boolean" }', - description: i18n.translate('kbn.advancedSettings.sortOptionsText', { - defaultMessage: '{optionsLink} for the Elasticsearch sort parameter', - description: - 'Part of composite text: kbn.advancedSettings.sortOptions.optionsLinkText + ' + - 'kbn.advancedSettings.sortOptionsText', - values: { - optionsLink: - '' + - i18n.translate('kbn.advancedSettings.sortOptions.optionsLinkText', { - defaultMessage: 'Options', - }) + - '', - }, - }), - type: 'json', - }, dateFormat: { name: i18n.translate('kbn.advancedSettings.dateFormatTitle', { defaultMessage: 'Date format', @@ -261,160 +163,6 @@ export function getUiSettingDefaults() { }, }), }, - defaultIndex: { - name: i18n.translate('kbn.advancedSettings.defaultIndexTitle', { - defaultMessage: 'Default index', - }), - value: null, - type: 'string', - description: i18n.translate('kbn.advancedSettings.defaultIndexText', { - defaultMessage: 'The index to access if no index is set', - }), - }, - 'courier:ignoreFilterIfFieldNotInIndex': { - name: i18n.translate('kbn.advancedSettings.courier.ignoreFilterTitle', { - defaultMessage: 'Ignore filter(s)', - }), - value: false, - description: i18n.translate('kbn.advancedSettings.courier.ignoreFilterText', { - defaultMessage: - 'This configuration enhances support for dashboards containing visualizations accessing dissimilar indexes. ' + - 'When disabled, all filters are applied to all visualizations. ' + - 'When enabled, filter(s) will be ignored for a visualization ' + - `when the visualization's index does not contain the filtering field.`, - }), - category: ['search'], - }, - 'courier:setRequestPreference': { - name: i18n.translate('kbn.advancedSettings.courier.requestPreferenceTitle', { - defaultMessage: 'Request preference', - }), - value: 'sessionId', - options: ['sessionId', 'custom', 'none'], - optionLabels: requestPreferenceOptionLabels, - type: 'select', - description: i18n.translate('kbn.advancedSettings.courier.requestPreferenceText', { - defaultMessage: `Allows you to set which shards handle your search requests. -
    -
  • {sessionId}: restricts operations to execute all search requests on the same shards. - This has the benefit of reusing shard caches across requests.
  • -
  • {custom}: allows you to define a your own preference. - Use courier:customRequestPreference to customize your preference value.
  • -
  • {none}: means do not set a preference. - This might provide better performance because requests can be spread across all shard copies. - However, results might be inconsistent because different shards might be in different refresh states.
  • -
`, - values: { - sessionId: requestPreferenceOptionLabels.sessionId, - custom: requestPreferenceOptionLabels.custom, - none: requestPreferenceOptionLabels.none, - }, - }), - category: ['search'], - }, - 'courier:customRequestPreference': { - name: i18n.translate('kbn.advancedSettings.courier.customRequestPreferenceTitle', { - defaultMessage: 'Custom request preference', - }), - value: '_local', - type: 'string', - description: i18n.translate('kbn.advancedSettings.courier.customRequestPreferenceText', { - defaultMessage: - '{requestPreferenceLink} used when {setRequestReferenceSetting} is set to {customSettingValue}.', - description: - 'Part of composite text: kbn.advancedSettings.courier.customRequestPreference.requestPreferenceLinkText + ' + - 'kbn.advancedSettings.courier.customRequestPreferenceText', - values: { - setRequestReferenceSetting: 'courier:setRequestPreference', - customSettingValue: '"custom"', - requestPreferenceLink: - '' + - i18n.translate( - 'kbn.advancedSettings.courier.customRequestPreference.requestPreferenceLinkText', - { - defaultMessage: 'Request Preference', - } - ) + - '', - }, - }), - category: ['search'], - }, - 'courier:maxConcurrentShardRequests': { - name: i18n.translate('kbn.advancedSettings.courier.maxRequestsTitle', { - defaultMessage: 'Max Concurrent Shard Requests', - }), - value: 0, - type: 'number', - description: i18n.translate('kbn.advancedSettings.courier.maxRequestsText', { - defaultMessage: - 'Controls the {maxRequestsLink} setting used for _msearch requests sent by Kibana. ' + - 'Set to 0 to disable this config and use the Elasticsearch default.', - values: { - maxRequestsLink: `max_concurrent_shard_requests`, - }, - }), - category: ['search'], - }, - 'courier:batchSearches': { - name: i18n.translate('kbn.advancedSettings.courier.batchSearchesTitle', { - defaultMessage: 'Batch concurrent searches', - }), - value: false, - type: 'boolean', - description: i18n.translate('kbn.advancedSettings.courier.batchSearchesText', { - defaultMessage: `When disabled, dashboard panels will load individually, and search requests will terminate when users navigate - away or update the query. When enabled, dashboard panels will load together when all of the data is loaded, and - searches will not terminate.`, - }), - deprecation: { - message: i18n.translate('kbn.advancedSettings.courier.batchSearchesTextDeprecation', { - defaultMessage: 'This setting is deprecated and will be removed in Kibana 8.0.', - }), - docLinksKey: 'kibanaSearchSettings', - }, - category: ['search'], - }, - 'search:includeFrozen': { - name: 'Search in frozen indices', - description: `Will include frozen indices in results if enabled. Searching through frozen indices - might increase the search time.`, - value: false, - category: ['search'], - }, - 'histogram:barTarget': { - name: i18n.translate('kbn.advancedSettings.histogram.barTargetTitle', { - defaultMessage: 'Target bars', - }), - value: 50, - description: i18n.translate('kbn.advancedSettings.histogram.barTargetText', { - defaultMessage: - 'Attempt to generate around this many bars when using "auto" interval in date histograms', - }), - }, - 'histogram:maxBars': { - name: i18n.translate('kbn.advancedSettings.histogram.maxBarsTitle', { - defaultMessage: 'Maximum bars', - }), - value: 100, - description: i18n.translate('kbn.advancedSettings.histogram.maxBarsText', { - defaultMessage: - 'Never show more than this many bars in date histograms, scale values if needed', - }), - }, - 'visualize:enableLabs': { - name: i18n.translate('kbn.advancedSettings.visualizeEnableLabsTitle', { - defaultMessage: 'Enable experimental visualizations', - }), - value: true, - description: i18n.translate('kbn.advancedSettings.visualizeEnableLabsText', { - defaultMessage: `Allows users to create, view, and edit experimental visualizations. If disabled, - only visualizations that are considered production-ready are available to the user.`, - }), - category: ['visualization'], - }, 'visualization:tileMap:maxPrecision': { name: i18n.translate('kbn.advancedSettings.visualization.tileMap.maxPrecisionTitle', { defaultMessage: 'Maximum tile map precision', @@ -493,43 +241,6 @@ export function getUiSettingDefaults() { }), category: ['visualization'], }, - 'csv:separator': { - name: i18n.translate('kbn.advancedSettings.csv.separatorTitle', { - defaultMessage: 'CSV separator', - }), - value: ',', - description: i18n.translate('kbn.advancedSettings.csv.separatorText', { - defaultMessage: 'Separate exported values with this string', - }), - }, - 'csv:quoteValues': { - name: i18n.translate('kbn.advancedSettings.csv.quoteValuesTitle', { - defaultMessage: 'Quote CSV values', - }), - value: true, - description: i18n.translate('kbn.advancedSettings.csv.quoteValuesText', { - defaultMessage: 'Should values be quoted in csv exports?', - }), - }, - 'history:limit': { - name: i18n.translate('kbn.advancedSettings.historyLimitTitle', { - defaultMessage: 'History limit', - }), - value: 10, - description: i18n.translate('kbn.advancedSettings.historyLimitText', { - defaultMessage: - 'In fields that have history (e.g. query inputs), show this many recent values', - }), - }, - 'shortDots:enable': { - name: i18n.translate('kbn.advancedSettings.shortenFieldsTitle', { - defaultMessage: 'Shorten fields', - }), - value: false, - description: i18n.translate('kbn.advancedSettings.shortenFieldsText', { - defaultMessage: 'Shorten long fields, for example, instead of foo.bar.baz, show f.b.baz', - }), - }, 'truncate:maxHeight': { name: i18n.translate('kbn.advancedSettings.maxCellHeightTitle', { defaultMessage: 'Maximum table cell height', @@ -540,138 +251,6 @@ export function getUiSettingDefaults() { 'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation', }), }, - 'format:defaultTypeMap': { - name: i18n.translate('kbn.advancedSettings.format.defaultTypeMapTitle', { - defaultMessage: 'Field type format name', - }), - value: `{ - "ip": { "id": "ip", "params": {} }, - "date": { "id": "date", "params": {} }, - "date_nanos": { "id": "date_nanos", "params": {}, "es": true }, - "number": { "id": "number", "params": {} }, - "boolean": { "id": "boolean", "params": {} }, - "_source": { "id": "_source", "params": {} }, - "_default_": { "id": "string", "params": {} } -}`, - type: 'json', - description: i18n.translate('kbn.advancedSettings.format.defaultTypeMapText', { - defaultMessage: - 'Map of the format name to use by default for each field type. ' + - '{defaultFormat} is used if the field type is not mentioned explicitly', - values: { - defaultFormat: '"_default_"', - }, - }), - }, - 'format:number:defaultPattern': { - name: i18n.translate('kbn.advancedSettings.format.numberFormatTitle', { - defaultMessage: 'Number format', - }), - value: '0,0.[000]', - type: 'string', - description: i18n.translate('kbn.advancedSettings.format.numberFormatText', { - defaultMessage: 'Default {numeralFormatLink} for the "number" format', - description: - 'Part of composite text: kbn.advancedSettings.format.numberFormatText + ' + - 'kbn.advancedSettings.format.numberFormat.numeralFormatLinkText', - values: { - numeralFormatLink: - '' + - i18n.translate('kbn.advancedSettings.format.numberFormat.numeralFormatLinkText', { - defaultMessage: 'numeral format', - }) + - '', - }, - }), - }, - 'format:bytes:defaultPattern': { - name: i18n.translate('kbn.advancedSettings.format.bytesFormatTitle', { - defaultMessage: 'Bytes format', - }), - value: '0,0.[0]b', - type: 'string', - description: i18n.translate('kbn.advancedSettings.format.bytesFormatText', { - defaultMessage: 'Default {numeralFormatLink} for the "bytes" format', - description: - 'Part of composite text: kbn.advancedSettings.format.bytesFormatText + ' + - 'kbn.advancedSettings.format.bytesFormat.numeralFormatLinkText', - values: { - numeralFormatLink: - '' + - i18n.translate('kbn.advancedSettings.format.bytesFormat.numeralFormatLinkText', { - defaultMessage: 'numeral format', - }) + - '', - }, - }), - }, - 'format:percent:defaultPattern': { - name: i18n.translate('kbn.advancedSettings.format.percentFormatTitle', { - defaultMessage: 'Percent format', - }), - value: '0,0.[000]%', - type: 'string', - description: i18n.translate('kbn.advancedSettings.format.percentFormatText', { - defaultMessage: 'Default {numeralFormatLink} for the "percent" format', - description: - 'Part of composite text: kbn.advancedSettings.format.percentFormatText + ' + - 'kbn.advancedSettings.format.percentFormat.numeralFormatLinkText', - values: { - numeralFormatLink: - '' + - i18n.translate('kbn.advancedSettings.format.percentFormat.numeralFormatLinkText', { - defaultMessage: 'numeral format', - }) + - '', - }, - }), - }, - 'format:currency:defaultPattern': { - name: i18n.translate('kbn.advancedSettings.format.currencyFormatTitle', { - defaultMessage: 'Currency format', - }), - value: '($0,0.[00])', - type: 'string', - description: i18n.translate('kbn.advancedSettings.format.currencyFormatText', { - defaultMessage: 'Default {numeralFormatLink} for the "currency" format', - description: - 'Part of composite text: kbn.advancedSettings.format.currencyFormatText + ' + - 'kbn.advancedSettings.format.currencyFormat.numeralFormatLinkText', - values: { - numeralFormatLink: - '' + - i18n.translate('kbn.advancedSettings.format.currencyFormat.numeralFormatLinkText', { - defaultMessage: 'numeral format', - }) + - '', - }, - }), - }, - 'format:number:defaultLocale': { - name: i18n.translate('kbn.advancedSettings.format.formattingLocaleTitle', { - defaultMessage: 'Formatting locale', - }), - value: 'en', - type: 'select', - options: numeralLanguageIds, - optionLabels: Object.fromEntries( - numeralLanguages.map((language) => [language.id, language.name]) - ), - description: i18n.translate('kbn.advancedSettings.format.formattingLocaleText', { - defaultMessage: `{numeralLanguageLink} locale`, - description: - 'Part of composite text: kbn.advancedSettings.format.formattingLocale.numeralLanguageLinkText + ' + - 'kbn.advancedSettings.format.formattingLocaleText', - values: { - numeralLanguageLink: - '' + - i18n.translate('kbn.advancedSettings.format.formattingLocale.numeralLanguageLinkText', { - defaultMessage: 'Numeral language', - }) + - '', - }, - }), - }, 'timepicker:timeDefaults': { name: i18n.translate('kbn.advancedSettings.timepicker.timeDefaultsTitle', { defaultMessage: 'Time filter defaults', @@ -686,120 +265,6 @@ export function getUiSettingDefaults() { }), requiresPageReload: true, }, - 'timepicker:refreshIntervalDefaults': { - name: i18n.translate('kbn.advancedSettings.timepicker.refreshIntervalDefaultsTitle', { - defaultMessage: 'Time filter refresh interval', - }), - value: `{ - "pause": false, - "value": 0 -}`, - type: 'json', - description: i18n.translate('kbn.advancedSettings.timepicker.refreshIntervalDefaultsText', { - defaultMessage: `The timefilter's default refresh interval`, - }), - requiresPageReload: true, - }, - 'timepicker:quickRanges': { - name: i18n.translate('kbn.advancedSettings.timepicker.quickRangesTitle', { - defaultMessage: 'Time filter quick ranges', - }), - value: JSON.stringify( - [ - { - from: 'now/d', - to: 'now/d', - display: i18n.translate('kbn.advancedSettings.timepicker.today', { - defaultMessage: 'Today', - }), - }, - { - from: 'now/w', - to: 'now/w', - display: i18n.translate('kbn.advancedSettings.timepicker.thisWeek', { - defaultMessage: 'This week', - }), - }, - { - from: 'now-15m', - to: 'now', - display: i18n.translate('kbn.advancedSettings.timepicker.last15Minutes', { - defaultMessage: 'Last 15 minutes', - }), - }, - { - from: 'now-30m', - to: 'now', - display: i18n.translate('kbn.advancedSettings.timepicker.last30Minutes', { - defaultMessage: 'Last 30 minutes', - }), - }, - { - from: 'now-1h', - to: 'now', - display: i18n.translate('kbn.advancedSettings.timepicker.last1Hour', { - defaultMessage: 'Last 1 hour', - }), - }, - { - from: 'now-24h', - to: 'now', - display: i18n.translate('kbn.advancedSettings.timepicker.last24Hours', { - defaultMessage: 'Last 24 hours', - }), - }, - { - from: 'now-7d', - to: 'now', - display: i18n.translate('kbn.advancedSettings.timepicker.last7Days', { - defaultMessage: 'Last 7 days', - }), - }, - { - from: 'now-30d', - to: 'now', - display: i18n.translate('kbn.advancedSettings.timepicker.last30Days', { - defaultMessage: 'Last 30 days', - }), - }, - { - from: 'now-90d', - to: 'now', - display: i18n.translate('kbn.advancedSettings.timepicker.last90Days', { - defaultMessage: 'Last 90 days', - }), - }, - { - from: 'now-1y', - to: 'now', - display: i18n.translate('kbn.advancedSettings.timepicker.last1Year', { - defaultMessage: 'Last 1 year', - }), - }, - ], - null, - 2 - ), - type: 'json', - description: i18n.translate('kbn.advancedSettings.timepicker.quickRangesText', { - defaultMessage: - 'The list of ranges to show in the Quick section of the time filter. This should be an array of objects, ' + - 'with each object containing "from", "to" (see {acceptedFormatsLink}), and ' + - '"display" (the title to be displayed).', - description: - 'Part of composite text: kbn.advancedSettings.timepicker.quickRangesText + ' + - 'kbn.advancedSettings.timepicker.quickRanges.acceptedFormatsLinkText', - values: { - acceptedFormatsLink: - `` + - i18n.translate('kbn.advancedSettings.timepicker.quickRanges.acceptedFormatsLinkText', { - defaultMessage: 'accepted formats', - }) + - '', - }, - }), - }, 'theme:darkMode': { name: i18n.translate('kbn.advancedSettings.darkModeTitle', { defaultMessage: 'Dark mode', @@ -822,26 +287,6 @@ export function getUiSettingDefaults() { }), requiresPageReload: true, }, - 'filters:pinnedByDefault': { - name: i18n.translate('kbn.advancedSettings.pinFiltersTitle', { - defaultMessage: 'Pin filters by default', - }), - value: false, - description: i18n.translate('kbn.advancedSettings.pinFiltersText', { - defaultMessage: 'Whether the filters should have a global state (be pinned) by default', - }), - }, - 'filterEditor:suggestValues': { - name: i18n.translate('kbn.advancedSettings.suggestFilterValuesTitle', { - defaultMessage: 'Filter editor suggest values', - description: '"Filter editor" refers to the UI you create filters in.', - }), - value: true, - description: i18n.translate('kbn.advancedSettings.suggestFilterValuesText', { - defaultMessage: - 'Set this property to false to prevent the filter editor from suggesting values for fields.', - }), - }, 'notifications:banner': { name: i18n.translate('kbn.advancedSettings.notifications.bannerTitle', { defaultMessage: 'Custom banner notification', @@ -930,28 +375,6 @@ export function getUiSettingDefaults() { type: 'number', category: ['notifications'], }, - 'state:storeInSessionStorage': { - name: i18n.translate('kbn.advancedSettings.storeUrlTitle', { - defaultMessage: 'Store URLs in session storage', - }), - value: false, - description: i18n.translate('kbn.advancedSettings.storeUrlText', { - defaultMessage: - 'The URL can sometimes grow to be too large for some browsers to handle. ' + - 'To counter-act this we are testing if storing parts of the URL in session storage could help. ' + - 'Please let us know how it goes!', - }), - }, - 'indexPattern:placeholder': { - name: i18n.translate('kbn.advancedSettings.indexPatternPlaceholderTitle', { - defaultMessage: 'Index pattern placeholder', - }), - value: '', - description: i18n.translate('kbn.advancedSettings.indexPatternPlaceholderText', { - defaultMessage: - 'The placeholder for the "Index pattern name" field in "Management > Index Patterns > Create Index Pattern".', - }), - }, 'accessibility:disableAnimations': { name: i18n.translate('kbn.advancedSettings.disableAnimationsTitle', { defaultMessage: 'Disable Animations', diff --git a/src/legacy/core_plugins/timelion/public/directives/saved_object_finder.js b/src/legacy/core_plugins/timelion/public/directives/saved_object_finder.js index 08a347fbf7295..879fab206b99d 100644 --- a/src/legacy/core_plugins/timelion/public/directives/saved_object_finder.js +++ b/src/legacy/core_plugins/timelion/public/directives/saved_object_finder.js @@ -29,6 +29,7 @@ import { PaginateDirectiveProvider, } from '../../../../../plugins/kibana_legacy/public'; import { PER_PAGE_SETTING } from '../../../../../plugins/saved_objects/common'; +import { VISUALIZE_ENABLE_LABS_SETTING } from '../../../../../plugins/visualizations/public'; const module = uiModules.get('kibana'); @@ -294,7 +295,7 @@ module prevSearch = filter; - const isLabsEnabled = config.get('visualize:enableLabs'); + const isLabsEnabled = config.get(VISUALIZE_ENABLE_LABS_SETTING); self.service.find(filter).then(function (hits) { hits.hits = hits.hits.filter( (hit) => isLabsEnabled || _.get(hit, 'type.stage') !== 'experimental' diff --git a/src/legacy/server/saved_objects/saved_objects_mixin.js b/src/legacy/server/saved_objects/saved_objects_mixin.js index 7d84c27bd1ef0..63839b9d0f1d7 100644 --- a/src/legacy/server/saved_objects/saved_objects_mixin.js +++ b/src/legacy/server/saved_objects/saved_objects_mixin.js @@ -27,14 +27,13 @@ import { importSavedObjectsFromStream, resolveSavedObjectsImportErrors, } from '../../../core/server/saved_objects'; -import { getRootPropertiesObjects } from '../../../core/server/saved_objects/mappings'; import { convertTypesToLegacySchema } from '../../../core/server/saved_objects/utils'; export function savedObjectsMixin(kbnServer, server) { const migrator = kbnServer.newPlatform.__internals.kibanaMigrator; const typeRegistry = kbnServer.newPlatform.start.core.savedObjects.getTypeRegistry(); const mappings = migrator.getActiveMappings(); - const allTypes = Object.keys(getRootPropertiesObjects(mappings)); + const allTypes = typeRegistry.getAllTypes().map((t) => t.name); const schema = new SavedObjectsSchema(convertTypesToLegacySchema(typeRegistry.getAllTypes())); const visibleTypes = allTypes.filter((type) => !schema.isHiddenType(type)); diff --git a/src/legacy/ui/public/_index.scss b/src/legacy/ui/public/_index.scss index d258ef190a100..323de2ea7d263 100644 --- a/src/legacy/ui/public/_index.scss +++ b/src/legacy/ui/public/_index.scss @@ -10,4 +10,3 @@ @import './accessibility/index'; @import './directives/index'; -@import './error_url_overflow/index'; diff --git a/src/legacy/ui/public/error_url_overflow/__tests__/ie_regex.js b/src/legacy/ui/public/error_url_overflow/__tests__/ie_regex.js deleted file mode 100644 index 3d770c13a81aa..0000000000000 --- a/src/legacy/ui/public/error_url_overflow/__tests__/ie_regex.js +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from '@kbn/expect'; -import { IE_REGEX } from '../../../../../plugins/kibana_legacy/public'; - -describe('IE_REGEX', () => { - it('should detect IE 9', () => { - const userAgent = 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)'; - expect(IE_REGEX.test(userAgent)).to.be(true); - }); - - it('should detect IE 10', () => { - const userAgent = - 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0)'; - expect(IE_REGEX.test(userAgent)).to.be(true); - }); - - it('should detect IE 11', () => { - const userAgent = - 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; ' + - '.NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; rv:11.0) like Gecko'; - expect(IE_REGEX.test(userAgent)).to.be(true); - }); - - it('should detect Edge', () => { - const userAgent = - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' + - '(KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/13.10586'; - expect(IE_REGEX.test(userAgent)).to.be(true); - }); - - it('should not detect Chrome on MacOS', () => { - const userAgent = - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 ' + - '(KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'; - expect(IE_REGEX.test(userAgent)).to.be(false); - }); - - it('should not detect Chrome on Windows', () => { - const userAgent = - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' + - '(KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'; - expect(IE_REGEX.test(userAgent)).to.be(false); - }); - - it('should not detect Safari on MacOS', () => { - const userAgent = - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 ' + - '(KHTML, like Gecko) Version/10.1.1 Safari/603.2.4'; - expect(IE_REGEX.test(userAgent)).to.be(false); - }); - - it('should not detect Firefox on MacOS', () => { - const userAgent = - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:46.0) Gecko/20100101 Firefox/46.0'; - expect(IE_REGEX.test(userAgent)).to.be(false); - }); - - it('should not detect Firefox on Windows', () => { - const userAgent = - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:46.0) Gecko/20100101 Firefox/46.0'; - expect(IE_REGEX.test(userAgent)).to.be(false); - }); -}); diff --git a/src/legacy/ui/public/error_url_overflow/_error_url_overflow.scss b/src/legacy/ui/public/error_url_overflow/_error_url_overflow.scss deleted file mode 100644 index df96d72521a5a..0000000000000 --- a/src/legacy/ui/public/error_url_overflow/_error_url_overflow.scss +++ /dev/null @@ -1,3 +0,0 @@ -.kbnError--url-overflow-app { - padding: $euiSizeL; -} diff --git a/src/legacy/ui/public/error_url_overflow/_index.scss b/src/legacy/ui/public/error_url_overflow/_index.scss deleted file mode 100644 index 15e2f77798268..0000000000000 --- a/src/legacy/ui/public/error_url_overflow/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import './error_url_overflow'; diff --git a/src/legacy/ui/public/error_url_overflow/error_url_overflow.html b/src/legacy/ui/public/error_url_overflow/error_url_overflow.html deleted file mode 100644 index 643c39ffed08d..0000000000000 --- a/src/legacy/ui/public/error_url_overflow/error_url_overflow.html +++ /dev/null @@ -1,55 +0,0 @@ -
-

- - - -

- -

- -

-

- -
    -
  1. -
  2. -
  3. -
-
-
-

- -

-
diff --git a/src/legacy/ui/public/error_url_overflow/error_url_overflow.js b/src/legacy/ui/public/error_url_overflow/error_url_overflow.js deleted file mode 100644 index 223b81fa36fde..0000000000000 --- a/src/legacy/ui/public/error_url_overflow/error_url_overflow.js +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { i18n } from '@kbn/i18n'; -import uiRoutes from '../routes'; -import { KbnUrlProvider } from '../url'; - -import template from './error_url_overflow.html'; -import { UrlOverflowService } from '../../../../plugins/kibana_legacy/public'; - -export { UrlOverflowService }; - -uiRoutes.when('/error/url-overflow', { - template, - k7Breadcrumbs: () => [ - { - text: i18n.translate('common.ui.errorUrlOverflow.breadcrumbs.errorText', { - defaultMessage: 'Error', - }), - }, - ], - controllerAs: 'controller', - controller: class OverflowController { - constructor(Private, $scope) { - const kbnUrl = Private(KbnUrlProvider); - const urlOverflow = new UrlOverflowService(); - - if (!urlOverflow.get()) { - kbnUrl.redirectPath('/'); - return; - } - - this.url = urlOverflow.get(); - this.limit = urlOverflow.failLength(); - this.advancedSettingsLabel = i18n.translate( - 'common.ui.errorUrlOverflow.howTofixError.enableOptionText.advancedSettingsLinkText', - { defaultMessage: 'advanced settings' } - ); - $scope.$on('$destroy', () => urlOverflow.clear()); - } - }, -}); diff --git a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js b/src/legacy/ui/public/new_platform/new_platform.karma_mock.js index 229bfb1978a4e..d98770842a0f0 100644 --- a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js +++ b/src/legacy/ui/public/new_platform/new_platform.karma_mock.js @@ -28,6 +28,11 @@ import { // eslint-disable-next-line @kbn/eslint/no-restricted-paths } from '../../../../../src/plugins/data/public/search/aggs'; import { ComponentRegistry } from '../../../../../src/plugins/advanced_settings/public/'; +import { UI_SETTINGS } from '../../../../../src/plugins/data/public/'; +import { + CSV_SEPARATOR_SETTING, + CSV_QUOTE_VALUES_SETTING, +} from '../../../../../src/plugins/share/public'; const mockObservable = () => { return { @@ -49,18 +54,31 @@ let isTimeRangeSelectorEnabled = true; let isAutoRefreshSelectorEnabled = true; export const mockUiSettings = { - get: (item) => { - return mockUiSettings[item]; + get: (item, defaultValue) => { + const defaultValues = { + dateFormat: 'MMM D, YYYY @ HH:mm:ss.SSS', + 'dateFormat:tz': 'UTC', + [UI_SETTINGS.SHORT_DOTS_ENABLE]: true, + [UI_SETTINGS.COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX]: true, + [UI_SETTINGS.QUERY_ALLOW_LEADING_WILDCARDS]: true, + [UI_SETTINGS.QUERY_STRING_OPTIONS]: {}, + [UI_SETTINGS.FORMAT_CURRENCY_DEFAULT_PATTERN]: '($0,0.[00])', + [UI_SETTINGS.FORMAT_NUMBER_DEFAULT_PATTERN]: '0,0.[000]', + [UI_SETTINGS.FORMAT_PERCENT_DEFAULT_PATTERN]: '0,0.[000]%', + [UI_SETTINGS.FORMAT_NUMBER_DEFAULT_LOCALE]: 'en', + [UI_SETTINGS.FORMAT_DEFAULT_TYPE_MAP]: {}, + [CSV_SEPARATOR_SETTING]: ',', + [CSV_QUOTE_VALUES_SETTING]: true, + [UI_SETTINGS.SEARCH_QUERY_LANGUAGE]: 'kuery', + 'state:storeInSessionStorage': false, + }; + + return defaultValues[item] || defaultValue; }, getUpdate$: () => ({ subscribe: sinon.fake(), }), isDefault: sinon.fake(), - 'query:allowLeadingWildcards': true, - 'query:queryString:options': {}, - 'courier:ignoreFilterIfFieldNotInIndex': true, - 'dateFormat:tz': 'Browser', - 'format:defaultTypeMap': {}, }; const mockCoreSetup = { @@ -236,6 +254,9 @@ export const npSetup = { }, share: { register: () => {}, + urlGenerators: { + registerUrlGenerator: () => {}, + }, }, devTools: { register: () => {}, @@ -524,6 +545,8 @@ export function __setup__(coreSetup) { // bootstrap an LP plugin outside of tests) npSetup.core.application.register = () => {}; + npSetup.core.uiSettings.get = mockUiSettings.get; + // Services that need to be set in the legacy platform since the legacy data // & vis plugins which previously provided them have been removed. setSetupServices(npSetup); @@ -532,6 +555,8 @@ export function __setup__(coreSetup) { export function __start__(coreStart) { npStart.core = coreStart; + npStart.core.uiSettings.get = mockUiSettings.get; + // Services that need to be set in the legacy platform since the legacy data // & vis plugins which previously provided them have been removed. setStartServices(npStart); diff --git a/src/legacy/ui/public/new_platform/set_services.ts b/src/legacy/ui/public/new_platform/set_services.ts index 9d02ad67b3937..ee92eda064aa8 100644 --- a/src/legacy/ui/public/new_platform/set_services.ts +++ b/src/legacy/ui/public/new_platform/set_services.ts @@ -65,6 +65,7 @@ export function setStartServices(npStart: NpStart) { visualizationsServices.setCapabilities(npStart.core.application.capabilities); visualizationsServices.setHttp(npStart.core.http); visualizationsServices.setApplication(npStart.core.application); + visualizationsServices.setEmbeddable(npStart.plugins.embeddable); visualizationsServices.setSavedObjects(npStart.core.savedObjects); visualizationsServices.setIndexPatterns(npStart.plugins.data.indexPatterns); visualizationsServices.setFilterManager(npStart.plugins.data.query.filterManager); diff --git a/src/legacy/ui/public/styles/_legacy/_base.scss b/src/legacy/ui/public/styles/_legacy/_base.scss index fd0a1335f9685..877ae033ae584 100644 --- a/src/legacy/ui/public/styles/_legacy/_base.scss +++ b/src/legacy/ui/public/styles/_legacy/_base.scss @@ -64,10 +64,6 @@ input[type='checkbox'], padding-bottom: $euiSizeS; } - .globalQueryBar { - padding: 0px $euiSizeS $euiSizeS $euiSizeS; - } - > nav, > navbar { z-index: 2 !important; diff --git a/src/legacy/ui/public/timefilter/setup_router.ts b/src/legacy/ui/public/timefilter/setup_router.ts index a7492e538b3af..7c25c6aa3166e 100644 --- a/src/legacy/ui/public/timefilter/setup_router.ts +++ b/src/legacy/ui/public/timefilter/setup_router.ts @@ -21,10 +21,15 @@ import _ from 'lodash'; import { IScope } from 'angular'; import moment from 'moment'; import chrome from 'ui/chrome'; -import { RefreshInterval, TimeRange, TimefilterContract } from 'src/plugins/data/public'; import { Subscription } from 'rxjs'; import { fatalError } from 'ui/notify/fatal_error'; import { subscribeWithScope } from '../../../../plugins/kibana_legacy/public'; +import { + RefreshInterval, + TimeRange, + TimefilterContract, + UI_SETTINGS, +} from '../../../../plugins/data/public'; // TODO // remove everything underneath once globalState is no longer an angular service @@ -38,7 +43,7 @@ export function getTimefilterConfig() { const settings = chrome.getUiSettingsClient(); return { timeDefaults: settings.get('timepicker:timeDefaults'), - refreshIntervalDefaults: settings.get('timepicker:refreshIntervalDefaults'), + refreshIntervalDefaults: settings.get(UI_SETTINGS.TIMEPICKER_REFRESH_INTERVAL_DEFAULTS), }; } diff --git a/src/plugins/advanced_settings/public/management_app/lib/get_category_name.ts b/src/plugins/advanced_settings/public/management_app/lib/get_category_name.ts index bf3ac9628754a..31df6875c97d9 100644 --- a/src/plugins/advanced_settings/public/management_app/lib/get_category_name.ts +++ b/src/plugins/advanced_settings/public/management_app/lib/get_category_name.ts @@ -46,8 +46,8 @@ const names: Record = { search: i18n.translate('advancedSettings.categoryNames.searchLabel', { defaultMessage: 'Search', }), - siem: i18n.translate('advancedSettings.categoryNames.siemLabel', { - defaultMessage: 'SIEM', + securitySolution: i18n.translate('advancedSettings.categoryNames.securitySolutionLabel', { + defaultMessage: 'Security Solution', }), }; diff --git a/src/plugins/charts/public/services/theme/theme.ts b/src/plugins/charts/public/services/theme/theme.ts index 166e1c539688a..e1e71573caa3a 100644 --- a/src/plugins/charts/public/services/theme/theme.ts +++ b/src/plugins/charts/public/services/theme/theme.ts @@ -42,8 +42,10 @@ export class ThemeService { /** A React hook for consuming the charts theme */ public useChartsTheme = () => { + /* eslint-disable-next-line react-hooks/rules-of-hooks */ const [value, update] = useState(this.chartsDefaultTheme); + /* eslint-disable-next-line react-hooks/rules-of-hooks */ useEffect(() => { const s = this.chartsTheme$.subscribe(update); return () => s.unsubscribe(); diff --git a/src/plugins/console/public/application/containers/editor/editor.tsx b/src/plugins/console/public/application/containers/editor/editor.tsx index 0bfe837f2cd90..66d3cbab20ac5 100644 --- a/src/plugins/console/public/application/containers/editor/editor.tsx +++ b/src/plugins/console/public/application/containers/editor/editor.tsx @@ -47,6 +47,7 @@ export const Editor = memo(({ loading }: Props) => { INITIAL_PANEL_WIDTH, ]); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const onPanelWidthChange = useCallback( debounce((widths: number[]) => { storage.set(StorageKeys.WIDTH, widths); diff --git a/src/plugins/console/public/application/hooks/use_save_current_text_object.ts b/src/plugins/console/public/application/hooks/use_save_current_text_object.ts index ab517ba1bfdd1..1bd1a7fb09bd1 100644 --- a/src/plugins/console/public/application/hooks/use_save_current_text_object.ts +++ b/src/plugins/console/public/application/hooks/use_save_current_text_object.ts @@ -32,6 +32,7 @@ export const useSaveCurrentTextObject = () => { const { currentTextObject } = useEditorReadContext(); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ return useCallback( throttle( (text: string) => { diff --git a/src/plugins/console/server/lib/spec_definitions/js/filter.ts b/src/plugins/console/server/lib/spec_definitions/js/filter.ts index 27e02f7cf1837..b5e99e610b8ba 100644 --- a/src/plugins/console/server/lib/spec_definitions/js/filter.ts +++ b/src/plugins/console/server/lib/spec_definitions/js/filter.ts @@ -58,13 +58,6 @@ filters.limit = { value: 100, }; -filters.type = { - __template: { - value: 'TYPE', - }, - value: '{type}', -}; - filters.geo_bounding_box = { __template: { FIELD: { diff --git a/src/plugins/dashboard/public/application/dashboard_app_controller.tsx b/src/plugins/dashboard/public/application/dashboard_app_controller.tsx index 8dd0a766da97b..206ef4f3d4313 100644 --- a/src/plugins/dashboard/public/application/dashboard_app_controller.tsx +++ b/src/plugins/dashboard/public/application/dashboard_app_controller.tsx @@ -19,8 +19,9 @@ import _, { uniq } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { EUI_MODAL_CANCEL_BUTTON } from '@elastic/eui'; -import React from 'react'; +import { EUI_MODAL_CANCEL_BUTTON, EuiCheckboxGroup } from '@elastic/eui'; +import { EuiCheckboxGroupIdToSelectedMap } from '@elastic/eui/src/components/form/checkbox/checkbox_group'; +import React, { useState, ReactElement } from 'react'; import ReactDOM from 'react-dom'; import angular from 'angular'; @@ -41,6 +42,7 @@ import { QueryState, SavedQuery, syncQueryStateWithUrl, + UI_SETTINGS, } from '../../../data/public'; import { getSavedObjectFinder, SaveResult, showSaveModal } from '../../../saved_objects/public'; @@ -93,6 +95,25 @@ export interface DashboardAppControllerDependencies extends RenderDeps { navigation: NavigationStart; } +enum UrlParams { + SHOW_TOP_MENU = 'show-top-menu', + SHOW_QUERY_INPUT = 'show-query-input', + SHOW_TIME_FILTER = 'show-time-filter', + SHOW_FILTER_BAR = 'show-filter-bar', + HIDE_FILTER_BAR = 'hide-filter-bar', +} + +interface UrlParamsSelectedMap { + [UrlParams.SHOW_TOP_MENU]: boolean; + [UrlParams.SHOW_QUERY_INPUT]: boolean; + [UrlParams.SHOW_TIME_FILTER]: boolean; + [UrlParams.SHOW_FILTER_BAR]: boolean; +} + +interface UrlParamValues extends Omit { + [UrlParams.HIDE_FILTER_BAR]: boolean; +} + export class DashboardAppController { // Part of the exposed plugin API - do not remove without careful consideration. appStatus: { @@ -132,8 +153,16 @@ export class DashboardAppController { const filterManager = queryService.filterManager; const queryFilter = filterManager; const timefilter = queryService.timefilter.timefilter; - let showSearchBar = true; - let showQueryBar = true; + const isEmbeddedExternally = Boolean($routeParams.embed); + + // url param rules should only apply when embedded (e.g. url?embed=true) + const shouldForceDisplay = (param: string): boolean => + isEmbeddedExternally && Boolean($routeParams[param]); + + const forceShowTopNavMenu = shouldForceDisplay(UrlParams.SHOW_TOP_MENU); + const forceShowQueryInput = shouldForceDisplay(UrlParams.SHOW_QUERY_INPUT); + const forceShowDatePicker = shouldForceDisplay(UrlParams.SHOW_TIME_FILTER); + const forceHideFilterBar = shouldForceDisplay(UrlParams.HIDE_FILTER_BAR); let lastReloadRequestTime = 0; const dash = ($scope.dash = $route.current.locals.dash); @@ -250,9 +279,6 @@ export class DashboardAppController { } }; - const showFilterBar = () => - $scope.model.filters.length > 0 || !dashboardStateManager.getFullScreenMode(); - const getEmptyScreenProps = ( shouldShowEditHelp: boolean, isEmptyInReadOnlyMode: boolean @@ -298,6 +324,7 @@ export class DashboardAppController { viewMode: dashboardStateManager.getViewMode(), panels: embeddablesMap, isFullScreenMode: dashboardStateManager.getFullScreenMode(), + isEmbeddedExternally, isEmptyState: shouldShowEditHelp || shouldShowViewHelp || isEmptyInReadonlyMode, useMargins: dashboardStateManager.getUseMargins(), lastReloadRequestTime, @@ -430,7 +457,8 @@ export class DashboardAppController { dashboardStateManager.getQuery() || { query: '', language: - localStorage.get('kibana.userQueryLanguage') || uiSettings.get('search:queryLanguage'), + localStorage.get('kibana.userQueryLanguage') || + uiSettings.get(UI_SETTINGS.SEARCH_QUERY_LANGUAGE), }, queryFilter.getFilters() ); @@ -588,17 +616,33 @@ export class DashboardAppController { dashboardStateManager.setSavedQueryId(savedQueryId); }; + const shouldShowFilterBar = (forceHide: boolean): boolean => + !forceHide && ($scope.model.filters.length > 0 || !dashboardStateManager.getFullScreenMode()); + + const shouldShowNavBarComponent = (forceShow: boolean): boolean => + (forceShow || $scope.isVisible) && !dashboardStateManager.getFullScreenMode(); + const getNavBarProps = () => { const isFullScreenMode = dashboardStateManager.getFullScreenMode(); const screenTitle = dashboardStateManager.getTitle(); + const showTopNavMenu = shouldShowNavBarComponent(forceShowTopNavMenu); + const showQueryInput = shouldShowNavBarComponent(forceShowQueryInput); + const showDatePicker = shouldShowNavBarComponent(forceShowDatePicker); + const showQueryBar = showQueryInput || showDatePicker; + const showFilterBar = shouldShowFilterBar(forceHideFilterBar); + const showSearchBar = showQueryBar || showFilterBar; + return { appName: 'dashboard', - config: $scope.isVisible ? $scope.topNavMenu : undefined, + config: showTopNavMenu ? $scope.topNavMenu : undefined, className: isFullScreenMode ? 'kbnTopNavMenu-isFullScreen' : undefined, screenTitle, + showTopNavMenu, showSearchBar, showQueryBar, - showFilterBar: showFilterBar(), + showQueryInput, + showDatePicker, + showFilterBar, indexPatterns: $scope.indexPatterns, showSaveQuery: $scope.showSaveQuery, query: $scope.model.query, @@ -796,7 +840,6 @@ export class DashboardAppController { } = {}; navActions[TopNavIds.FULL_SCREEN] = () => { dashboardStateManager.setFullScreenMode(true); - showQueryBar = false; updateNavBar(); }; navActions[TopNavIds.EXIT_EDIT_MODE] = () => onChangeViewMode(ViewMode.VIEW); @@ -921,6 +964,80 @@ export class DashboardAppController { if (share) { // the share button is only availabale if "share" plugin contract enabled navActions[TopNavIds.SHARE] = (anchorElement) => { + const EmbedUrlParamExtension = ({ + setParamValue, + }: { + setParamValue: (paramUpdate: UrlParamValues) => void; + }): ReactElement => { + const [urlParamsSelectedMap, setUrlParamsSelectedMap] = useState({ + [UrlParams.SHOW_TOP_MENU]: false, + [UrlParams.SHOW_QUERY_INPUT]: false, + [UrlParams.SHOW_TIME_FILTER]: false, + [UrlParams.SHOW_FILTER_BAR]: true, + }); + + const checkboxes = [ + { + id: UrlParams.SHOW_TOP_MENU, + label: i18n.translate('dashboard.embedUrlParamExtension.topMenu', { + defaultMessage: 'Top menu', + }), + }, + { + id: UrlParams.SHOW_QUERY_INPUT, + label: i18n.translate('dashboard.embedUrlParamExtension.query', { + defaultMessage: 'Query', + }), + }, + { + id: UrlParams.SHOW_TIME_FILTER, + label: i18n.translate('dashboard.embedUrlParamExtension.timeFilter', { + defaultMessage: 'Time filter', + }), + }, + { + id: UrlParams.SHOW_FILTER_BAR, + label: i18n.translate('dashboard.embedUrlParamExtension.filterBar', { + defaultMessage: 'Filter bar', + }), + }, + ]; + + const handleChange = (param: string): void => { + const urlParamsSelectedMapUpdate = { + ...urlParamsSelectedMap, + [param]: !urlParamsSelectedMap[param as keyof UrlParamsSelectedMap], + }; + setUrlParamsSelectedMap(urlParamsSelectedMapUpdate); + + const urlParamValues = { + [UrlParams.SHOW_TOP_MENU]: urlParamsSelectedMap[UrlParams.SHOW_TOP_MENU], + [UrlParams.SHOW_QUERY_INPUT]: urlParamsSelectedMap[UrlParams.SHOW_QUERY_INPUT], + [UrlParams.SHOW_TIME_FILTER]: urlParamsSelectedMap[UrlParams.SHOW_TIME_FILTER], + [UrlParams.HIDE_FILTER_BAR]: !urlParamsSelectedMap[UrlParams.SHOW_FILTER_BAR], + [param === UrlParams.SHOW_FILTER_BAR ? UrlParams.HIDE_FILTER_BAR : param]: + param === UrlParams.SHOW_FILTER_BAR + ? urlParamsSelectedMap[UrlParams.SHOW_FILTER_BAR] + : !urlParamsSelectedMap[param as keyof UrlParamsSelectedMap], + }; + setParamValue(urlParamValues); + }; + + return ( + + ); + }; + share.toggleShareContextMenu({ anchorElement, allowEmbed: true, @@ -933,6 +1050,12 @@ export class DashboardAppController { title: dash.title, }, isDirty: dashboardStateManager.getIsDirty(), + embedUrlParamExtensions: [ + { + paramName: 'embed', + component: EmbedUrlParamExtension, + }, + ], }); }; } @@ -953,8 +1076,6 @@ export class DashboardAppController { const visibleSubscription = chrome.getIsVisible$().subscribe((isVisible) => { $scope.$evalAsync(() => { $scope.isVisible = isVisible; - showSearchBar = isVisible || showFilterBar(); - showQueryBar = !dashboardStateManager.getFullScreenMode() && isVisible; updateNavBar(); }); }); diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx index 7e25d80c9d619..2121ca4c784bd 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx @@ -57,6 +57,7 @@ export interface DashboardContainerInput extends ContainerInput { useMargins: boolean; title: string; description?: string; + isEmbeddedExternally: boolean; isFullScreenMode: boolean; panels: { [panelId: string]: DashboardPanelState; @@ -105,6 +106,7 @@ export class DashboardContainer extends Container - + , dom diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container_factory.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container_factory.tsx index a20ba148115a0..22e18ddbf22d5 100644 --- a/src/plugins/dashboard/public/application/embeddable/dashboard_container_factory.tsx +++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container_factory.tsx @@ -65,6 +65,7 @@ export class DashboardContainerFactory public getDefaultInput(): Partial { return { panels: {}, + isEmbeddedExternally: false, isFullScreenMode: false, useMargins: true, }; diff --git a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx index 9b7cec2f182ba..9a2610a82b97d 100644 --- a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx +++ b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx @@ -80,6 +80,7 @@ function prepare(props?: Partial) { dashboardContainer = new DashboardContainer(initialInput, options); const defaultTestProps: DashboardGridProps = { container: dashboardContainer, + PanelComponent: () =>
, kibana: null as any, intl: null as any, }; diff --git a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx index 19d9ad34e729c..dcd07fe394c7d 100644 --- a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx +++ b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx @@ -30,7 +30,7 @@ import React from 'react'; import { Subscription } from 'rxjs'; import ReactGridLayout, { Layout } from 'react-grid-layout'; import { GridData } from '../../../../common'; -import { ViewMode, EmbeddableChildPanel } from '../../../embeddable_plugin'; +import { ViewMode, EmbeddableChildPanel, EmbeddableStart } from '../../../embeddable_plugin'; import { DASHBOARD_GRID_COLUMN_COUNT, DASHBOARD_GRID_HEIGHT } from '../dashboard_constants'; import { DashboardPanelState } from '../types'; import { withKibana } from '../../../../../kibana_react/public'; @@ -115,6 +115,7 @@ const ResponsiveSizedGrid = sizeMe(config)(ResponsiveGrid); export interface DashboardGridProps extends ReactIntl.InjectedIntlProps { kibana: DashboardReactContextValue; + PanelComponent: EmbeddableStart['EmbeddablePanel']; container: DashboardContainer; } @@ -271,14 +272,7 @@ class DashboardGridUi extends React.Component {
); diff --git a/src/plugins/dashboard/public/application/embeddable/panel/dashboard_panel_placement.ts b/src/plugins/dashboard/public/application/embeddable/panel/dashboard_panel_placement.ts index 62a39ee898d3a..1b060c186db97 100644 --- a/src/plugins/dashboard/public/application/embeddable/panel/dashboard_panel_placement.ts +++ b/src/plugins/dashboard/public/application/embeddable/panel/dashboard_panel_placement.ts @@ -108,16 +108,32 @@ interface IplacementDirection { fits: boolean; } +/** + * Compare grid data by an ending y coordinate. Grid data with a smaller ending y coordinate + * comes first. + * @param a + * @param b + */ +function comparePanels(a: GridData, b: GridData): number { + if (a.y + a.h < b.y + b.h) { + return -1; + } + if (a.y + a.h > b.y + b.h) { + return 1; + } + // a.y === b.y + if (a.x + a.w <= b.x + b.w) { + return -1; + } + return 1; +} + export function placePanelBeside({ width, height, currentPanels, placeBesideId, }: IPanelPlacementBesideArgs): Omit { - // const clonedPanels = _.cloneDeep(currentPanels); - if (!placeBesideId) { - throw new Error('Place beside method called without placeBesideId'); - } const panelToPlaceBeside = currentPanels[placeBesideId]; if (!panelToPlaceBeside) { throw new PanelNotFoundError(); @@ -130,10 +146,11 @@ export function placePanelBeside({ const possiblePlacementDirections: IplacementDirection[] = [ { grid: { x: beside.x + beside.w, y: beside.y, w: width, h: height }, fits: true }, // right - { grid: { x: beside.x - width, y: beside.y, w: width, h: height }, fits: true }, // left + { grid: { x: 0, y: beside.y + beside.h, w: width, h: height }, fits: true }, // left side of next row { grid: { x: beside.x, y: beside.y + beside.h, w: width, h: height }, fits: true }, // bottom ]; + // first, we check if there is place around the current panel for (const direction of possiblePlacementDirections) { if ( direction.grid.x >= 0 && @@ -156,13 +173,32 @@ export function placePanelBeside({ } } // if we get here that means there is no blank space around the panel we are placing beside. This means it's time to mess up the dashboard's groove. Fun! - const [, , bottomPlacement] = possiblePlacementDirections; - for (const currentPanelGrid of otherPanels) { - if (bottomPlacement.grid.y <= currentPanelGrid.y) { - const movedPanel = _.cloneDeep(currentPanels[currentPanelGrid.i]); - movedPanel.gridData.y = movedPanel.gridData.y + bottomPlacement.grid.h; - currentPanels[currentPanelGrid.i] = movedPanel; + /** + * 1. sort the panels in the grid + * 2. place the cloned panel to the bottom + * 3. reposition the panels after the cloned panel in the grid + */ + const grid = otherPanels.sort(comparePanels); + + let position = 0; + for (position; position < grid.length; position++) { + if (beside.i === grid[position].i) { + break; } } + const bottomPlacement = possiblePlacementDirections[2]; + // place to the bottom and move all other panels + let originalPositionInTheGrid = grid[position + 1].i; + const diff = + bottomPlacement.grid.y + + bottomPlacement.grid.h - + currentPanels[originalPositionInTheGrid].gridData.y; + + for (let j = position + 1; j < grid.length; j++) { + originalPositionInTheGrid = grid[j].i; + const movedPanel = _.cloneDeep(currentPanels[originalPositionInTheGrid]); + movedPanel.gridData.y = movedPanel.gridData.y + diff; + currentPanels[originalPositionInTheGrid] = movedPanel; + } return bottomPlacement.grid; } diff --git a/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx b/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx index 1b257880b9401..25e451dc7f793 100644 --- a/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx +++ b/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx @@ -87,6 +87,7 @@ function getProps( dashboardContainer = new DashboardContainer(input, options); const defaultTestProps: DashboardViewportProps = { container: dashboardContainer, + PanelComponent: () =>
, }; return { diff --git a/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.tsx b/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.tsx index ae239bc27fdba..9ee50426b19bb 100644 --- a/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.tsx +++ b/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.tsx @@ -19,7 +19,7 @@ import React from 'react'; import { Subscription } from 'rxjs'; -import { PanelState } from '../../../embeddable_plugin'; +import { PanelState, EmbeddableStart } from '../../../embeddable_plugin'; import { DashboardContainer, DashboardReactContextValue } from '../dashboard_container'; import { DashboardGrid } from '../grid'; import { context } from '../../../../../kibana_react/public'; @@ -27,6 +27,7 @@ import { context } from '../../../../../kibana_react/public'; export interface DashboardViewportProps { container: DashboardContainer; renderEmpty?: () => React.ReactNode; + PanelComponent: EmbeddableStart['EmbeddablePanel']; } interface State { @@ -35,6 +36,7 @@ interface State { title: string; description?: string; panels: { [key: string]: PanelState }; + isEmbeddedExternally?: boolean; isEmptyState?: boolean; } @@ -51,6 +53,7 @@ export class DashboardViewport extends React.Component {isFullScreenMode && ( )} {renderEmpty && renderEmpty()} @@ -114,8 +121,15 @@ export class DashboardViewport extends React.Component )} - +
); } diff --git a/src/plugins/dashboard/public/application/test_helpers/get_sample_dashboard_input.ts b/src/plugins/dashboard/public/application/test_helpers/get_sample_dashboard_input.ts index 4ceac90672cb3..825a69155ba22 100644 --- a/src/plugins/dashboard/public/application/test_helpers/get_sample_dashboard_input.ts +++ b/src/plugins/dashboard/public/application/test_helpers/get_sample_dashboard_input.ts @@ -27,6 +27,7 @@ export function getSampleDashboardInput( id: '123', filters: [], useMargins: false, + isEmbeddedExternally: false, isFullScreenMode: false, title: 'My Dashboard', query: { diff --git a/src/plugins/dashboard/public/plugin.tsx b/src/plugins/dashboard/public/plugin.tsx index 0de3982039928..a3338ab3bbcbb 100644 --- a/src/plugins/dashboard/public/plugin.tsx +++ b/src/plugins/dashboard/public/plugin.tsx @@ -167,15 +167,26 @@ export class DashboardPlugin const getStartServices = async () => { const [coreStart, deps] = await core.getStartServices(); - const useHideChrome = () => { + const useHideChrome = ({ toggleChrome } = { toggleChrome: true }) => { React.useEffect(() => { - coreStart.chrome.setIsVisible(false); - return () => coreStart.chrome.setIsVisible(true); - }, []); + if (toggleChrome) { + coreStart.chrome.setIsVisible(false); + } + + return () => { + if (toggleChrome) { + coreStart.chrome.setIsVisible(true); + } + }; + }, [toggleChrome]); }; - const ExitFullScreenButton: React.FC = (props) => { - useHideChrome(); + const ExitFullScreenButton: React.FC< + ExitFullScreenButtonProps & { + toggleChrome: boolean; + } + > = ({ toggleChrome, ...props }) => { + useHideChrome({ toggleChrome }); return ; }; return { diff --git a/src/plugins/data/common/constants.ts b/src/plugins/data/common/constants.ts index 66a96e3e6e129..8ec72dc1f9a74 100644 --- a/src/plugins/data/common/constants.ts +++ b/src/plugins/data/common/constants.ts @@ -18,5 +18,33 @@ */ export const DEFAULT_QUERY_LANGUAGE = 'kuery'; -export const META_FIELDS_SETTING = 'metaFields'; -export const DOC_HIGHLIGHT_SETTING = 'doc_table:highlight'; + +export const UI_SETTINGS = { + META_FIELDS: 'metaFields', + DOC_HIGHLIGHT: 'doc_table:highlight', + QUERY_STRING_OPTIONS: 'query:queryString:options', + QUERY_ALLOW_LEADING_WILDCARDS: 'query:allowLeadingWildcards', + SEARCH_QUERY_LANGUAGE: 'search:queryLanguage', + SORT_OPTIONS: 'sort:options', + COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX: 'courier:ignoreFilterIfFieldNotInIndex', + COURIER_SET_REQUEST_PREFERENCE: 'courier:setRequestPreference', + COURIER_CUSTOM_REQUEST_PREFERENCE: 'courier:customRequestPreference', + COURIER_MAX_CONCURRENT_SHARD_REQUESTS: 'courier:maxConcurrentShardRequests', + COURIER_BATCH_SEARCHES: 'courier:batchSearches', + SEARCH_INCLUDE_FROZEN: 'search:includeFrozen', + HISTOGRAM_BAR_TARGET: 'histogram:barTarget', + HISTOGRAM_MAX_BARS: 'histogram:maxBars', + HISTORY_LIMIT: 'history:limit', + SHORT_DOTS_ENABLE: 'shortDots:enable', + FORMAT_DEFAULT_TYPE_MAP: 'format:defaultTypeMap', + FORMAT_NUMBER_DEFAULT_PATTERN: 'format:number:defaultPattern', + FORMAT_PERCENT_DEFAULT_PATTERN: 'format:percent:defaultPattern', + FORMAT_BYTES_DEFAULT_PATTERN: 'format:bytes:defaultPattern', + FORMAT_CURRENCY_DEFAULT_PATTERN: 'format:currency:defaultPattern', + FORMAT_NUMBER_DEFAULT_LOCALE: 'format:number:defaultLocale', + TIMEPICKER_REFRESH_INTERVAL_DEFAULTS: 'timepicker:refreshIntervalDefaults', + TIMEPICKER_QUICK_RANGES: 'timepicker:quickRanges', + INDEXPATTERN_PLACEHOLDER: 'indexPattern:placeholder', + FILTERS_PINNED_BY_DEFAULT: 'filters:pinnedByDefault', + FILTERS_EDITOR_SUGGEST_VALUES: 'filterEditor:suggestValues', +}; diff --git a/src/plugins/data/common/es_query/es_query/get_es_query_config.test.ts b/src/plugins/data/common/es_query/es_query/get_es_query_config.test.ts index d146d81973d0d..5fa3c67dea400 100644 --- a/src/plugins/data/common/es_query/es_query/get_es_query_config.test.ts +++ b/src/plugins/data/common/es_query/es_query/get_es_query_config.test.ts @@ -19,18 +19,19 @@ import { get } from 'lodash'; import { getEsQueryConfig } from './get_es_query_config'; import { IUiSettingsClient } from 'kibana/public'; +import { UI_SETTINGS } from '../../'; const config = ({ get(item: string) { return get(config, item); }, - 'query:allowLeadingWildcards': { + [UI_SETTINGS.QUERY_ALLOW_LEADING_WILDCARDS]: { allowLeadingWildcards: true, }, - 'query:queryString:options': { + [UI_SETTINGS.QUERY_STRING_OPTIONS]: { queryStringOptions: {}, }, - 'courier:ignoreFilterIfFieldNotInIndex': { + [UI_SETTINGS.COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX]: { ignoreFilterIfFieldNotInIndex: true, }, 'dateFormat:tz': { diff --git a/src/plugins/data/common/es_query/es_query/get_es_query_config.ts b/src/plugins/data/common/es_query/es_query/get_es_query_config.ts index 0a82cf03bdb44..ff8fc5b11b26e 100644 --- a/src/plugins/data/common/es_query/es_query/get_es_query_config.ts +++ b/src/plugins/data/common/es_query/es_query/get_es_query_config.ts @@ -18,15 +18,18 @@ */ import { EsQueryConfig } from './build_es_query'; +import { UI_SETTINGS } from '../../'; interface KibanaConfig { get(key: string): T; } export function getEsQueryConfig(config: KibanaConfig) { - const allowLeadingWildcards = config.get('query:allowLeadingWildcards'); - const queryStringOptions = config.get('query:queryString:options'); - const ignoreFilterIfFieldNotInIndex = config.get('courier:ignoreFilterIfFieldNotInIndex'); + const allowLeadingWildcards = config.get(UI_SETTINGS.QUERY_ALLOW_LEADING_WILDCARDS); + const queryStringOptions = config.get(UI_SETTINGS.QUERY_STRING_OPTIONS); + const ignoreFilterIfFieldNotInIndex = config.get( + UI_SETTINGS.COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX + ); const dateFormatTZ = config.get('dateFormat:tz'); return { diff --git a/src/plugins/data/common/field_formats/converters/bytes.test.ts b/src/plugins/data/common/field_formats/converters/bytes.test.ts index 8dad9fc206e72..e0c26170c2907 100644 --- a/src/plugins/data/common/field_formats/converters/bytes.test.ts +++ b/src/plugins/data/common/field_formats/converters/bytes.test.ts @@ -18,11 +18,12 @@ */ import { BytesFormat } from './bytes'; +import { UI_SETTINGS } from '../../constants'; describe('BytesFormat', () => { const config: Record = {}; - config['format:bytes:defaultPattern'] = '0,0.[000]b'; + config[UI_SETTINGS.FORMAT_BYTES_DEFAULT_PATTERN] = '0,0.[000]b'; const getConfig = (key: string) => config[key]; diff --git a/src/plugins/data/common/field_formats/converters/number.test.ts b/src/plugins/data/common/field_formats/converters/number.test.ts index fe36d5b12e873..31c5ea41bf5af 100644 --- a/src/plugins/data/common/field_formats/converters/number.test.ts +++ b/src/plugins/data/common/field_formats/converters/number.test.ts @@ -18,11 +18,12 @@ */ import { NumberFormat } from './number'; +import { UI_SETTINGS } from '../../constants'; describe('NumberFormat', () => { const config: Record = {}; - config['format:number:defaultPattern'] = '0,0.[000]'; + config[UI_SETTINGS.FORMAT_NUMBER_DEFAULT_PATTERN] = '0,0.[000]'; const getConfig = (key: string) => config[key]; diff --git a/src/plugins/data/common/field_formats/converters/numeral.ts b/src/plugins/data/common/field_formats/converters/numeral.ts index a483b5a1e4f99..1d844bca3f89a 100644 --- a/src/plugins/data/common/field_formats/converters/numeral.ts +++ b/src/plugins/data/common/field_formats/converters/numeral.ts @@ -24,6 +24,7 @@ import numeralLanguages from '@elastic/numeral/languages'; import { KBN_FIELD_TYPES } from '../../kbn_field_types/types'; import { FieldFormat } from '../field_format'; import { TextContextTypeConvert } from '../types'; +import { UI_SETTINGS } from '../../constants'; const numeralInst = numeral(); @@ -51,7 +52,8 @@ export abstract class NumeralFormat extends FieldFormat { if (isNaN(val)) return ''; const previousLocale = numeral.language(); - const defaultLocale = (this.getConfig && this.getConfig('format:number:defaultLocale')) || 'en'; + const defaultLocale = + (this.getConfig && this.getConfig(UI_SETTINGS.FORMAT_NUMBER_DEFAULT_LOCALE)) || 'en'; numeral.language(defaultLocale); const formatted = numeralInst.set(val).format(this.param('pattern')); diff --git a/src/plugins/data/common/field_formats/converters/percent.test.ts b/src/plugins/data/common/field_formats/converters/percent.test.ts index 8b26564814af3..754234bdeb78b 100644 --- a/src/plugins/data/common/field_formats/converters/percent.test.ts +++ b/src/plugins/data/common/field_formats/converters/percent.test.ts @@ -18,11 +18,12 @@ */ import { PercentFormat } from './percent'; +import { UI_SETTINGS } from '../../constants'; describe('PercentFormat', () => { const config: Record = {}; - config['format:percent:defaultPattern'] = '0,0.[000]%'; + config[UI_SETTINGS.FORMAT_PERCENT_DEFAULT_PATTERN] = '0,0.[000]%'; const getConfig = (key: string) => config[key]; diff --git a/src/plugins/data/common/field_formats/converters/percent.ts b/src/plugins/data/common/field_formats/converters/percent.ts index ef3b0a1503a98..ecf9c7d19108d 100644 --- a/src/plugins/data/common/field_formats/converters/percent.ts +++ b/src/plugins/data/common/field_formats/converters/percent.ts @@ -20,6 +20,7 @@ import { i18n } from '@kbn/i18n'; import { NumeralFormat } from './numeral'; import { TextContextTypeConvert, FIELD_FORMAT_IDS } from '../types'; +import { UI_SETTINGS } from '../../constants'; export class PercentFormat extends NumeralFormat { static id = FIELD_FORMAT_IDS.PERCENT; @@ -32,7 +33,7 @@ export class PercentFormat extends NumeralFormat { allowsNumericalAggregations = true; getParamDefaults = () => ({ - pattern: this.getConfig!('format:percent:defaultPattern'), + pattern: this.getConfig!(UI_SETTINGS.FORMAT_PERCENT_DEFAULT_PATTERN), fractional: true, }); diff --git a/src/plugins/data/common/field_formats/converters/source.ts b/src/plugins/data/common/field_formats/converters/source.ts index 9e50d47bb2624..f00261e00971a 100644 --- a/src/plugins/data/common/field_formats/converters/source.ts +++ b/src/plugins/data/common/field_formats/converters/source.ts @@ -22,6 +22,7 @@ import { shortenDottedString } from '../../utils'; import { KBN_FIELD_TYPES } from '../../kbn_field_types/types'; import { FieldFormat } from '../field_format'; import { TextContextTypeConvert, HtmlContextTypeConvert, FIELD_FORMAT_IDS } from '../types'; +import { UI_SETTINGS } from '../../'; /** * Remove all of the whitespace between html tags @@ -71,7 +72,7 @@ export class SourceFormat extends FieldFormat { const formatted = field.indexPattern.formatHit(hit); const highlightPairs: any[] = []; const sourcePairs: any[] = []; - const isShortDots = this.getConfig!('shortDots:enable'); + const isShortDots = this.getConfig!(UI_SETTINGS.SHORT_DOTS_ENABLE); keys(formatted).forEach((key) => { const pairs = highlights[key] ? highlightPairs : sourcePairs; diff --git a/src/plugins/data/common/field_formats/field_formats_registry.ts b/src/plugins/data/common/field_formats/field_formats_registry.ts index c04a371066de3..9325485bce75d 100644 --- a/src/plugins/data/common/field_formats/field_formats_registry.ts +++ b/src/plugins/data/common/field_formats/field_formats_registry.ts @@ -33,6 +33,7 @@ import { baseFormatters } from './constants/base_formatters'; import { FieldFormat } from './field_format'; import { SerializedFieldFormat } from '../../../expressions/common/types'; import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../types'; +import { UI_SETTINGS } from '../'; export class FieldFormatsRegistry { protected fieldFormats: Map = new Map(); @@ -49,7 +50,7 @@ export class FieldFormatsRegistry { metaParamsOptions: Record = {}, defaultFieldConverters: FieldFormatInstanceType[] = baseFormatters ) { - const defaultTypeMap = getConfig('format:defaultTypeMap'); + const defaultTypeMap = getConfig(UI_SETTINGS.FORMAT_DEFAULT_TYPE_MAP); this.register(defaultFieldConverters); this.parseDefaultTypeMap(defaultTypeMap); this.getConfig = getConfig; diff --git a/src/plugins/data/config.ts b/src/plugins/data/config.ts new file mode 100644 index 0000000000000..09cb2cb2afeca --- /dev/null +++ b/src/plugins/data/config.ts @@ -0,0 +1,33 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; + +export const configSchema = schema.object({ + autocomplete: schema.object({ + querySuggestions: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + valueSuggestions: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), + }), +}); + +export type ConfigSchema = TypeOf; diff --git a/src/plugins/data/public/autocomplete/autocomplete_service.ts b/src/plugins/data/public/autocomplete/autocomplete_service.ts index cf248adea0b05..2136a405baad6 100644 --- a/src/plugins/data/public/autocomplete/autocomplete_service.ts +++ b/src/plugins/data/public/autocomplete/autocomplete_service.ts @@ -17,19 +17,30 @@ * under the License. */ -import { CoreSetup } from 'src/core/public'; +import { CoreSetup, PluginInitializerContext } from 'src/core/public'; import { QuerySuggestionGetFn } from './providers/query_suggestion_provider'; import { + getEmptyValueSuggestions, setupValueSuggestionProvider, ValueSuggestionsGetFn, } from './providers/value_suggestion_provider'; +import { ConfigSchema } from '../../config'; + export class AutocompleteService { + autocompleteConfig: ConfigSchema['autocomplete']; + + constructor(initializerContext: PluginInitializerContext) { + const { autocomplete } = initializerContext.config.get(); + + this.autocompleteConfig = autocomplete; + } + private readonly querySuggestionProviders: Map = new Map(); private getValueSuggestions?: ValueSuggestionsGetFn; private addQuerySuggestionProvider = (language: string, provider: QuerySuggestionGetFn): void => { - if (language && provider) { + if (language && provider && this.autocompleteConfig.querySuggestions.enabled) { this.querySuggestionProviders.set(language, provider); } }; @@ -47,7 +58,9 @@ export class AutocompleteService { /** @public **/ public setup(core: CoreSetup) { - this.getValueSuggestions = setupValueSuggestionProvider(core); + this.getValueSuggestions = this.autocompleteConfig.valueSuggestions.enabled + ? setupValueSuggestionProvider(core) + : getEmptyValueSuggestions; return { addQuerySuggestionProvider: this.addQuerySuggestionProvider, diff --git a/src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts b/src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts index 5df88000edbd5..a6a45a26f06b3 100644 --- a/src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts +++ b/src/plugins/data/public/autocomplete/providers/value_suggestion_provider.ts @@ -19,7 +19,7 @@ import { memoize } from 'lodash'; import { CoreSetup } from 'src/core/public'; -import { IIndexPattern, IFieldType } from '../../../common'; +import { IIndexPattern, IFieldType, UI_SETTINGS } from '../../../common'; function resolver(title: string, field: IFieldType, query: string, boolFilter: any) { // Only cache results for a minute @@ -38,6 +38,8 @@ interface ValueSuggestionsGetFnArgs { signal?: AbortSignal; } +export const getEmptyValueSuggestions = (() => Promise.resolve([])) as ValueSuggestionsGetFn; + export const setupValueSuggestionProvider = (core: CoreSetup): ValueSuggestionsGetFn => { const requestSuggestions = memoize( (index: string, field: IFieldType, query: string, boolFilter: any = [], signal?: AbortSignal) => @@ -56,7 +58,9 @@ export const setupValueSuggestionProvider = (core: CoreSetup): ValueSuggestionsG boolFilter, signal, }: ValueSuggestionsGetFnArgs): Promise => { - const shouldSuggestValues = core!.uiSettings.get('filterEditor:suggestValues'); + const shouldSuggestValues = core!.uiSettings.get( + UI_SETTINGS.FILTERS_EDITOR_SUGGEST_VALUES + ); const { title } = indexPattern; if (field.type === 'boolean') { diff --git a/src/plugins/data/public/field_formats/field_formats_service.ts b/src/plugins/data/public/field_formats/field_formats_service.ts index 22c7e90c06130..3ddc8d0b68a5b 100644 --- a/src/plugins/data/public/field_formats/field_formats_service.ts +++ b/src/plugins/data/public/field_formats/field_formats_service.ts @@ -18,7 +18,7 @@ */ import { CoreSetup } from 'src/core/public'; -import { FieldFormatsRegistry } from '../../common'; +import { FieldFormatsRegistry, UI_SETTINGS } from '../../common'; import { deserializeFieldFormat } from './utils/deserialize'; import { FormatFactory } from '../../common/field_formats/utils'; import { baseFormattersPublic } from './constants'; @@ -28,7 +28,7 @@ export class FieldFormatsService { public setup(core: CoreSetup) { core.uiSettings.getUpdate$().subscribe(({ key, newValue }) => { - if (key === 'format:defaultTypeMap') { + if (key === UI_SETTINGS.FORMAT_DEFAULT_TYPE_MAP) { this.fieldFormatsRegistry.parseDefaultTypeMap(newValue); } }); diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index 4a5b3fd5714db..eb3f937a4168b 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -17,9 +17,8 @@ * under the License. */ -import './index.scss'; - import { PluginInitializerContext } from '../../../core/public'; +import { ConfigSchema } from '../config'; /* * Filters: @@ -266,6 +265,7 @@ export { ES_FIELD_TYPES, KBN_FIELD_TYPES, IndexPatternAttributes, + UI_SETTINGS, } from '../common'; /* @@ -341,8 +341,6 @@ export { SYNC_SEARCH_STRATEGY, getEsPreference, getSearchErrorType, - ISearchContext, - TSearchStrategyProvider, ISearchStrategy, ISearch, ISearchOptions, @@ -450,7 +448,7 @@ export { import { DataPublicPlugin } from './plugin'; -export function plugin(initializerContext: PluginInitializerContext) { +export function plugin(initializerContext: PluginInitializerContext) { return new DataPublicPlugin(initializerContext); } diff --git a/src/plugins/data/public/index_patterns/index_patterns/_pattern_cache.ts b/src/plugins/data/public/index_patterns/index_patterns/_pattern_cache.ts index eb6c69b414316..a3653bb529fa3 100644 --- a/src/plugins/data/public/index_patterns/index_patterns/_pattern_cache.ts +++ b/src/plugins/data/public/index_patterns/index_patterns/_pattern_cache.ts @@ -19,7 +19,7 @@ import { IndexPattern } from './index_pattern'; -interface PatternCache { +export interface PatternCache { get: (id: string) => IndexPattern; set: (id: string, value: IndexPattern) => IndexPattern; clear: (id: string) => void; diff --git a/src/plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts b/src/plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts index e4058007e0a57..84135bb5d1e2b 100644 --- a/src/plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts +++ b/src/plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts @@ -85,6 +85,9 @@ const savedObjectsClient = { const patternCache = { clear: jest.fn(), + get: jest.fn(), + set: jest.fn(), + clearAll: jest.fn(), }; const config = { diff --git a/src/plugins/data/public/index_patterns/index_patterns/index_pattern.ts b/src/plugins/data/public/index_patterns/index_patterns/index_pattern.ts index 43404c32cb3d4..84ea12a1f684f 100644 --- a/src/plugins/data/public/index_patterns/index_patterns/index_pattern.ts +++ b/src/plugins/data/public/index_patterns/index_patterns/index_pattern.ts @@ -33,7 +33,7 @@ import { KBN_FIELD_TYPES, IIndexPattern, IFieldType, - META_FIELDS_SETTING, + UI_SETTINGS, } from '../../../common'; import { findByTitle } from '../utils'; import { IndexPatternMissingIndices } from '../lib'; @@ -44,6 +44,7 @@ import { flattenHitWrapper } from './flatten_hit'; import { IIndexPatternsApiClient } from './index_patterns_api_client'; import { getNotifications, getFieldFormats } from '../../services'; import { TypeMeta } from './types'; +import { PatternCache } from './_pattern_cache'; const MAX_ATTEMPTS_TO_RESOLVE_CONFLICTS = 3; const type = 'index-pattern'; @@ -65,12 +66,13 @@ export class IndexPattern implements IIndexPattern { private version: string | undefined; private savedObjectsClient: SavedObjectsClientContract; - private patternCache: any; + private patternCache: PatternCache; private getConfig: any; private sourceFilters?: []; private originalBody: { [key: string]: any } = {}; public fieldsFetcher: any; // probably want to factor out any direct usage and change to private private shortDotsEnable: boolean = false; + private apiClient: IIndexPatternsApiClient; private mapping: MappingObject = expandShorthand({ title: ES_FIELD_TYPES.TEXT, @@ -99,7 +101,7 @@ export class IndexPattern implements IIndexPattern { getConfig: any, savedObjectsClient: SavedObjectsClientContract, apiClient: IIndexPatternsApiClient, - patternCache: any + patternCache: PatternCache ) { this.id = id; this.savedObjectsClient = savedObjectsClient; @@ -108,8 +110,8 @@ export class IndexPattern implements IIndexPattern { // which cause problems when being consumed from angular this.getConfig = getConfig; - this.shortDotsEnable = this.getConfig('shortDots:enable'); - this.metaFields = this.getConfig(META_FIELDS_SETTING); + this.shortDotsEnable = this.getConfig(UI_SETTINGS.SHORT_DOTS_ENABLE); + this.metaFields = this.getConfig(UI_SETTINGS.META_FIELDS); this.createFieldList = getIndexPatternFieldListCreator({ fieldFormats: getFieldFormats(), @@ -117,8 +119,13 @@ export class IndexPattern implements IIndexPattern { }); this.fields = this.createFieldList(this, [], this.shortDotsEnable); - this.fieldsFetcher = createFieldsFetcher(this, apiClient, this.getConfig(META_FIELDS_SETTING)); - this.flattenHit = flattenHitWrapper(this, this.getConfig(META_FIELDS_SETTING)); + this.apiClient = apiClient; + this.fieldsFetcher = createFieldsFetcher( + this, + apiClient, + this.getConfig(UI_SETTINGS.META_FIELDS) + ); + this.flattenHit = flattenHitWrapper(this, this.getConfig(UI_SETTINGS.META_FIELDS)); this.formatHit = formatHitProvider( this, getFieldFormats().getDefaultInstance(KBN_FIELD_TYPES.STRING) @@ -392,8 +399,8 @@ export class IndexPattern implements IIndexPattern { duplicateId, this.getConfig, this.savedObjectsClient, - this.patternCache, - this.fieldsFetcher + this.apiClient, + this.patternCache ); await duplicatePattern.destroy(); } @@ -441,8 +448,8 @@ export class IndexPattern implements IIndexPattern { this.id, this.getConfig, this.savedObjectsClient, - this.patternCache, - this.fieldsFetcher + this.apiClient, + this.patternCache ); return samePattern.init().then(() => { // What keys changed from now and what the server returned @@ -485,7 +492,7 @@ export class IndexPattern implements IIndexPattern { this.version = samePattern.version; // Clear cache - this.patternCache.clear(this.id); + this.patternCache.clear(this.id!); // Try the save again return this.save(saveAttempts); @@ -541,8 +548,8 @@ export class IndexPattern implements IIndexPattern { } destroy() { - this.patternCache.clear(this.id); if (this.id) { + this.patternCache.clear(this.id); return this.savedObjectsClient.delete(type, this.id); } } diff --git a/src/plugins/data/public/mocks.ts b/src/plugins/data/public/mocks.ts index 7307c93139d59..d544d3c800bbe 100644 --- a/src/plugins/data/public/mocks.ts +++ b/src/plugins/data/public/mocks.ts @@ -21,11 +21,17 @@ import { Plugin, IndexPatternsContract } from '.'; import { fieldFormatsServiceMock } from './field_formats/mocks'; import { searchSetupMock, searchStartMock } from './search/mocks'; import { queryServiceMock } from './query/mocks'; +import { AutocompleteStart, AutocompleteSetup } from './autocomplete'; export type Setup = jest.Mocked>; export type Start = jest.Mocked>; -const autocompleteMock: any = { +const automcompleteSetupMock: jest.Mocked = { + addQuerySuggestionProvider: jest.fn(), + getQuerySuggestions: jest.fn(), +}; + +const autocompleteStartMock: jest.Mocked = { getValueSuggestions: jest.fn(), getQuerySuggestions: jest.fn(), hasQuerySuggestions: jest.fn(), @@ -34,7 +40,7 @@ const autocompleteMock: any = { const createSetupContract = (): Setup => { const querySetupMock = queryServiceMock.createSetupContract(); return { - autocomplete: autocompleteMock, + autocomplete: automcompleteSetupMock, search: searchSetupMock, fieldFormats: fieldFormatsServiceMock.createSetupContract(), query: querySetupMock, @@ -48,7 +54,7 @@ const createStartContract = (): Start => { createFiltersFromValueClickAction: jest.fn().mockResolvedValue(['yes']), createFiltersFromRangeSelectAction: jest.fn(), }, - autocomplete: autocompleteMock, + autocomplete: autocompleteStartMock, search: searchStartMock, fieldFormats: fieldFormatsServiceMock.createStartContract(), query: queryStartMock, diff --git a/src/plugins/data/public/plugin.ts b/src/plugins/data/public/plugin.ts index 08796216db1e0..06b5cbdfdfdfb 100644 --- a/src/plugins/data/public/plugin.ts +++ b/src/plugins/data/public/plugin.ts @@ -17,6 +17,8 @@ * under the License. */ +import './index.scss'; + import { PluginInitializerContext, CoreSetup, @@ -24,6 +26,7 @@ import { Plugin, PackageInfo, } from 'src/core/public'; +import { ConfigSchema } from '../config'; import { Storage, IStorageWrapper, createStartServicesGetter } from '../../kibana_utils/public'; import { DataPublicPluginSetup, @@ -83,17 +86,18 @@ declare module '../../ui_actions/public' { } export class DataPublicPlugin implements Plugin { - private readonly autocomplete = new AutocompleteService(); + private readonly autocomplete: AutocompleteService; private readonly searchService: SearchService; private readonly fieldFormatsService: FieldFormatsService; private readonly queryService: QueryService; private readonly storage: IStorageWrapper; private readonly packageInfo: PackageInfo; - constructor(initializerContext: PluginInitializerContext) { + constructor(initializerContext: PluginInitializerContext) { this.searchService = new SearchService(); this.queryService = new QueryService(); this.fieldFormatsService = new FieldFormatsService(); + this.autocomplete = new AutocompleteService(initializerContext); this.storage = new Storage(window.localStorage); this.packageInfo = initializerContext.env.packageInfo; } diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 142ec9c8c877e..7054575e8ef9e 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -53,6 +53,7 @@ import { SimpleSavedObject } from 'src/core/public'; import { Subscription } from 'rxjs'; import { Toast } from 'kibana/public'; import { ToastsStart } from 'kibana/public'; +import { TypeOf } from '@kbn/config-schema'; import { UiActionsSetup } from 'src/plugins/ui_actions/public'; import { UiActionsStart } from 'src/plugins/ui_actions/public'; import { Unit } from '@elastic/datemath'; @@ -841,7 +842,8 @@ export type IMetricAggType = MetricAggType; // @public (undocumented) export class IndexPattern implements IIndexPattern { // Warning: (ae-forgotten-export) The symbol "IIndexPatternsApiClient" needs to be exported by the entry point index.d.ts - constructor(id: string | undefined, getConfig: any, savedObjectsClient: SavedObjectsClientContract, apiClient: IIndexPatternsApiClient, patternCache: any); + // Warning: (ae-forgotten-export) The symbol "PatternCache" needs to be exported by the entry point index.d.ts + constructor(id: string | undefined, getConfig: any, savedObjectsClient: SavedObjectsClientContract, apiClient: IIndexPatternsApiClient, patternCache: PatternCache); // (undocumented) [key: string]: any; // (undocumented) @@ -1114,16 +1116,6 @@ export interface IResponseTypesMap { // @public (undocumented) export type ISearch = (request: IRequestTypesMap[T], options?: ISearchOptions) => Observable; -// Warning: (ae-missing-release-tag) "ISearchContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export interface ISearchContext { - // (undocumented) - core: CoreStart; - // (undocumented) - getSearchStrategy: (name: T) => TSearchStrategyProvider; -} - // Warning: (ae-missing-release-tag) "ISearchGeneric" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -1319,7 +1311,8 @@ export type PhrasesFilter = Filter & { // // @public (undocumented) export class Plugin implements Plugin_2 { - constructor(initializerContext: PluginInitializerContext_2); + // Warning: (ae-forgotten-export) The symbol "ConfigSchema" needs to be exported by the entry point index.d.ts + constructor(initializerContext: PluginInitializerContext_2); // Warning: (ae-forgotten-export) The symbol "DataSetupDependencies" needs to be exported by the entry point index.d.ts // // (undocumented) @@ -1336,7 +1329,7 @@ export class Plugin implements Plugin_2): Plugin; // Warning: (ae-missing-release-tag) "Query" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1785,10 +1778,38 @@ export interface TimeRange { to: string; } -// Warning: (ae-missing-release-tag) "TSearchStrategyProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public -export type TSearchStrategyProvider = (context: ISearchContext) => ISearchStrategy; +// Warning: (ae-missing-release-tag) "UI_SETTINGS" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const UI_SETTINGS: { + META_FIELDS: string; + DOC_HIGHLIGHT: string; + QUERY_STRING_OPTIONS: string; + QUERY_ALLOW_LEADING_WILDCARDS: string; + SEARCH_QUERY_LANGUAGE: string; + SORT_OPTIONS: string; + COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX: string; + COURIER_SET_REQUEST_PREFERENCE: string; + COURIER_CUSTOM_REQUEST_PREFERENCE: string; + COURIER_MAX_CONCURRENT_SHARD_REQUESTS: string; + COURIER_BATCH_SEARCHES: string; + SEARCH_INCLUDE_FROZEN: string; + HISTOGRAM_BAR_TARGET: string; + HISTOGRAM_MAX_BARS: string; + HISTORY_LIMIT: string; + SHORT_DOTS_ENABLE: string; + FORMAT_DEFAULT_TYPE_MAP: string; + FORMAT_NUMBER_DEFAULT_PATTERN: string; + FORMAT_PERCENT_DEFAULT_PATTERN: string; + FORMAT_BYTES_DEFAULT_PATTERN: string; + FORMAT_CURRENCY_DEFAULT_PATTERN: string; + FORMAT_NUMBER_DEFAULT_LOCALE: string; + TIMEPICKER_REFRESH_INTERVAL_DEFAULTS: string; + TIMEPICKER_QUICK_RANGES: string; + INDEXPATTERN_PLACEHOLDER: string; + FILTERS_PINNED_BY_DEFAULT: string; + FILTERS_EDITOR_SUGGEST_VALUES: string; +}; // Warnings were encountered during analysis: @@ -1798,52 +1819,52 @@ export type TSearchStrategyProvider = (context: ISearc // src/plugins/data/common/es_query/filters/match_all_filter.ts:28:3 - (ae-forgotten-export) The symbol "MatchAllFilterMeta" needs to be exported by the entry point index.d.ts // src/plugins/data/common/es_query/filters/phrase_filter.ts:33:3 - (ae-forgotten-export) The symbol "PhraseFilterMeta" needs to be exported by the entry point index.d.ts // src/plugins/data/common/es_query/filters/phrases_filter.ts:31:3 - (ae-forgotten-export) The symbol "PhrasesFilterMeta" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:66:23 - (ae-forgotten-export) The symbol "FilterLabel" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:66:23 - (ae-forgotten-export) The symbol "FILTERS" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:66:23 - (ae-forgotten-export) The symbol "getDisplayValueFromFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:66:23 - (ae-forgotten-export) The symbol "generateFilters" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:66:23 - (ae-forgotten-export) The symbol "changeTimeFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:66:23 - (ae-forgotten-export) The symbol "convertRangeFilterToTimeRangeString" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:66:23 - (ae-forgotten-export) The symbol "extractTimeFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:137:21 - (ae-forgotten-export) The symbol "buildEsQuery" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:137:21 - (ae-forgotten-export) The symbol "getEsQueryConfig" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:137:21 - (ae-forgotten-export) The symbol "luceneStringToDsl" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:137:21 - (ae-forgotten-export) The symbol "decorateQuery" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:179:26 - (ae-forgotten-export) The symbol "FieldFormatsRegistry" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:179:26 - (ae-forgotten-export) The symbol "BoolFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:179:26 - (ae-forgotten-export) The symbol "BytesFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:179:26 - (ae-forgotten-export) The symbol "ColorFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:179:26 - (ae-forgotten-export) The symbol "DateNanosFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:179:26 - (ae-forgotten-export) The symbol "DurationFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:179:26 - (ae-forgotten-export) The symbol "IpFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:179:26 - (ae-forgotten-export) The symbol "NumberFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:179:26 - (ae-forgotten-export) The symbol "PercentFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:179:26 - (ae-forgotten-export) The symbol "RelativeDateFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:179:26 - (ae-forgotten-export) The symbol "SourceFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:179:26 - (ae-forgotten-export) The symbol "StaticLookupFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:179:26 - (ae-forgotten-export) The symbol "UrlFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:179:26 - (ae-forgotten-export) The symbol "StringFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:179:26 - (ae-forgotten-export) The symbol "TruncateFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:237:27 - (ae-forgotten-export) The symbol "isFilterable" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:237:27 - (ae-forgotten-export) The symbol "isNestedField" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:237:27 - (ae-forgotten-export) The symbol "validateIndexPattern" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:237:27 - (ae-forgotten-export) The symbol "getFromSavedObject" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:237:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:237:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:377:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:377:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:377:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:377:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:379:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:380:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:389:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:390:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:391:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:395:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:396:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:399:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:400:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:403:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:65:23 - (ae-forgotten-export) The symbol "FilterLabel" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:65:23 - (ae-forgotten-export) The symbol "FILTERS" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:65:23 - (ae-forgotten-export) The symbol "getDisplayValueFromFilter" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:65:23 - (ae-forgotten-export) The symbol "generateFilters" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:65:23 - (ae-forgotten-export) The symbol "changeTimeFilter" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:65:23 - (ae-forgotten-export) The symbol "convertRangeFilterToTimeRangeString" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:65:23 - (ae-forgotten-export) The symbol "extractTimeFilter" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:136:21 - (ae-forgotten-export) The symbol "buildEsQuery" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:136:21 - (ae-forgotten-export) The symbol "getEsQueryConfig" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:136:21 - (ae-forgotten-export) The symbol "luceneStringToDsl" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:136:21 - (ae-forgotten-export) The symbol "decorateQuery" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:178:26 - (ae-forgotten-export) The symbol "FieldFormatsRegistry" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:178:26 - (ae-forgotten-export) The symbol "BoolFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:178:26 - (ae-forgotten-export) The symbol "BytesFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:178:26 - (ae-forgotten-export) The symbol "ColorFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:178:26 - (ae-forgotten-export) The symbol "DateNanosFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:178:26 - (ae-forgotten-export) The symbol "DurationFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:178:26 - (ae-forgotten-export) The symbol "IpFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:178:26 - (ae-forgotten-export) The symbol "NumberFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:178:26 - (ae-forgotten-export) The symbol "PercentFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:178:26 - (ae-forgotten-export) The symbol "RelativeDateFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:178:26 - (ae-forgotten-export) The symbol "SourceFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:178:26 - (ae-forgotten-export) The symbol "StaticLookupFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:178:26 - (ae-forgotten-export) The symbol "UrlFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:178:26 - (ae-forgotten-export) The symbol "StringFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:178:26 - (ae-forgotten-export) The symbol "TruncateFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:236:27 - (ae-forgotten-export) The symbol "isFilterable" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:236:27 - (ae-forgotten-export) The symbol "isNestedField" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:236:27 - (ae-forgotten-export) The symbol "validateIndexPattern" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:236:27 - (ae-forgotten-export) The symbol "getFromSavedObject" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:236:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:236:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:375:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:375:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:375:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:375:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:377:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:378:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:387:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:388:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:389:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:393:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:394:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:397:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:398:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts // src/plugins/data/public/query/state_sync/connect_to_query_state.ts:33:33 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts // src/plugins/data/public/query/state_sync/connect_to_query_state.ts:37:1 - (ae-forgotten-export) The symbol "QueryStateChange" needs to be exported by the entry point index.d.ts // src/plugins/data/public/types.ts:52:5 - (ae-forgotten-export) The symbol "createFiltersFromValueClickAction" needs to be exported by the entry point index.d.ts diff --git a/src/plugins/data/public/query/filter_manager/filter_manager.test.ts b/src/plugins/data/public/query/filter_manager/filter_manager.test.ts index 3c69a498e74cd..878142906f54b 100644 --- a/src/plugins/data/public/query/filter_manager/filter_manager.test.ts +++ b/src/plugins/data/public/query/filter_manager/filter_manager.test.ts @@ -24,14 +24,14 @@ import { Subscription } from 'rxjs'; import { FilterManager } from './filter_manager'; import { getFilter } from './test_helpers/get_stub_filter'; import { getFiltersArray } from './test_helpers/get_filters_array'; -import { Filter, FilterStateStore } from '../../../common'; +import { Filter, FilterStateStore, UI_SETTINGS } from '../../../common'; import { coreMock } from '../../../../../core/public/mocks'; const setupMock = coreMock.createSetup(); const uiSettingsMock = (pinnedByDefault: boolean) => (key: string) => { switch (key) { - case 'filters:pinnedByDefault': + case UI_SETTINGS.FILTERS_PINNED_BY_DEFAULT: return pinnedByDefault; default: throw new Error(`Unexpected uiSettings key in FilterManager mock: ${key}`); diff --git a/src/plugins/data/public/query/filter_manager/filter_manager.ts b/src/plugins/data/public/query/filter_manager/filter_manager.ts index d58a0eb45c04f..60a49a4bd50f4 100644 --- a/src/plugins/data/public/query/filter_manager/filter_manager.ts +++ b/src/plugins/data/public/query/filter_manager/filter_manager.ts @@ -34,6 +34,7 @@ import { isFilterPinned, compareFilters, COMPARE_ALL_OPTIONS, + UI_SETTINGS, } from '../../../common'; export class FilterManager { @@ -129,7 +130,7 @@ export class FilterManager { public addFilters( filters: Filter[] | Filter, - pinFilterStatus: boolean = this.uiSettings.get('filters:pinnedByDefault') + pinFilterStatus: boolean = this.uiSettings.get(UI_SETTINGS.FILTERS_PINNED_BY_DEFAULT) ) { if (!Array.isArray(filters)) { filters = [filters]; @@ -157,7 +158,7 @@ export class FilterManager { public setFilters( newFilters: Filter[], - pinFilterStatus: boolean = this.uiSettings.get('filters:pinnedByDefault') + pinFilterStatus: boolean = this.uiSettings.get(UI_SETTINGS.FILTERS_PINNED_BY_DEFAULT) ) { const store = pinFilterStatus ? FilterStateStore.GLOBAL_STATE : FilterStateStore.APP_STATE; diff --git a/src/plugins/data/public/query/lib/get_query_log.ts b/src/plugins/data/public/query/lib/get_query_log.ts index a71eb7580cf07..b7827d2c8de02 100644 --- a/src/plugins/data/public/query/lib/get_query_log.ts +++ b/src/plugins/data/public/query/lib/get_query_log.ts @@ -20,6 +20,7 @@ import { IUiSettingsClient } from 'src/core/public'; import { IStorageWrapper } from 'src/plugins/kibana_utils/public'; import { PersistedLog } from '../persisted_log'; +import { UI_SETTINGS } from '../../../common'; export function getQueryLog( uiSettings: IUiSettingsClient, @@ -30,7 +31,7 @@ export function getQueryLog( return new PersistedLog( `typeahead:${appName}-${language}`, { - maxLength: uiSettings.get('history:limit'), + maxLength: uiSettings.get(UI_SETTINGS.HISTORY_LIMIT), filterDuplicates: true, }, storage diff --git a/src/plugins/data/public/query/state_sync/connect_to_query_state.test.ts b/src/plugins/data/public/query/state_sync/connect_to_query_state.test.ts index 06e4c1c8be6d5..4e394445b75ae 100644 --- a/src/plugins/data/public/query/state_sync/connect_to_query_state.test.ts +++ b/src/plugins/data/public/query/state_sync/connect_to_query_state.test.ts @@ -20,7 +20,7 @@ import { Subscription } from 'rxjs'; import { FilterManager } from '../filter_manager'; import { getFilter } from '../filter_manager/test_helpers/get_stub_filter'; -import { Filter, FilterStateStore } from '../../../common'; +import { Filter, FilterStateStore, UI_SETTINGS } from '../../../common'; import { coreMock } from '../../../../../core/public/mocks'; import { BaseStateContainer, createStateContainer, Storage } from '../../../../kibana_utils/public'; import { QueryService, QueryStart } from '../query_service'; @@ -46,11 +46,11 @@ const startMock = coreMock.createStart(); setupMock.uiSettings.get.mockImplementation((key: string) => { switch (key) { - case 'filters:pinnedByDefault': + case UI_SETTINGS.FILTERS_PINNED_BY_DEFAULT: return true; case 'timepicker:timeDefaults': return { from: 'now-15m', to: 'now' }; - case 'timepicker:refreshIntervalDefaults': + case UI_SETTINGS.TIMEPICKER_REFRESH_INTERVAL_DEFAULTS: return { pause: false, value: 0 }; default: throw new Error(`sync_query test: not mocked uiSetting: ${key}`); diff --git a/src/plugins/data/public/query/state_sync/sync_state_with_url.test.ts b/src/plugins/data/public/query/state_sync/sync_state_with_url.test.ts index 50dc35ea955ee..7727153537257 100644 --- a/src/plugins/data/public/query/state_sync/sync_state_with_url.test.ts +++ b/src/plugins/data/public/query/state_sync/sync_state_with_url.test.ts @@ -21,7 +21,7 @@ import { Subscription } from 'rxjs'; import { createBrowserHistory, History } from 'history'; import { FilterManager } from '../filter_manager'; import { getFilter } from '../filter_manager/test_helpers/get_stub_filter'; -import { Filter, FilterStateStore } from '../../../common'; +import { Filter, FilterStateStore, UI_SETTINGS } from '../../../common'; import { coreMock } from '../../../../../core/public/mocks'; import { createKbnUrlStateStorage, @@ -39,11 +39,11 @@ const startMock = coreMock.createStart(); setupMock.uiSettings.get.mockImplementation((key: string) => { switch (key) { - case 'filters:pinnedByDefault': + case UI_SETTINGS.FILTERS_PINNED_BY_DEFAULT: return true; case 'timepicker:timeDefaults': return { from: 'now-15m', to: 'now' }; - case 'timepicker:refreshIntervalDefaults': + case UI_SETTINGS.TIMEPICKER_REFRESH_INTERVAL_DEFAULTS: return { pause: false, value: 0 }; default: throw new Error(`sync_query test: not mocked uiSetting: ${key}`); diff --git a/src/plugins/data/public/query/timefilter/timefilter_service.ts b/src/plugins/data/public/query/timefilter/timefilter_service.ts index 413163ed059ad..df2fbc8e5a8f3 100644 --- a/src/plugins/data/public/query/timefilter/timefilter_service.ts +++ b/src/plugins/data/public/query/timefilter/timefilter_service.ts @@ -20,6 +20,7 @@ import { IUiSettingsClient } from 'src/core/public'; import { IStorageWrapper } from 'src/plugins/kibana_utils/public'; import { TimeHistory, Timefilter, TimeHistoryContract, TimefilterContract } from './index'; +import { UI_SETTINGS } from '../../../common'; /** * Filter Service @@ -35,7 +36,7 @@ export class TimefilterService { public setup({ uiSettings, storage }: TimeFilterServiceDependencies): TimefilterSetup { const timefilterConfig = { timeDefaults: uiSettings.get('timepicker:timeDefaults'), - refreshIntervalDefaults: uiSettings.get('timepicker:refreshIntervalDefaults'), + refreshIntervalDefaults: uiSettings.get(UI_SETTINGS.TIMEPICKER_REFRESH_INTERVAL_DEFAULTS), }; const history = new TimeHistory(storage); const timefilter = new Timefilter(timefilterConfig, history); diff --git a/src/plugins/data/public/search/aggs/buckets/date_histogram.ts b/src/plugins/data/public/search/aggs/buckets/date_histogram.ts index d5c97d0c95c5c..8a5596f669cb7 100644 --- a/src/plugins/data/public/search/aggs/buckets/date_histogram.ts +++ b/src/plugins/data/public/search/aggs/buckets/date_histogram.ts @@ -31,7 +31,7 @@ import { dateHistogramInterval, TimeRange } from '../../../../common'; import { writeParams } from '../agg_params'; import { isMetricAggType } from '../metrics/metric_agg_type'; -import { FIELD_FORMAT_IDS, KBN_FIELD_TYPES } from '../../../../common'; +import { FIELD_FORMAT_IDS, KBN_FIELD_TYPES, UI_SETTINGS } from '../../../../common'; import { TimefilterContract } from '../../../query'; import { QuerySetup } from '../../../query/query_service'; import { GetInternalStartServicesFn } from '../../../types'; @@ -125,8 +125,8 @@ export const getDateHistogramBucketAgg = ({ const { timefilter } = query.timefilter; buckets = new TimeBuckets({ - 'histogram:maxBars': uiSettings.get('histogram:maxBars'), - 'histogram:barTarget': uiSettings.get('histogram:barTarget'), + 'histogram:maxBars': uiSettings.get(UI_SETTINGS.HISTOGRAM_MAX_BARS), + 'histogram:barTarget': uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET), dateFormat: uiSettings.get('dateFormat'), 'dateFormat:scaled': uiSettings.get('dateFormat:scaled'), }); diff --git a/src/plugins/data/public/search/aggs/buckets/filters.ts b/src/plugins/data/public/search/aggs/buckets/filters.ts index 3f3f13bb955c1..4052c0b390155 100644 --- a/src/plugins/data/public/search/aggs/buckets/filters.ts +++ b/src/plugins/data/public/search/aggs/buckets/filters.ts @@ -26,7 +26,7 @@ import { toAngularJSON } from '../utils'; import { BucketAggType } from './bucket_agg_type'; import { BUCKET_TYPES } from './bucket_agg_types'; import { Storage } from '../../../../../../plugins/kibana_utils/public'; -import { getEsQueryConfig, buildEsQuery, Query } from '../../../../common'; +import { getEsQueryConfig, buildEsQuery, Query, UI_SETTINGS } from '../../../../common'; import { getQueryLog } from '../../../query'; import { GetInternalStartServicesFn } from '../../../types'; import { BaseAggParams } from '../types'; @@ -69,7 +69,10 @@ export const getFiltersBucketAgg = ({ { name: 'filters', default: [ - { input: { query: '', language: uiSettings.get('search:queryLanguage') }, label: '' }, + { + input: { query: '', language: uiSettings.get(UI_SETTINGS.SEARCH_QUERY_LANGUAGE) }, + label: '', + }, ], write(aggConfig, output) { const inFilters: FilterValue[] = aggConfig.params.filters; diff --git a/src/plugins/data/public/search/aggs/buckets/histogram.ts b/src/plugins/data/public/search/aggs/buckets/histogram.ts index d04df4f8aac6b..c1fad17f488db 100644 --- a/src/plugins/data/public/search/aggs/buckets/histogram.ts +++ b/src/plugins/data/public/search/aggs/buckets/histogram.ts @@ -24,7 +24,7 @@ import { IUiSettingsClient } from 'src/core/public'; import { BucketAggType, IBucketAggConfig } from './bucket_agg_type'; import { createFilterHistogram } from './create_filter/histogram'; import { BUCKET_TYPES } from './bucket_agg_types'; -import { KBN_FIELD_TYPES } from '../../../../common'; +import { KBN_FIELD_TYPES, UI_SETTINGS } from '../../../../common'; import { GetInternalStartServicesFn } from '../../../types'; import { BaseAggParams } from '../types'; import { ExtendedBounds } from './lib/extended_bounds'; @@ -155,8 +155,8 @@ export const getHistogramBucketAgg = ({ const range = autoBounds.max - autoBounds.min; const bars = range / interval; - if (bars > uiSettings.get('histogram:maxBars')) { - const minInterval = range / uiSettings.get('histogram:maxBars'); + if (bars > uiSettings.get(UI_SETTINGS.HISTOGRAM_MAX_BARS)) { + const minInterval = range / uiSettings.get(UI_SETTINGS.HISTOGRAM_MAX_BARS); // Round interval by order of magnitude to provide clean intervals // Always round interval up so there will always be less buckets than histogram:maxBars diff --git a/src/plugins/data/public/search/aggs/utils/calculate_auto_time_expression.ts b/src/plugins/data/public/search/aggs/utils/calculate_auto_time_expression.ts index 9d976784329cc..30fcdd9d83a38 100644 --- a/src/plugins/data/public/search/aggs/utils/calculate_auto_time_expression.ts +++ b/src/plugins/data/public/search/aggs/utils/calculate_auto_time_expression.ts @@ -19,7 +19,7 @@ import moment from 'moment'; import { IUiSettingsClient } from 'src/core/public'; import { TimeBuckets } from '../buckets/lib/time_buckets'; -import { toAbsoluteDates, TimeRange } from '../../../../common'; +import { toAbsoluteDates, TimeRange, UI_SETTINGS } from '../../../../common'; export function getCalculateAutoTimeExpression(uiSettings: IUiSettingsClient) { return function calculateAutoTimeExpression(range: TimeRange) { @@ -29,8 +29,8 @@ export function getCalculateAutoTimeExpression(uiSettings: IUiSettingsClient) { } const buckets = new TimeBuckets({ - 'histogram:maxBars': uiSettings.get('histogram:maxBars'), - 'histogram:barTarget': uiSettings.get('histogram:barTarget'), + 'histogram:maxBars': uiSettings.get(UI_SETTINGS.HISTOGRAM_MAX_BARS), + 'histogram:barTarget': uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET), dateFormat: uiSettings.get('dateFormat'), 'dateFormat:scaled': uiSettings.get('dateFormat:scaled'), }); diff --git a/src/plugins/data/public/search/es_search/es_search_strategy.test.ts b/src/plugins/data/public/search/es_search/es_search_strategy.test.ts index de1835f09f3bf..b580c5170aad7 100644 --- a/src/plugins/data/public/search/es_search/es_search_strategy.test.ts +++ b/src/plugins/data/public/search/es_search/es_search_strategy.test.ts @@ -17,40 +17,31 @@ * under the License. */ +import { CoreSetup } from '../../../../../core/public'; import { coreMock } from '../../../../../core/public/mocks'; import { esSearchStrategyProvider } from './es_search_strategy'; -import { CoreStart } from 'kibana/public'; import { ES_SEARCH_STRATEGY } from '../../../common/search/es_search'; describe('ES search strategy', () => { - let mockCoreStart: MockedKeys; - const mockSearch = jest.fn(); + let mockCoreSetup: MockedKeys; + const mockSearch = { search: jest.fn() }; beforeEach(() => { - mockCoreStart = coreMock.createStart(); - mockSearch.mockClear(); + mockCoreSetup = coreMock.createSetup(); + mockSearch.search.mockClear(); }); it('returns a strategy with `search` that calls the sync search `search`', () => { const request = { params: {} }; const options = {}; - const esSearch = esSearchStrategyProvider({ - core: mockCoreStart, - getSearchStrategy: jest.fn().mockImplementation(() => { - return () => { - return { - search: mockSearch, - }; - }; - }), - }); + const esSearch = esSearchStrategyProvider(mockCoreSetup, mockSearch); esSearch.search(request, options); - expect(mockSearch.mock.calls[0][0]).toEqual({ + expect(mockSearch.search.mock.calls[0][0]).toEqual({ ...request, serverStrategy: ES_SEARCH_STRATEGY, }); - expect(mockSearch.mock.calls[0][1]).toBe(options); + expect(mockSearch.search.mock.calls[0][1]).toBe(options); }); }); diff --git a/src/plugins/data/public/search/es_search/es_search_strategy.ts b/src/plugins/data/public/search/es_search/es_search_strategy.ts index a61428c998157..82f8bf21ee57b 100644 --- a/src/plugins/data/public/search/es_search/es_search_strategy.ts +++ b/src/plugins/data/public/search/es_search/es_search_strategy.ts @@ -18,25 +18,26 @@ */ import { Observable } from 'rxjs'; +import { CoreSetup } from '../../../../../core/public'; import { ES_SEARCH_STRATEGY, IEsSearchResponse } from '../../../common/search'; +import { ISearch } from '../i_search'; +import { ISearchStrategy } from '../types'; import { SYNC_SEARCH_STRATEGY } from '../sync_search_strategy'; import { getEsPreference } from './get_es_preference'; -import { ISearchContext, TSearchStrategyProvider, ISearchStrategy } from '../types'; -export const esSearchStrategyProvider: TSearchStrategyProvider = ( - context: ISearchContext -): ISearchStrategy => { - const syncStrategyProvider = context.getSearchStrategy(SYNC_SEARCH_STRATEGY); - const { search } = syncStrategyProvider(context); - return { - search: (request, options) => { - request.params = { - preference: getEsPreference(context.core.uiSettings), - ...request.params, - }; - return search({ ...request, serverStrategy: ES_SEARCH_STRATEGY }, options) as Observable< - IEsSearchResponse - >; - }, +export function esSearchStrategyProvider( + core: CoreSetup, + syncStrategy: ISearchStrategy +) { + const search: ISearch = (request, options) => { + request.params = { + preference: getEsPreference(core.uiSettings), + ...request.params, + }; + return syncStrategy.search( + { ...request, serverStrategy: ES_SEARCH_STRATEGY }, + options + ) as Observable; }; -}; + return { search }; +} diff --git a/src/plugins/data/public/search/es_search/get_es_preference.test.ts b/src/plugins/data/public/search/es_search/get_es_preference.test.ts index 8b8156b4519d6..05a74b3e6205a 100644 --- a/src/plugins/data/public/search/es_search/get_es_preference.test.ts +++ b/src/plugins/data/public/search/es_search/get_es_preference.test.ts @@ -20,6 +20,7 @@ import { getEsPreference } from './get_es_preference'; import { CoreStart } from '../../../../../core/public'; import { coreMock } from '../../../../../core/public/mocks'; +import { UI_SETTINGS } from '../../../common'; describe('Get ES preference', () => { let mockCoreStart: MockedKeys; @@ -30,8 +31,8 @@ describe('Get ES preference', () => { test('returns the session ID if set to sessionId', () => { mockCoreStart.uiSettings.get.mockImplementation((key: string) => { - if (key === 'courier:setRequestPreference') return 'sessionId'; - if (key === 'courier:customRequestPreference') return 'foobar'; + if (key === UI_SETTINGS.COURIER_SET_REQUEST_PREFERENCE) return 'sessionId'; + if (key === UI_SETTINGS.COURIER_CUSTOM_REQUEST_PREFERENCE) return 'foobar'; }); const preference = getEsPreference(mockCoreStart.uiSettings, 'my_session_id'); expect(preference).toBe('my_session_id'); @@ -39,8 +40,8 @@ describe('Get ES preference', () => { test('returns the custom preference if set to custom', () => { mockCoreStart.uiSettings.get.mockImplementation((key: string) => { - if (key === 'courier:setRequestPreference') return 'custom'; - if (key === 'courier:customRequestPreference') return 'foobar'; + if (key === UI_SETTINGS.COURIER_SET_REQUEST_PREFERENCE) return 'custom'; + if (key === UI_SETTINGS.COURIER_CUSTOM_REQUEST_PREFERENCE) return 'foobar'; }); const preference = getEsPreference(mockCoreStart.uiSettings); expect(preference).toBe('foobar'); @@ -48,8 +49,8 @@ describe('Get ES preference', () => { test('returns undefined if set to none', () => { mockCoreStart.uiSettings.get.mockImplementation((key: string) => { - if (key === 'courier:setRequestPreference') return 'none'; - if (key === 'courier:customRequestPreference') return 'foobar'; + if (key === UI_SETTINGS.COURIER_SET_REQUEST_PREFERENCE) return 'none'; + if (key === UI_SETTINGS.COURIER_CUSTOM_REQUEST_PREFERENCE) return 'foobar'; }); const preference = getEsPreference(mockCoreStart.uiSettings); expect(preference).toBe(undefined); diff --git a/src/plugins/data/public/search/es_search/get_es_preference.ts b/src/plugins/data/public/search/es_search/get_es_preference.ts index 3f1c2b9b3b736..5e40712067bb0 100644 --- a/src/plugins/data/public/search/es_search/get_es_preference.ts +++ b/src/plugins/data/public/search/es_search/get_es_preference.ts @@ -18,12 +18,13 @@ */ import { IUiSettingsClient } from '../../../../../core/public'; +import { UI_SETTINGS } from '../../../common'; const defaultSessionId = `${Date.now()}`; export function getEsPreference(uiSettings: IUiSettingsClient, sessionId = defaultSessionId) { - const setPreference = uiSettings.get('courier:setRequestPreference'); + const setPreference = uiSettings.get(UI_SETTINGS.COURIER_SET_REQUEST_PREFERENCE); if (setPreference === 'sessionId') return `${sessionId}`; - const customPreference = uiSettings.get('courier:customRequestPreference'); + const customPreference = uiSettings.get(UI_SETTINGS.COURIER_CUSTOM_REQUEST_PREFERENCE); return setPreference === 'custom' ? customPreference : undefined; } diff --git a/src/plugins/data/public/search/fetch/get_search_params.test.ts b/src/plugins/data/public/search/fetch/get_search_params.test.ts index 4809d76a46f59..f9b62fdd4fc61 100644 --- a/src/plugins/data/public/search/fetch/get_search_params.test.ts +++ b/src/plugins/data/public/search/fetch/get_search_params.test.ts @@ -19,6 +19,7 @@ import { getSearchParams } from './get_search_params'; import { IUiSettingsClient } from 'kibana/public'; +import { UI_SETTINGS } from '../../../common'; function getConfigStub(config: any = {}) { return { @@ -40,21 +41,21 @@ describe('getSearchParams', () => { }); test('includes ignore_throttled according to search:includeFrozen', () => { - let config = getConfigStub({ 'search:includeFrozen': true }); + let config = getConfigStub({ [UI_SETTINGS.SEARCH_INCLUDE_FROZEN]: true }); let searchParams = getSearchParams(config); expect(searchParams.ignore_throttled).toBe(false); - config = getConfigStub({ 'search:includeFrozen': false }); + config = getConfigStub({ [UI_SETTINGS.SEARCH_INCLUDE_FROZEN]: false }); searchParams = getSearchParams(config); expect(searchParams.ignore_throttled).toBe(true); }); test('includes max_concurrent_shard_requests according to courier:maxConcurrentShardRequests', () => { - let config = getConfigStub({ 'courier:maxConcurrentShardRequests': 0 }); + let config = getConfigStub({ [UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS]: 0 }); let searchParams = getSearchParams(config); expect(searchParams.max_concurrent_shard_requests).toBe(undefined); - config = getConfigStub({ 'courier:maxConcurrentShardRequests': 5 }); + config = getConfigStub({ [UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS]: 5 }); searchParams = getSearchParams(config); expect(searchParams.max_concurrent_shard_requests).toBe(5); }); diff --git a/src/plugins/data/public/search/fetch/get_search_params.ts b/src/plugins/data/public/search/fetch/get_search_params.ts index f0c43bd2e74cd..60bdc9ed6473a 100644 --- a/src/plugins/data/public/search/fetch/get_search_params.ts +++ b/src/plugins/data/public/search/fetch/get_search_params.ts @@ -18,6 +18,7 @@ */ import { IUiSettingsClient } from 'kibana/public'; +import { UI_SETTINGS } from '../../../common'; const sessionId = Date.now(); @@ -33,19 +34,19 @@ export function getSearchParams(config: IUiSettingsClient, esShardTimeout: numbe } export function getIgnoreThrottled(config: IUiSettingsClient) { - return !config.get('search:includeFrozen'); + return !config.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); } export function getMaxConcurrentShardRequests(config: IUiSettingsClient) { - const maxConcurrentShardRequests = config.get('courier:maxConcurrentShardRequests'); + const maxConcurrentShardRequests = config.get(UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS); return maxConcurrentShardRequests > 0 ? maxConcurrentShardRequests : undefined; } export function getPreference(config: IUiSettingsClient) { - const setRequestPreference = config.get('courier:setRequestPreference'); + const setRequestPreference = config.get(UI_SETTINGS.COURIER_SET_REQUEST_PREFERENCE); if (setRequestPreference === 'sessionId') return sessionId; return setRequestPreference === 'custom' - ? config.get('courier:customRequestPreference') + ? config.get(UI_SETTINGS.COURIER_CUSTOM_REQUEST_PREFERENCE) : undefined; } diff --git a/src/plugins/data/public/search/index.ts b/src/plugins/data/public/search/index.ts index 26149432f6117..53686f9be9b4d 100644 --- a/src/plugins/data/public/search/index.ts +++ b/src/plugins/data/public/search/index.ts @@ -21,13 +21,7 @@ export * from './aggs'; export * from './expressions'; export * from './tabify'; -export { - ISearchSetup, - ISearchStart, - ISearchContext, - TSearchStrategyProvider, - ISearchStrategy, -} from './types'; +export { ISearchSetup, ISearchStart, ISearchStrategy } from './types'; export { ISearch, diff --git a/src/plugins/data/public/search/legacy/default_search_strategy.test.ts b/src/plugins/data/public/search/legacy/default_search_strategy.test.ts index c619c9b17d9a8..436b522744622 100644 --- a/src/plugins/data/public/search/legacy/default_search_strategy.test.ts +++ b/src/plugins/data/public/search/legacy/default_search_strategy.test.ts @@ -21,6 +21,7 @@ import { IUiSettingsClient } from 'kibana/public'; import { defaultSearchStrategy } from './default_search_strategy'; import { searchStartMock } from '../mocks'; import { SearchStrategySearchParams } from './types'; +import { UI_SETTINGS } from '../../../common'; const { search } = defaultSearchStrategy; @@ -69,30 +70,30 @@ describe('defaultSearchStrategy', function () { }); test('does not send max_concurrent_shard_requests by default', async () => { - const config = getConfigStub({ 'courier:batchSearches': true }); + const config = getConfigStub({ [UI_SETTINGS.COURIER_BATCH_SEARCHES]: true }); await search({ ...searchArgs, config }); expect(es.msearch.mock.calls[0][0].max_concurrent_shard_requests).toBe(undefined); }); test('allows configuration of max_concurrent_shard_requests', async () => { const config = getConfigStub({ - 'courier:batchSearches': true, - 'courier:maxConcurrentShardRequests': 42, + [UI_SETTINGS.COURIER_BATCH_SEARCHES]: true, + [UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS]: 42, }); await search({ ...searchArgs, config }); expect(es.msearch.mock.calls[0][0].max_concurrent_shard_requests).toBe(42); }); test('should set rest_total_hits_as_int to true on a request', async () => { - const config = getConfigStub({ 'courier:batchSearches': true }); + const config = getConfigStub({ [UI_SETTINGS.COURIER_BATCH_SEARCHES]: true }); await search({ ...searchArgs, config }); expect(es.msearch.mock.calls[0][0]).toHaveProperty('rest_total_hits_as_int', true); }); test('should set ignore_throttled=false when including frozen indices', async () => { const config = getConfigStub({ - 'courier:batchSearches': true, - 'search:includeFrozen': true, + [UI_SETTINGS.COURIER_BATCH_SEARCHES]: true, + [UI_SETTINGS.SEARCH_INCLUDE_FROZEN]: true, }); await search({ ...searchArgs, config }); expect(es.msearch.mock.calls[0][0]).toHaveProperty('ignore_throttled', false); @@ -100,7 +101,7 @@ describe('defaultSearchStrategy', function () { test('should properly call abort with msearch', () => { const config = getConfigStub({ - 'courier:batchSearches': true, + [UI_SETTINGS.COURIER_BATCH_SEARCHES]: true, }); search({ ...searchArgs, config }).abort(); expect(msearchMockResponse.abort).toHaveBeenCalled(); diff --git a/src/plugins/data/public/search/legacy/fetch_soon.test.ts b/src/plugins/data/public/search/legacy/fetch_soon.test.ts index e99e13ba33d1a..61d3568350b6b 100644 --- a/src/plugins/data/public/search/legacy/fetch_soon.test.ts +++ b/src/plugins/data/public/search/legacy/fetch_soon.test.ts @@ -22,6 +22,7 @@ import { callClient } from './call_client'; import { IUiSettingsClient } from 'kibana/public'; import { FetchHandlers, FetchOptions } from '../fetch/types'; import { SearchRequest, SearchResponse } from '../index'; +import { UI_SETTINGS } from '../../../common'; function getConfigStub(config: any = {}) { return { @@ -60,7 +61,7 @@ describe('fetchSoon', () => { test('should execute asap if config is set to not batch searches', () => { const config = getConfigStub({ - 'courier:batchSearches': false, + [UI_SETTINGS.COURIER_BATCH_SEARCHES]: false, }); const request = {}; const options = {}; @@ -72,7 +73,7 @@ describe('fetchSoon', () => { test('should delay by 50ms if config is set to batch searches', () => { const config = getConfigStub({ - 'courier:batchSearches': true, + [UI_SETTINGS.COURIER_BATCH_SEARCHES]: true, }); const request = {}; const options = {}; @@ -88,7 +89,7 @@ describe('fetchSoon', () => { test('should send a batch of requests to callClient', () => { const config = getConfigStub({ - 'courier:batchSearches': true, + [UI_SETTINGS.COURIER_BATCH_SEARCHES]: true, }); const requests = [{ foo: 1 }, { foo: 2 }]; const options = [{ bar: 1 }, { bar: 2 }]; @@ -105,7 +106,7 @@ describe('fetchSoon', () => { test('should return the response to the corresponding call for multiple batched requests', async () => { const config = getConfigStub({ - 'courier:batchSearches': true, + [UI_SETTINGS.COURIER_BATCH_SEARCHES]: true, }); const requests = [{ _mockResponseId: 'foo' }, { _mockResponseId: 'bar' }]; @@ -120,7 +121,7 @@ describe('fetchSoon', () => { test('should wait for the previous batch to start before starting a new batch', () => { const config = getConfigStub({ - 'courier:batchSearches': true, + [UI_SETTINGS.COURIER_BATCH_SEARCHES]: true, }); const firstBatch = [{ foo: 1 }, { foo: 2 }]; const secondBatch = [{ bar: 1 }, { bar: 2 }]; diff --git a/src/plugins/data/public/search/legacy/fetch_soon.ts b/src/plugins/data/public/search/legacy/fetch_soon.ts index 304c1c4d63f5b..fed2c52bc491f 100644 --- a/src/plugins/data/public/search/legacy/fetch_soon.ts +++ b/src/plugins/data/public/search/legacy/fetch_soon.ts @@ -20,6 +20,7 @@ import { callClient } from './call_client'; import { FetchHandlers, FetchOptions } from '../fetch/types'; import { SearchRequest, SearchResponse } from '../index'; +import { UI_SETTINGS } from '../../../common'; /** * This function introduces a slight delay in the request process to allow multiple requests to queue @@ -30,7 +31,7 @@ export async function fetchSoon( options: FetchOptions, fetchHandlers: FetchHandlers ) { - const msToDelay = fetchHandlers.config.get('courier:batchSearches') ? 50 : 0; + const msToDelay = fetchHandlers.config.get(UI_SETTINGS.COURIER_BATCH_SEARCHES) ? 50 : 0; return delayedFetch(request, options, fetchHandlers, msToDelay); } diff --git a/src/plugins/data/public/search/legacy/get_msearch_params.test.ts b/src/plugins/data/public/search/legacy/get_msearch_params.test.ts index ce98f6ab2a7bb..dc61e19406631 100644 --- a/src/plugins/data/public/search/legacy/get_msearch_params.test.ts +++ b/src/plugins/data/public/search/legacy/get_msearch_params.test.ts @@ -19,6 +19,7 @@ import { getMSearchParams } from './get_msearch_params'; import { IUiSettingsClient } from '../../../../../core/public'; +import { UI_SETTINGS } from '../../../common'; function getConfigStub(config: any = {}) { return { @@ -34,29 +35,29 @@ describe('getMSearchParams', () => { }); test('includes ignore_throttled according to search:includeFrozen', () => { - let config = getConfigStub({ 'search:includeFrozen': true }); + let config = getConfigStub({ [UI_SETTINGS.SEARCH_INCLUDE_FROZEN]: true }); let msearchParams = getMSearchParams(config); expect(msearchParams.ignore_throttled).toBe(false); - config = getConfigStub({ 'search:includeFrozen': false }); + config = getConfigStub({ [UI_SETTINGS.SEARCH_INCLUDE_FROZEN]: false }); msearchParams = getMSearchParams(config); expect(msearchParams.ignore_throttled).toBe(true); }); test('includes max_concurrent_shard_requests according to courier:maxConcurrentShardRequests if greater than 0', () => { - let config = getConfigStub({ 'courier:maxConcurrentShardRequests': 0 }); + let config = getConfigStub({ [UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS]: 0 }); let msearchParams = getMSearchParams(config); expect(msearchParams.max_concurrent_shard_requests).toBe(undefined); - config = getConfigStub({ 'courier:maxConcurrentShardRequests': 5 }); + config = getConfigStub({ [UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS]: 5 }); msearchParams = getMSearchParams(config); expect(msearchParams.max_concurrent_shard_requests).toBe(5); }); test('does not include other search params that are included in the msearch header or body', () => { const config = getConfigStub({ - 'search:includeFrozen': false, - 'courier:maxConcurrentShardRequests': 5, + [UI_SETTINGS.SEARCH_INCLUDE_FROZEN]: false, + [UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS]: 5, }); const msearchParams = getMSearchParams(config); expect(msearchParams.hasOwnProperty('ignore_unavailable')).toBe(false); diff --git a/src/plugins/data/public/search/mocks.ts b/src/plugins/data/public/search/mocks.ts index 44082040b5b0b..fcdbeb515423d 100644 --- a/src/plugins/data/public/search/mocks.ts +++ b/src/plugins/data/public/search/mocks.ts @@ -18,18 +18,20 @@ */ import { searchAggsSetupMock, searchAggsStartMock } from './aggs/mocks'; -import { ISearchStart } from './types'; +import { ISearchSetup, ISearchStart } from './types'; import { searchSourceMock, createSearchSourceMock } from './search_source/mocks'; -const searchSetupMock = { +export * from './search_source/mocks'; + +const searchSetupMock: jest.Mocked = { aggs: searchAggsSetupMock(), - registerSearchStrategyContext: jest.fn(), - registerSearchStrategyProvider: jest.fn(), + registerSearchStrategy: jest.fn(), }; const searchStartMock: jest.Mocked = { aggs: searchAggsStartMock(), setInterceptor: jest.fn(), + getSearchStrategy: jest.fn(), search: jest.fn(), searchSource: searchSourceMock, __LEGACY: { diff --git a/src/plugins/data/public/search/search_service.test.ts b/src/plugins/data/public/search/search_service.test.ts index b1f7925bec4bb..fa138cef1a4a0 100644 --- a/src/plugins/data/public/search/search_service.test.ts +++ b/src/plugins/data/public/search/search_service.test.ts @@ -38,7 +38,7 @@ describe('Search service', () => { packageInfo: { version: '8' }, expressions: expressionsPluginMock.createSetupContract(), } as any); - expect(setup).toHaveProperty('registerSearchStrategyProvider'); + expect(setup).toHaveProperty('registerSearchStrategy'); }); }); }); diff --git a/src/plugins/data/public/search/search_service.ts b/src/plugins/data/public/search/search_service.ts index 1615aac9e7b7d..d5997c15817f6 100644 --- a/src/plugins/data/public/search/search_service.ts +++ b/src/plugins/data/public/search/search_service.ts @@ -18,11 +18,11 @@ */ import { Plugin, CoreSetup, CoreStart, PackageInfo } from '../../../../core/public'; +import { SYNC_SEARCH_STRATEGY, syncSearchStrategyProvider } from './sync_search_strategy'; +import { ISearchSetup, ISearchStart, TSearchStrategiesMap, ISearchStrategy } from './types'; import { ExpressionsSetup } from '../../../../plugins/expressions/public'; -import { SYNC_SEARCH_STRATEGY, syncSearchStrategyProvider } from './sync_search_strategy'; import { createSearchSource, SearchSource, SearchSourceDependencies } from './search_source'; -import { ISearchSetup, ISearchStart, TSearchStrategyProvider, TSearchStrategiesMap } from './types'; import { TStrategyTypes } from './strategy_types'; import { getEsClient, LegacyApiCaller } from './legacy'; import { ES_SEARCH_STRATEGY, DEFAULT_SEARCH_STRATEGY } from '../../common/search'; @@ -54,11 +54,8 @@ interface SearchServiceStartDependencies { } /** - * The search plugin exposes two registration methods for other plugins: - * - registerSearchStrategyProvider for plugins to add their own custom - * search strategies - * - registerSearchStrategyContext for plugins to expose information - * and/or functionality for other search strategies to use + * The search plugin exposes a method `registerSearchStrategy` for other plugins + * to add their own custom search strategies. * * It also comes with two search strategy implementations - SYNC_SEARCH_STRATEGY and ES_SEARCH_STRATEGY. */ @@ -73,17 +70,19 @@ export class SearchService implements Plugin { private readonly aggTypesRegistry = new AggTypesRegistry(); private searchInterceptor!: SearchInterceptor; - private registerSearchStrategyProvider = ( + private registerSearchStrategy = ( name: T, - strategyProvider: TSearchStrategyProvider + strategy: ISearchStrategy ) => { - this.searchStrategies[name] = strategyProvider; + this.searchStrategies[name] = strategy; }; - private getSearchStrategy = (name: T): TSearchStrategyProvider => { - const strategyProvider = this.searchStrategies[name]; - if (!strategyProvider) throw new Error(`Search strategy ${name} not found`); - return strategyProvider; + private getSearchStrategy = (name: T): ISearchStrategy => { + const strategy = this.searchStrategies[name]; + if (!strategy) { + throw new Error(`Search strategy ${name} not found`); + } + return strategy; }; public setup( @@ -91,8 +90,11 @@ export class SearchService implements Plugin { { expressions, packageInfo, query, getInternalStartServices }: SearchServiceSetupDependencies ): ISearchSetup { this.esClient = getEsClient(core.injectedMetadata, core.http, packageInfo); - this.registerSearchStrategyProvider(SYNC_SEARCH_STRATEGY, syncSearchStrategyProvider); - this.registerSearchStrategyProvider(ES_SEARCH_STRATEGY, esSearchStrategyProvider); + + const syncSearchStrategy = syncSearchStrategyProvider(core); + const esSearchStrategy = esSearchStrategyProvider(core, syncSearchStrategy); + this.registerSearchStrategy(SYNC_SEARCH_STRATEGY, syncSearchStrategy); + this.registerSearchStrategy(ES_SEARCH_STRATEGY, esSearchStrategy); const aggTypesSetup = this.aggTypesRegistry.setup(); @@ -114,7 +116,7 @@ export class SearchService implements Plugin { calculateAutoTimeExpression: getCalculateAutoTimeExpression(core.uiSettings), types: aggTypesSetup, }, - registerSearchStrategyProvider: this.registerSearchStrategyProvider, + registerSearchStrategy: this.registerSearchStrategy, }; } @@ -134,12 +136,10 @@ export class SearchService implements Plugin { const aggTypesStart = this.aggTypesRegistry.start(); const search: ISearchGeneric = (request, options, strategyName) => { - const strategyProvider = this.getSearchStrategy(strategyName || DEFAULT_SEARCH_STRATEGY); - const searchStrategy = strategyProvider({ - core, - getSearchStrategy: this.getSearchStrategy, - }); - return this.searchInterceptor.search(searchStrategy.search as any, request, options); + const { search: defaultSearch } = this.getSearchStrategy( + strategyName || DEFAULT_SEARCH_STRATEGY + ); + return this.searchInterceptor.search(defaultSearch as any, request, options); }; const legacySearch = { @@ -164,6 +164,7 @@ export class SearchService implements Plugin { }, types: aggTypesStart, }, + getSearchStrategy: this.getSearchStrategy, search, searchSource: { create: createSearchSource(dependencies.indexPatterns, searchSourceDependencies), diff --git a/src/plugins/data/public/search/search_source/search_source.ts b/src/plugins/data/public/search/search_source/search_source.ts index 38f4ce73713c8..b926739112e0e 100644 --- a/src/plugins/data/public/search/search_source/search_source.ts +++ b/src/plugins/data/public/search/search_source/search_source.ts @@ -75,12 +75,11 @@ import { CoreStart } from 'kibana/public'; import { normalizeSortRequest } from './normalize_sort_request'; import { filterDocvalueFields } from './filter_docvalue_fields'; import { fieldWildcardFilter } from '../../../../kibana_utils/public'; -import { META_FIELDS_SETTING, DOC_HIGHLIGHT_SETTING } from '../../../common'; import { IIndexPattern, ISearchGeneric, SearchRequest } from '../..'; import { SearchSourceOptions, SearchSourceFields } from './types'; import { FetchOptions, RequestFailure, getSearchParams, handleResponse } from '../fetch'; -import { getEsQueryConfig, buildEsQuery, Filter } from '../../../common'; +import { getEsQueryConfig, buildEsQuery, Filter, UI_SETTINGS } from '../../../common'; import { getHighlightRequest } from '../../../common/field_formats'; import { fetchSoon } from '../legacy'; import { extractReferences } from './extract_references'; @@ -251,7 +250,7 @@ export class SearchSource { this.history = [searchRequest]; let response; - if (uiSettings.get('courier:batchSearches')) { + if (uiSettings.get(UI_SETTINGS.COURIER_BATCH_SEARCHES)) { response = await this.legacyFetch(searchRequest, options); } else { response = this.fetch$(searchRequest, options.abortSignal).toPromise(); @@ -365,7 +364,7 @@ export class SearchSource { const sort = normalizeSortRequest( val, this.getField('index'), - uiSettings.get('sort:options') + uiSettings.get(UI_SETTINGS.SORT_OPTIONS) ); return addToBody(key, sort); default: @@ -425,7 +424,7 @@ export class SearchSource { // exclude source fields for this index pattern specified by the user const filter = fieldWildcardFilter( body._source.excludes, - uiSettings.get(META_FIELDS_SETTING) + uiSettings.get(UI_SETTINGS.META_FIELDS) ); body.docvalue_fields = body.docvalue_fields.filter((docvalueField: any) => filter(docvalueField.field) @@ -448,7 +447,7 @@ export class SearchSource { body.query = buildEsQuery(index, query, filters, esQueryConfigs); if (highlightAll && body.query) { - body.highlight = getHighlightRequest(body.query, uiSettings.get(DOC_HIGHLIGHT_SETTING)); + body.highlight = getHighlightRequest(body.query, uiSettings.get(UI_SETTINGS.DOC_HIGHLIGHT)); delete searchRequest.highlightAll; } diff --git a/src/plugins/data/public/search/sync_search_strategy.test.ts b/src/plugins/data/public/search/sync_search_strategy.test.ts index 6197980314b86..383a312fffad9 100644 --- a/src/plugins/data/public/search/sync_search_strategy.test.ts +++ b/src/plugins/data/public/search/sync_search_strategy.test.ts @@ -19,26 +19,23 @@ import { coreMock } from '../../../../core/public/mocks'; import { SYNC_SEARCH_STRATEGY, syncSearchStrategyProvider } from './sync_search_strategy'; -import { CoreStart } from 'kibana/public'; +import { CoreSetup } from 'kibana/public'; describe('Sync search strategy', () => { - let mockCoreStart: MockedKeys; + let mockCoreSetup: MockedKeys; beforeEach(() => { - mockCoreStart = coreMock.createStart(); + mockCoreSetup = coreMock.createSetup(); }); it('returns a strategy with `search` that calls the backend API', () => { - mockCoreStart.http.fetch.mockImplementationOnce(() => Promise.resolve()); + mockCoreSetup.http.fetch.mockImplementationOnce(() => Promise.resolve()); - const syncSearch = syncSearchStrategyProvider({ - core: mockCoreStart, - getSearchStrategy: jest.fn(), - }); + const syncSearch = syncSearchStrategyProvider(mockCoreSetup); const request = { serverStrategy: SYNC_SEARCH_STRATEGY }; syncSearch.search(request, {}); - expect(mockCoreStart.http.fetch.mock.calls[0][0]).toEqual({ + expect(mockCoreSetup.http.fetch.mock.calls[0][0]).toEqual({ path: `/internal/search/${SYNC_SEARCH_STRATEGY}`, body: JSON.stringify({ serverStrategy: 'SYNC_SEARCH_STRATEGY', @@ -52,15 +49,12 @@ describe('Sync search strategy', () => { const expectedLoadingCountValues = [0, 1, 0]; const receivedLoadingCountValues: number[] = []; - mockCoreStart.http.fetch.mockResolvedValueOnce('response'); + mockCoreSetup.http.fetch.mockResolvedValueOnce('response'); - const syncSearch = syncSearchStrategyProvider({ - core: mockCoreStart, - getSearchStrategy: jest.fn(), - }); + const syncSearch = syncSearchStrategyProvider(mockCoreSetup); const request = { serverStrategy: SYNC_SEARCH_STRATEGY }; - const loadingCount$ = mockCoreStart.http.addLoadingCountSource.mock.calls[0][0]; + const loadingCount$ = mockCoreSetup.http.addLoadingCountSource.mock.calls[0][0]; loadingCount$.subscribe((value) => receivedLoadingCountValues.push(value)); await syncSearch.search(request, {}).toPromise(); @@ -73,15 +67,12 @@ describe('Sync search strategy', () => { const expectedLoadingCountValues = [0, 1, 0]; const receivedLoadingCountValues: number[] = []; - mockCoreStart.http.fetch.mockRejectedValueOnce('error'); + mockCoreSetup.http.fetch.mockRejectedValueOnce('error'); - const syncSearch = syncSearchStrategyProvider({ - core: mockCoreStart, - getSearchStrategy: jest.fn(), - }); + const syncSearch = syncSearchStrategyProvider(mockCoreSetup); const request = { serverStrategy: SYNC_SEARCH_STRATEGY }; - const loadingCount$ = mockCoreStart.http.addLoadingCountSource.mock.calls[0][0]; + const loadingCount$ = mockCoreSetup.http.addLoadingCountSource.mock.calls[0][0]; loadingCount$.subscribe((value) => receivedLoadingCountValues.push(value)); try { diff --git a/src/plugins/data/public/search/sync_search_strategy.ts b/src/plugins/data/public/search/sync_search_strategy.ts index 860ce593ae217..25d2731df7d5c 100644 --- a/src/plugins/data/public/search/sync_search_strategy.ts +++ b/src/plugins/data/public/search/sync_search_strategy.ts @@ -19,9 +19,9 @@ import { BehaviorSubject, from } from 'rxjs'; import { finalize } from 'rxjs/operators'; +import { CoreSetup } from '../../../../core/public'; import { IKibanaSearchRequest } from '../../common/search'; -import { ISearch, ISearchOptions } from './i_search'; -import { TSearchStrategyProvider, ISearchStrategy, ISearchContext } from './types'; +import { ISearch } from './i_search'; export const SYNC_SEARCH_STRATEGY = 'SYNC_SEARCH_STRATEGY'; @@ -29,27 +29,22 @@ export interface ISyncSearchRequest extends IKibanaSearchRequest { serverStrategy: string; } -export const syncSearchStrategyProvider: TSearchStrategyProvider = ( - context: ISearchContext -): ISearchStrategy => { +export function syncSearchStrategyProvider(core: CoreSetup) { const loadingCount$ = new BehaviorSubject(0); - context.core.http.addLoadingCountSource(loadingCount$); + core.http.addLoadingCountSource(loadingCount$); - const search: ISearch = ( - request: ISyncSearchRequest, - options: ISearchOptions = {} - ) => { + const search: ISearch = (request, options) => { loadingCount$.next(loadingCount$.getValue() + 1); return from( - context.core.http.fetch({ + core.http.fetch({ path: `/internal/search/${request.serverStrategy}`, method: 'POST', body: JSON.stringify(request), - signal: options.signal, + signal: options?.signal, }) ).pipe(finalize(() => loadingCount$.next(loadingCount$.getValue() - 1))); }; return { search }; -}; +} diff --git a/src/plugins/data/public/search/types.ts b/src/plugins/data/public/search/types.ts index 64b4f1c5c2983..135974b697739 100644 --- a/src/plugins/data/public/search/types.ts +++ b/src/plugins/data/public/search/types.ts @@ -17,7 +17,6 @@ * under the License. */ -import { CoreStart } from 'kibana/public'; import { SearchAggsSetup, SearchAggsStart } from './aggs'; import { ISearch, ISearchGeneric } from './i_search'; import { TStrategyTypes } from './strategy_types'; @@ -25,11 +24,6 @@ import { LegacyApiCaller } from './legacy/es_client'; import { SearchInterceptor } from './search_interceptor'; import { ISearchSource, SearchSourceFields } from './search_source'; -export interface ISearchContext { - core: CoreStart; - getSearchStrategy: (name: T) => TSearchStrategyProvider; -} - /** * Search strategy interface contains a search method that takes in * a request and returns a promise that resolves to a response. @@ -39,27 +33,23 @@ export interface ISearchStrategy { } export type TSearchStrategiesMap = { - [K in TStrategyTypes]?: TSearchStrategyProvider; + [K in TStrategyTypes]?: ISearchStrategy; }; -/** - * Search strategy provider creates an instance of a search strategy with the request - * handler context bound to it. This way every search strategy can use - * whatever information they require from the request context. - */ -export type TSearchStrategyProvider = ( - context: ISearchContext -) => ISearchStrategy; - /** * Extension point exposed for other plugins to register their own search * strategies. */ -export type TRegisterSearchStrategyProvider = ( +export type TRegisterSearchStrategy = ( name: T, - searchStrategyProvider: TSearchStrategyProvider + searchStrategy: ISearchStrategy ) => void; +/** + * Used if a plugin needs access to an already registered search strategy. + */ +export type TGetSearchStrategy = (name: T) => ISearchStrategy; + export interface ISearchStartLegacy { esClient: LegacyApiCaller; } @@ -74,12 +64,18 @@ export interface ISearchSetup { * Extension point exposed for other plugins to register their own search * strategies. */ - registerSearchStrategyProvider: TRegisterSearchStrategyProvider; + registerSearchStrategy: TRegisterSearchStrategy; } export interface ISearchStart { aggs: SearchAggsStart; setInterceptor: (searchInterceptor: SearchInterceptor) => void; + + /** + * Used if a plugin needs access to an already registered search strategy. + */ + getSearchStrategy: TGetSearchStrategy; + search: ISearchGeneric; searchSource: { create: (fields?: SearchSourceFields) => Promise; diff --git a/src/plugins/data/public/ui/filter_bar/_global_filter_group.scss b/src/plugins/data/public/ui/filter_bar/_global_filter_group.scss index 1c47c28097454..731c9f4d7f18d 100644 --- a/src/plugins/data/public/ui/filter_bar/_global_filter_group.scss +++ b/src/plugins/data/public/ui/filter_bar/_global_filter_group.scss @@ -3,6 +3,10 @@ padding: 0px $euiSizeS $euiSizeS $euiSizeS; } +.globalQueryBar:first-child { + padding-top: $euiSizeS; +} + .globalQueryBar:not(:empty) { padding-bottom: $euiSizeS; } diff --git a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx index a54a25acc5913..43dba150bf8d4 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx @@ -36,6 +36,7 @@ import { toggleFilterDisabled, toggleFilterNegated, unpinFilter, + UI_SETTINGS, } from '../../../common'; interface Props { @@ -76,7 +77,7 @@ function FilterBarUI(props: Props) { } function renderAddFilter() { - const isPinned = uiSettings!.get('filters:pinnedByDefault'); + const isPinned = uiSettings!.get(UI_SETTINGS.FILTERS_PINNED_BY_DEFAULT); const [indexPattern] = props.indexPatterns; const index = indexPattern && indexPattern.id; const newFilter = buildEmptyFilter(isPinned, index); diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/phrase_suggestor.tsx b/src/plugins/data/public/ui/filter_bar/filter_editor/phrase_suggestor.tsx index 546365b89d9be..94138f60b52b1 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/phrase_suggestor.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/phrase_suggestor.tsx @@ -22,6 +22,7 @@ import { debounce } from 'lodash'; import { withKibana, KibanaReactContextValue } from '../../../../../kibana_react/public'; import { IDataPluginServices, IIndexPattern, IFieldType } from '../../..'; +import { UI_SETTINGS } from '../../../../common'; export interface PhraseSuggestorProps { kibana: KibanaReactContextValue; @@ -54,7 +55,9 @@ export class PhraseSuggestorUI extends React.Com } protected isSuggestingValues() { - const shouldSuggestValues = this.services.uiSettings.get('filterEditor:suggestValues'); + const shouldSuggestValues = this.services.uiSettings.get( + UI_SETTINGS.FILTERS_EDITOR_SUGGEST_VALUES + ); const { field } = this.props; return shouldSuggestValues && field && field.aggregatable && field.type === 'string'; } diff --git a/src/plugins/data/public/ui/filter_bar/filter_item.tsx b/src/plugins/data/public/ui/filter_bar/filter_item.tsx index c44e1faeb8e7f..053fca7d5773b 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_item.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_item.tsx @@ -74,7 +74,8 @@ export function FilterItem(props: Props) { setIndexPatternExists(false); }); } else { - setIndexPatternExists(false); + // Allow filters without an index pattern and don't validate them. + setIndexPatternExists(true); } }, [props.filter.meta.index]); @@ -244,6 +245,9 @@ export function FilterItem(props: Props) { * This function makes this behavior explicit, but it needs to be revised. */ function isFilterApplicable() { + // Any filter is applicable if no index patterns were provided to FilterBar. + if (!props.indexPatterns.length) return true; + const ip = getIndexPatternFromFilter(filter, indexPatterns); if (ip) return true; diff --git a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.test.tsx b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.test.tsx index f579adbc0c7e2..5f2d4c00cd6b6 100644 --- a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.test.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.test.tsx @@ -28,6 +28,7 @@ import { dataPluginMock } from '../../mocks'; import { KibanaContextProvider } from 'src/plugins/kibana_react/public'; import { I18nProvider } from '@kbn/i18n/react'; import { stubIndexPatternWithFields } from '../../stubs'; +import { UI_SETTINGS } from '../../../common'; const startMock = coreMock.createStart(); const mockTimeHistory = { @@ -38,7 +39,7 @@ const mockTimeHistory = { startMock.uiSettings.get.mockImplementation((key: string) => { switch (key) { - case 'timepicker:quickRanges': + case UI_SETTINGS.TIMEPICKER_QUICK_RANGES: return [ { from: 'now/d', @@ -48,7 +49,7 @@ startMock.uiSettings.get.mockImplementation((key: string) => { ]; case 'dateFormat': return 'MMM D, YYYY @ HH:mm:ss.SSS'; - case 'history:limit': + case UI_SETTINGS.HISTORY_LIMIT: return 10; case 'timepicker:timeDefaults': return { diff --git a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx index 433cb652ee5ce..f65bf97e391e2 100644 --- a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx @@ -38,7 +38,7 @@ import { Toast } from 'src/core/public'; import { IDataPluginServices, IIndexPattern, TimeRange, TimeHistoryContract, Query } from '../..'; import { useKibana, toMountPoint } from '../../../../kibana_react/public'; import { QueryStringInput } from './query_string_input'; -import { doesKueryExpressionHaveLuceneSyntaxError } from '../../../common'; +import { doesKueryExpressionHaveLuceneSyntaxError, UI_SETTINGS } from '../../../common'; import { PersistedLog, getQueryLog } from '../../query'; interface Props { @@ -255,7 +255,7 @@ export function QueryBarTopRow(props: Props) { } const commonlyUsedRanges = uiSettings! - .get('timepicker:quickRanges') + .get(UI_SETTINGS.TIMEPICKER_QUICK_RANGES) .map(({ from, to, display }: { from: string; to: string; display: string }) => { return { start: from, diff --git a/src/plugins/data/public/ui/search_bar/create_search_bar.tsx b/src/plugins/data/public/ui/search_bar/create_search_bar.tsx index 7723254f3aa51..81e84e3198072 100644 --- a/src/plugins/data/public/ui/search_bar/create_search_bar.tsx +++ b/src/plugins/data/public/ui/search_bar/create_search_bar.tsx @@ -27,7 +27,7 @@ import { useFilterManager } from './lib/use_filter_manager'; import { useTimefilter } from './lib/use_timefilter'; import { useSavedQuery } from './lib/use_saved_query'; import { DataPublicPluginStart } from '../../types'; -import { Filter, Query, TimeRange } from '../../../common'; +import { Filter, Query, TimeRange, UI_SETTINGS } from '../../../common'; interface StatefulSearchBarDeps { core: CoreStart; @@ -125,7 +125,8 @@ export function createSearchBar({ core, storage, data }: StatefulSearchBarDeps) const defaultQuery = { query: '', language: - storage.get('kibana.userQueryLanguage') || core.uiSettings.get('search:queryLanguage'), + storage.get('kibana.userQueryLanguage') || + core.uiSettings.get(UI_SETTINGS.SEARCH_QUERY_LANGUAGE), }; const [query, setQuery] = useState(props.query || defaultQuery); @@ -134,12 +135,14 @@ export function createSearchBar({ core, storage, data }: StatefulSearchBarDeps) queryRef.current = props.query; setQuery(props.query || defaultQuery); } + /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [defaultQuery, props.query]); useEffect(() => { if (props.onQuerySubmit !== onQuerySubmitRef.current) { onQuerySubmitRef.current = props.onQuerySubmit; } + /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [props.onQuerySubmit]); // handle service state updates. diff --git a/src/plugins/data/server/autocomplete/autocomplete_service.ts b/src/plugins/data/server/autocomplete/autocomplete_service.ts index 412e9b6236195..07f0ce0e7c1e5 100644 --- a/src/plugins/data/server/autocomplete/autocomplete_service.ts +++ b/src/plugins/data/server/autocomplete/autocomplete_service.ts @@ -17,14 +17,23 @@ * under the License. */ +import { TypeOf } from '@kbn/config-schema'; import { CoreSetup, Plugin, PluginInitializerContext } from 'kibana/server'; import { registerRoutes } from './routes'; +import { ConfigSchema, configSchema } from '../../config'; export class AutocompleteService implements Plugin { - constructor(private initializerContext: PluginInitializerContext) {} + private valueSuggestionsEnabled: boolean = true; + + constructor(private initializerContext: PluginInitializerContext) { + initializerContext.config.create>().subscribe((configUpdate) => { + this.valueSuggestionsEnabled = configUpdate.autocomplete.valueSuggestions.enabled; + }); + } public setup(core: CoreSetup) { - registerRoutes(core, this.initializerContext.config.legacy.globalConfig$); + if (this.valueSuggestionsEnabled) + registerRoutes(core, this.initializerContext.config.legacy.globalConfig$); } public start() {} diff --git a/src/plugins/data/server/index.ts b/src/plugins/data/server/index.ts index 47bef4255347c..831d23864d228 100644 --- a/src/plugins/data/server/index.ts +++ b/src/plugins/data/server/index.ts @@ -17,7 +17,8 @@ * under the License. */ -import { PluginInitializerContext } from '../../../core/server'; +import { PluginConfigDescriptor, PluginInitializerContext } from '../../../core/server'; +import { ConfigSchema, configSchema } from '../config'; import { DataServerPlugin, DataPluginSetup, DataPluginStart } from './plugin'; import { @@ -145,6 +146,7 @@ export { ES_FIELD_TYPES, KBN_FIELD_TYPES, IndexPatternAttributes, + UI_SETTINGS, } from '../common'; /** @@ -213,7 +215,7 @@ export { * @public */ -export function plugin(initializerContext: PluginInitializerContext) { +export function plugin(initializerContext: PluginInitializerContext) { return new DataServerPlugin(initializerContext); } @@ -222,3 +224,10 @@ export { DataPluginSetup as PluginSetup, DataPluginStart as PluginStart, }; + +export const config: PluginConfigDescriptor = { + exposeToBrowser: { + autocomplete: true, + }, + schema: configSchema, +}; diff --git a/src/plugins/data/server/kql_telemetry/usage_collector/fetch.test.ts b/src/plugins/data/server/kql_telemetry/usage_collector/fetch.test.ts index 446320b09757a..81e352fea51b2 100644 --- a/src/plugins/data/server/kql_telemetry/usage_collector/fetch.test.ts +++ b/src/plugins/data/server/kql_telemetry/usage_collector/fetch.test.ts @@ -22,6 +22,9 @@ import { APICaller } from 'kibana/server'; jest.mock('../../../common', () => ({ DEFAULT_QUERY_LANGUAGE: 'lucene', + UI_SETTINGS: { + SEARCH_QUERY_LANGUAGE: 'search:queryLanguage', + }, })); let fetch: ReturnType; diff --git a/src/plugins/data/server/kql_telemetry/usage_collector/fetch.ts b/src/plugins/data/server/kql_telemetry/usage_collector/fetch.ts index 9f3437161541f..157716b38f523 100644 --- a/src/plugins/data/server/kql_telemetry/usage_collector/fetch.ts +++ b/src/plugins/data/server/kql_telemetry/usage_collector/fetch.ts @@ -19,7 +19,7 @@ import { get } from 'lodash'; import { APICaller } from 'kibana/server'; -import { DEFAULT_QUERY_LANGUAGE } from '../../../common'; +import { DEFAULT_QUERY_LANGUAGE, UI_SETTINGS } from '../../../common'; const defaultSearchQueryLanguageSetting = DEFAULT_QUERY_LANGUAGE; @@ -40,7 +40,7 @@ export function fetchProvider(index: string) { const queryLanguageConfigValue = get( config, - 'hits.hits[0]._source.config.search:queryLanguage' + `hits.hits[0]._source.config.${UI_SETTINGS.SEARCH_QUERY_LANGUAGE}` ); // search:queryLanguage can potentially be in four states in the .kibana index: diff --git a/src/plugins/data/server/plugin.ts b/src/plugins/data/server/plugin.ts index 83a5358642ce4..8c9d0df2ed894 100644 --- a/src/plugins/data/server/plugin.ts +++ b/src/plugins/data/server/plugin.ts @@ -18,6 +18,7 @@ */ import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '../../../core/server'; +import { ConfigSchema } from '../config'; import { IndexPatternsService } from './index_patterns'; import { ISearchSetup } from './search'; import { SearchService } from './search/search_service'; @@ -27,7 +28,7 @@ import { KqlTelemetryService } from './kql_telemetry'; import { UsageCollectionSetup } from '../../usage_collection/server'; import { AutocompleteService } from './autocomplete'; import { FieldFormatsService, FieldFormatsSetup, FieldFormatsStart } from './field_formats'; -import { uiSettings } from './ui_settings'; +import { getUiSettings } from './ui_settings'; export interface DataPluginSetup { search: ISearchSetup; @@ -51,7 +52,7 @@ export class DataServerPlugin implements Plugin) { this.searchService = new SearchService(initializerContext); this.scriptsService = new ScriptsService(); this.kqlTelemetryService = new KqlTelemetryService(initializerContext); @@ -64,7 +65,8 @@ export class DataServerPlugin implements Plugin KBN_FIELD_TYPES; +// Warning: (ae-forgotten-export) The symbol "PluginConfigDescriptor" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "ConfigSchema" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "config" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const config: PluginConfigDescriptor; + // @public (undocumented) export enum ES_FIELD_TYPES { // (undocumented) @@ -604,7 +611,7 @@ export function parseInterval(interval: string): moment.Duration | null; // @public (undocumented) export class Plugin implements Plugin_2 { // Warning: (ae-forgotten-export) The symbol "PluginInitializerContext" needs to be exported by the entry point index.d.ts - constructor(initializerContext: PluginInitializerContext); + constructor(initializerContext: PluginInitializerContext); // Warning: (ae-forgotten-export) The symbol "DataPluginSetupDependencies" needs to be exported by the entry point index.d.ts // // (undocumented) @@ -627,7 +634,7 @@ export class Plugin implements Plugin_2 { } // @public -export function plugin(initializerContext: PluginInitializerContext): Plugin; +export function plugin(initializerContext: PluginInitializerContext): Plugin; // Warning: (ae-missing-release-tag) "DataPluginSetup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -713,38 +720,71 @@ export interface TimeRange { // @public export type TSearchStrategyProvider = (context: ISearchContext, caller: APICaller_2, search: ISearchGeneric) => ISearchStrategy; +// Warning: (ae-missing-release-tag) "UI_SETTINGS" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const UI_SETTINGS: { + META_FIELDS: string; + DOC_HIGHLIGHT: string; + QUERY_STRING_OPTIONS: string; + QUERY_ALLOW_LEADING_WILDCARDS: string; + SEARCH_QUERY_LANGUAGE: string; + SORT_OPTIONS: string; + COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX: string; + COURIER_SET_REQUEST_PREFERENCE: string; + COURIER_CUSTOM_REQUEST_PREFERENCE: string; + COURIER_MAX_CONCURRENT_SHARD_REQUESTS: string; + COURIER_BATCH_SEARCHES: string; + SEARCH_INCLUDE_FROZEN: string; + HISTOGRAM_BAR_TARGET: string; + HISTOGRAM_MAX_BARS: string; + HISTORY_LIMIT: string; + SHORT_DOTS_ENABLE: string; + FORMAT_DEFAULT_TYPE_MAP: string; + FORMAT_NUMBER_DEFAULT_PATTERN: string; + FORMAT_PERCENT_DEFAULT_PATTERN: string; + FORMAT_BYTES_DEFAULT_PATTERN: string; + FORMAT_CURRENCY_DEFAULT_PATTERN: string; + FORMAT_NUMBER_DEFAULT_LOCALE: string; + TIMEPICKER_REFRESH_INTERVAL_DEFAULTS: string; + TIMEPICKER_QUICK_RANGES: string; + INDEXPATTERN_PLACEHOLDER: string; + FILTERS_PINNED_BY_DEFAULT: string; + FILTERS_EDITOR_SUGGEST_VALUES: string; +}; + // Warnings were encountered during analysis: // -// src/plugins/data/server/index.ts:39:23 - (ae-forgotten-export) The symbol "buildCustomFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:39:23 - (ae-forgotten-export) The symbol "buildFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:70:21 - (ae-forgotten-export) The symbol "getEsQueryConfig" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:70:21 - (ae-forgotten-export) The symbol "buildEsQuery" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "FieldFormatsRegistry" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "FieldFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "BoolFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "BytesFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "ColorFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "DateNanosFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "DurationFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "IpFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "NumberFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "PercentFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "RelativeDateFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "SourceFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "StaticLookupFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "UrlFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "StringFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:102:26 - (ae-forgotten-export) The symbol "TruncateFormat" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:130:27 - (ae-forgotten-export) The symbol "isFilterable" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:130:27 - (ae-forgotten-export) The symbol "isNestedField" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:182:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:183:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:184:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:185:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:186:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/index.ts:189:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts -// src/plugins/data/server/plugin.ts:65:14 - (ae-forgotten-export) The symbol "ISearchSetup" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:40:23 - (ae-forgotten-export) The symbol "buildCustomFilter" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:40:23 - (ae-forgotten-export) The symbol "buildFilter" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:71:21 - (ae-forgotten-export) The symbol "getEsQueryConfig" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:71:21 - (ae-forgotten-export) The symbol "buildEsQuery" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "FieldFormatsRegistry" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "FieldFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "BoolFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "BytesFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "ColorFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "DateNanosFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "DurationFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "IpFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "NumberFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "PercentFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "RelativeDateFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "SourceFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "StaticLookupFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "UrlFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "StringFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:103:26 - (ae-forgotten-export) The symbol "TruncateFormat" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:131:27 - (ae-forgotten-export) The symbol "isFilterable" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:131:27 - (ae-forgotten-export) The symbol "isNestedField" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:184:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:185:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:186:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:187:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:188:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/index.ts:191:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/plugin.ts:66:14 - (ae-forgotten-export) The symbol "ISearchSetup" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/src/plugins/data/server/ui_settings.ts b/src/plugins/data/server/ui_settings.ts index 5af62be295201..de978c7968aee 100644 --- a/src/plugins/data/server/ui_settings.ts +++ b/src/plugins/data/server/ui_settings.ts @@ -19,33 +19,652 @@ import { i18n } from '@kbn/i18n'; import { schema } from '@kbn/config-schema'; - import { UiSettingsParams } from 'kibana/server'; -import { META_FIELDS_SETTING, DOC_HIGHLIGHT_SETTING } from '../common'; +// @ts-ignore untyped module +import numeralLanguages from '@elastic/numeral/languages'; +import { DEFAULT_QUERY_LANGUAGE, UI_SETTINGS } from '../common'; + +const luceneQueryLanguageLabel = i18n.translate('data.advancedSettings.searchQueryLanguageLucene', { + defaultMessage: 'Lucene', +}); + +const queryLanguageSettingName = i18n.translate('data.advancedSettings.searchQueryLanguageTitle', { + defaultMessage: 'Query language', +}); -export const uiSettings: Record = { - [META_FIELDS_SETTING]: { - name: i18n.translate('data.advancedSettings.metaFieldsTitle', { - defaultMessage: 'Meta fields', - }), - value: ['_source', '_id', '_type', '_index', '_score'], - description: i18n.translate('data.advancedSettings.metaFieldsText', { - defaultMessage: - 'Fields that exist outside of _source to merge into our document when displaying it', - }), - schema: schema.arrayOf(schema.string()), - }, - [DOC_HIGHLIGHT_SETTING]: { - name: i18n.translate('data.advancedSettings.docTableHighlightTitle', { - defaultMessage: 'Highlight results', - }), - value: true, - description: i18n.translate('data.advancedSettings.docTableHighlightText', { - defaultMessage: - 'Highlight results in Discover and Saved Searches Dashboard. ' + - 'Highlighting makes requests slow when working on big documents.', - }), - category: ['discover'], - schema: schema.boolean(), - }, +const requestPreferenceOptionLabels = { + sessionId: i18n.translate('data.advancedSettings.courier.requestPreferenceSessionId', { + defaultMessage: 'Session ID', + }), + custom: i18n.translate('data.advancedSettings.courier.requestPreferenceCustom', { + defaultMessage: 'Custom', + }), + none: i18n.translate('data.advancedSettings.courier.requestPreferenceNone', { + defaultMessage: 'None', + }), }; + +// We add the `en` key manually here, since that's not a real numeral locale, but the +// default fallback in case the locale is not found. +const numeralLanguageIds = [ + 'en', + ...numeralLanguages.map((numeralLanguage: any) => { + return numeralLanguage.id; + }), +]; + +export function getUiSettings(): Record> { + return { + [UI_SETTINGS.META_FIELDS]: { + name: i18n.translate('data.advancedSettings.metaFieldsTitle', { + defaultMessage: 'Meta fields', + }), + value: ['_source', '_id', '_type', '_index', '_score'], + description: i18n.translate('data.advancedSettings.metaFieldsText', { + defaultMessage: + 'Fields that exist outside of _source to merge into our document when displaying it', + }), + schema: schema.arrayOf(schema.string()), + }, + [UI_SETTINGS.DOC_HIGHLIGHT]: { + name: i18n.translate('data.advancedSettings.docTableHighlightTitle', { + defaultMessage: 'Highlight results', + }), + value: true, + description: i18n.translate('data.advancedSettings.docTableHighlightText', { + defaultMessage: + 'Highlight results in Discover and Saved Searches Dashboard. ' + + 'Highlighting makes requests slow when working on big documents.', + }), + category: ['discover'], + schema: schema.boolean(), + }, + [UI_SETTINGS.QUERY_STRING_OPTIONS]: { + name: i18n.translate('data.advancedSettings.query.queryStringOptionsTitle', { + defaultMessage: 'Query string options', + }), + value: '{ "analyze_wildcard": true }', + description: i18n.translate('data.advancedSettings.query.queryStringOptionsText', { + defaultMessage: + '{optionsLink} for the lucene query string parser. Is only used when "{queryLanguage}" is set ' + + 'to {luceneLanguage}.', + description: + 'Part of composite text: data.advancedSettings.query.queryStringOptions.optionsLinkText + ' + + 'data.advancedSettings.query.queryStringOptionsText', + values: { + optionsLink: + '' + + i18n.translate('data.advancedSettings.query.queryStringOptions.optionsLinkText', { + defaultMessage: 'Options', + }) + + '', + luceneLanguage: luceneQueryLanguageLabel, + queryLanguage: queryLanguageSettingName, + }, + }), + type: 'json', + schema: schema.object({ + analyze_wildcard: schema.boolean(), + }), + }, + [UI_SETTINGS.QUERY_ALLOW_LEADING_WILDCARDS]: { + name: i18n.translate('data.advancedSettings.query.allowWildcardsTitle', { + defaultMessage: 'Allow leading wildcards in query', + }), + value: true, + description: i18n.translate('data.advancedSettings.query.allowWildcardsText', { + defaultMessage: + 'When set, * is allowed as the first character in a query clause. ' + + 'Currently only applies when experimental query features are enabled in the query bar. ' + + 'To disallow leading wildcards in basic lucene queries, use {queryStringOptionsPattern}.', + values: { + queryStringOptionsPattern: UI_SETTINGS.QUERY_STRING_OPTIONS, + }, + }), + schema: schema.boolean(), + }, + [UI_SETTINGS.SEARCH_QUERY_LANGUAGE]: { + name: queryLanguageSettingName, + value: DEFAULT_QUERY_LANGUAGE, + description: i18n.translate('data.advancedSettings.searchQueryLanguageText', { + defaultMessage: + 'Query language used by the query bar. KQL is a new language built specifically for Kibana.', + }), + type: 'select', + options: ['lucene', 'kuery'], + optionLabels: { + lucene: luceneQueryLanguageLabel, + kuery: i18n.translate('data.advancedSettings.searchQueryLanguageKql', { + defaultMessage: 'KQL', + }), + }, + schema: schema.string(), + }, + [UI_SETTINGS.SORT_OPTIONS]: { + name: i18n.translate('data.advancedSettings.sortOptionsTitle', { + defaultMessage: 'Sort options', + }), + value: '{ "unmapped_type": "boolean" }', + description: i18n.translate('data.advancedSettings.sortOptionsText', { + defaultMessage: '{optionsLink} for the Elasticsearch sort parameter', + description: + 'Part of composite text: data.advancedSettings.sortOptions.optionsLinkText + ' + + 'data.advancedSettings.sortOptionsText', + values: { + optionsLink: + '' + + i18n.translate('data.advancedSettings.sortOptions.optionsLinkText', { + defaultMessage: 'Options', + }) + + '', + }, + }), + type: 'json', + schema: schema.object({ + unmapped_type: schema.string(), + }), + }, + defaultIndex: { + name: i18n.translate('data.advancedSettings.defaultIndexTitle', { + defaultMessage: 'Default index', + }), + value: null, + type: 'string', + description: i18n.translate('data.advancedSettings.defaultIndexText', { + defaultMessage: 'The index to access if no index is set', + }), + schema: schema.nullable(schema.string()), + }, + [UI_SETTINGS.COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX]: { + name: i18n.translate('data.advancedSettings.courier.ignoreFilterTitle', { + defaultMessage: 'Ignore filter(s)', + }), + value: false, + description: i18n.translate('data.advancedSettings.courier.ignoreFilterText', { + defaultMessage: + 'This configuration enhances support for dashboards containing visualizations accessing dissimilar indexes. ' + + 'When disabled, all filters are applied to all visualizations. ' + + 'When enabled, filter(s) will be ignored for a visualization ' + + `when the visualization's index does not contain the filtering field.`, + }), + category: ['search'], + schema: schema.boolean(), + }, + [UI_SETTINGS.COURIER_SET_REQUEST_PREFERENCE]: { + name: i18n.translate('data.advancedSettings.courier.requestPreferenceTitle', { + defaultMessage: 'Request preference', + }), + value: 'sessionId', + options: ['sessionId', 'custom', 'none'], + optionLabels: requestPreferenceOptionLabels, + type: 'select', + description: i18n.translate('data.advancedSettings.courier.requestPreferenceText', { + defaultMessage: `Allows you to set which shards handle your search requests. +
    +
  • {sessionId}: restricts operations to execute all search requests on the same shards. + This has the benefit of reusing shard caches across requests.
  • +
  • {custom}: allows you to define a your own preference. + Use 'courier:customRequestPreference' to customize your preference value.
  • +
  • {none}: means do not set a preference. + This might provide better performance because requests can be spread across all shard copies. + However, results might be inconsistent because different shards might be in different refresh states.
  • +
`, + values: { + sessionId: requestPreferenceOptionLabels.sessionId, + custom: requestPreferenceOptionLabels.custom, + none: requestPreferenceOptionLabels.none, + }, + }), + category: ['search'], + schema: schema.string(), + }, + [UI_SETTINGS.COURIER_CUSTOM_REQUEST_PREFERENCE]: { + name: i18n.translate('data.advancedSettings.courier.customRequestPreferenceTitle', { + defaultMessage: 'Custom request preference', + }), + value: '_local', + type: 'string', + description: i18n.translate('data.advancedSettings.courier.customRequestPreferenceText', { + defaultMessage: + '{requestPreferenceLink} used when {setRequestReferenceSetting} is set to {customSettingValue}.', + description: + 'Part of composite text: data.advancedSettings.courier.customRequestPreference.requestPreferenceLinkText + ' + + 'data.advancedSettings.courier.customRequestPreferenceText', + values: { + setRequestReferenceSetting: `${UI_SETTINGS.COURIER_SET_REQUEST_PREFERENCE}`, + customSettingValue: '"custom"', + requestPreferenceLink: + '' + + i18n.translate( + 'data.advancedSettings.courier.customRequestPreference.requestPreferenceLinkText', + { + defaultMessage: 'Request Preference', + } + ) + + '', + }, + }), + category: ['search'], + schema: schema.string(), + }, + [UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS]: { + name: i18n.translate('data.advancedSettings.courier.maxRequestsTitle', { + defaultMessage: 'Max Concurrent Shard Requests', + }), + value: 0, + type: 'number', + description: i18n.translate('data.advancedSettings.courier.maxRequestsText', { + defaultMessage: + 'Controls the {maxRequestsLink} setting used for _msearch requests sent by Kibana. ' + + 'Set to 0 to disable this config and use the Elasticsearch default.', + values: { + maxRequestsLink: `max_concurrent_shard_requests`, + }, + }), + category: ['search'], + schema: schema.number(), + }, + [UI_SETTINGS.COURIER_BATCH_SEARCHES]: { + name: i18n.translate('data.advancedSettings.courier.batchSearchesTitle', { + defaultMessage: 'Batch concurrent searches', + }), + value: false, + type: 'boolean', + description: i18n.translate('data.advancedSettings.courier.batchSearchesText', { + defaultMessage: `When disabled, dashboard panels will load individually, and search requests will terminate when users navigate + away or update the query. When enabled, dashboard panels will load together when all of the data is loaded, and + searches will not terminate.`, + }), + deprecation: { + message: i18n.translate('data.advancedSettings.courier.batchSearchesTextDeprecation', { + defaultMessage: 'This setting is deprecated and will be removed in Kibana 8.0.', + }), + docLinksKey: 'kibanaSearchSettings', + }, + category: ['search'], + schema: schema.boolean(), + }, + [UI_SETTINGS.SEARCH_INCLUDE_FROZEN]: { + name: 'Search in frozen indices', + description: `Will include frozen indices in results if enabled. Searching through frozen indices + might increase the search time.`, + value: false, + category: ['search'], + schema: schema.boolean(), + }, + [UI_SETTINGS.HISTOGRAM_BAR_TARGET]: { + name: i18n.translate('data.advancedSettings.histogram.barTargetTitle', { + defaultMessage: 'Target bars', + }), + value: 50, + description: i18n.translate('data.advancedSettings.histogram.barTargetText', { + defaultMessage: + 'Attempt to generate around this many bars when using "auto" interval in date histograms', + }), + schema: schema.number(), + }, + [UI_SETTINGS.HISTOGRAM_MAX_BARS]: { + name: i18n.translate('data.advancedSettings.histogram.maxBarsTitle', { + defaultMessage: 'Maximum bars', + }), + value: 100, + description: i18n.translate('data.advancedSettings.histogram.maxBarsText', { + defaultMessage: + 'Never show more than this many bars in date histograms, scale values if needed', + }), + schema: schema.number(), + }, + [UI_SETTINGS.HISTORY_LIMIT]: { + name: i18n.translate('data.advancedSettings.historyLimitTitle', { + defaultMessage: 'History limit', + }), + value: 10, + description: i18n.translate('data.advancedSettings.historyLimitText', { + defaultMessage: + 'In fields that have history (e.g. query inputs), show this many recent values', + }), + schema: schema.number(), + }, + [UI_SETTINGS.SHORT_DOTS_ENABLE]: { + name: i18n.translate('data.advancedSettings.shortenFieldsTitle', { + defaultMessage: 'Shorten fields', + }), + value: false, + description: i18n.translate('data.advancedSettings.shortenFieldsText', { + defaultMessage: 'Shorten long fields, for example, instead of foo.bar.baz, show f.b.baz', + }), + schema: schema.boolean(), + }, + [UI_SETTINGS.FORMAT_DEFAULT_TYPE_MAP]: { + name: i18n.translate('data.advancedSettings.format.defaultTypeMapTitle', { + defaultMessage: 'Field type format name', + }), + value: `{ + "ip": { "id": "ip", "params": {} }, + "date": { "id": "date", "params": {} }, + "date_nanos": { "id": "date_nanos", "params": {}, "es": true }, + "number": { "id": "number", "params": {} }, + "boolean": { "id": "boolean", "params": {} }, + "_source": { "id": "_source", "params": {} }, + "_default_": { "id": "string", "params": {} } +}`, + type: 'json', + description: i18n.translate('data.advancedSettings.format.defaultTypeMapText', { + defaultMessage: + 'Map of the format name to use by default for each field type. ' + + '{defaultFormat} is used if the field type is not mentioned explicitly', + values: { + defaultFormat: '"_default_"', + }, + }), + schema: schema.object({ + ip: schema.object({ + id: schema.string(), + params: schema.object({}), + }), + date: schema.object({ + id: schema.string(), + params: schema.object({}), + }), + date_nanos: schema.object({ + id: schema.string(), + params: schema.object({}), + es: schema.boolean(), + }), + number: schema.object({ + id: schema.string(), + params: schema.object({}), + }), + boolean: schema.object({ + id: schema.string(), + params: schema.object({}), + }), + _source: schema.object({ + id: schema.string(), + params: schema.object({}), + }), + _default_: schema.object({ + id: schema.string(), + params: schema.object({}), + }), + }), + }, + [UI_SETTINGS.FORMAT_NUMBER_DEFAULT_PATTERN]: { + name: i18n.translate('data.advancedSettings.format.numberFormatTitle', { + defaultMessage: 'Number format', + }), + value: '0,0.[000]', + type: 'string', + description: i18n.translate('data.advancedSettings.format.numberFormatText', { + defaultMessage: 'Default {numeralFormatLink} for the "number" format', + description: + 'Part of composite text: data.advancedSettings.format.numberFormatText + ' + + 'data.advancedSettings.format.numberFormat.numeralFormatLinkText', + values: { + numeralFormatLink: + '' + + i18n.translate('data.advancedSettings.format.numberFormat.numeralFormatLinkText', { + defaultMessage: 'numeral format', + }) + + '', + }, + }), + schema: schema.string(), + }, + [UI_SETTINGS.FORMAT_PERCENT_DEFAULT_PATTERN]: { + name: i18n.translate('data.advancedSettings.format.percentFormatTitle', { + defaultMessage: 'Percent format', + }), + value: '0,0.[000]%', + type: 'string', + description: i18n.translate('data.advancedSettings.format.percentFormatText', { + defaultMessage: 'Default {numeralFormatLink} for the "percent" format', + description: + 'Part of composite text: data.advancedSettings.format.percentFormatText + ' + + 'data.advancedSettings.format.percentFormat.numeralFormatLinkText', + values: { + numeralFormatLink: + '' + + i18n.translate('data.advancedSettings.format.percentFormat.numeralFormatLinkText', { + defaultMessage: 'numeral format', + }) + + '', + }, + }), + schema: schema.string(), + }, + [UI_SETTINGS.FORMAT_BYTES_DEFAULT_PATTERN]: { + name: i18n.translate('data.advancedSettings.format.bytesFormatTitle', { + defaultMessage: 'Bytes format', + }), + value: '0,0.[0]b', + type: 'string', + description: i18n.translate('data.advancedSettings.format.bytesFormatText', { + defaultMessage: 'Default {numeralFormatLink} for the "bytes" format', + description: + 'Part of composite text: data.advancedSettings.format.bytesFormatText + ' + + 'data.advancedSettings.format.bytesFormat.numeralFormatLinkText', + values: { + numeralFormatLink: + '' + + i18n.translate('data.advancedSettings.format.bytesFormat.numeralFormatLinkText', { + defaultMessage: 'numeral format', + }) + + '', + }, + }), + schema: schema.string(), + }, + [UI_SETTINGS.FORMAT_CURRENCY_DEFAULT_PATTERN]: { + name: i18n.translate('data.advancedSettings.format.currencyFormatTitle', { + defaultMessage: 'Currency format', + }), + value: '($0,0.[00])', + type: 'string', + description: i18n.translate('data.advancedSettings.format.currencyFormatText', { + defaultMessage: 'Default {numeralFormatLink} for the "currency" format', + description: + 'Part of composite text: data.advancedSettings.format.currencyFormatText + ' + + 'data.advancedSettings.format.currencyFormat.numeralFormatLinkText', + values: { + numeralFormatLink: + '' + + i18n.translate('data.advancedSettings.format.currencyFormat.numeralFormatLinkText', { + defaultMessage: 'numeral format', + }) + + '', + }, + }), + schema: schema.string(), + }, + [UI_SETTINGS.FORMAT_NUMBER_DEFAULT_LOCALE]: { + name: i18n.translate('data.advancedSettings.format.formattingLocaleTitle', { + defaultMessage: 'Formatting locale', + }), + value: 'en', + type: 'select', + options: numeralLanguageIds, + optionLabels: Object.fromEntries( + numeralLanguages.map((language: Record) => [language.id, language.name]) + ), + description: i18n.translate('data.advancedSettings.format.formattingLocaleText', { + defaultMessage: `{numeralLanguageLink} locale`, + description: + 'Part of composite text: data.advancedSettings.format.formattingLocale.numeralLanguageLinkText + ' + + 'data.advancedSettings.format.formattingLocaleText', + values: { + numeralLanguageLink: + '' + + i18n.translate( + 'data.advancedSettings.format.formattingLocale.numeralLanguageLinkText', + { + defaultMessage: 'Numeral language', + } + ) + + '', + }, + }), + schema: schema.string(), + }, + [UI_SETTINGS.TIMEPICKER_REFRESH_INTERVAL_DEFAULTS]: { + name: i18n.translate('data.advancedSettings.timepicker.refreshIntervalDefaultsTitle', { + defaultMessage: 'Time filter refresh interval', + }), + value: `{ + "pause": false, + "value": 0 +}`, + type: 'json', + description: i18n.translate('data.advancedSettings.timepicker.refreshIntervalDefaultsText', { + defaultMessage: `The timefilter's default refresh interval`, + }), + requiresPageReload: true, + schema: schema.object({ + pause: schema.boolean(), + value: schema.number(), + }), + }, + [UI_SETTINGS.TIMEPICKER_QUICK_RANGES]: { + name: i18n.translate('data.advancedSettings.timepicker.quickRangesTitle', { + defaultMessage: 'Time filter quick ranges', + }), + value: JSON.stringify( + [ + { + from: 'now/d', + to: 'now/d', + display: i18n.translate('data.advancedSettings.timepicker.today', { + defaultMessage: 'Today', + }), + }, + { + from: 'now/w', + to: 'now/w', + display: i18n.translate('data.advancedSettings.timepicker.thisWeek', { + defaultMessage: 'This week', + }), + }, + { + from: 'now-15m', + to: 'now', + display: i18n.translate('data.advancedSettings.timepicker.last15Minutes', { + defaultMessage: 'Last 15 minutes', + }), + }, + { + from: 'now-30m', + to: 'now', + display: i18n.translate('data.advancedSettings.timepicker.last30Minutes', { + defaultMessage: 'Last 30 minutes', + }), + }, + { + from: 'now-1h', + to: 'now', + display: i18n.translate('data.advancedSettings.timepicker.last1Hour', { + defaultMessage: 'Last 1 hour', + }), + }, + { + from: 'now-24h', + to: 'now', + display: i18n.translate('data.advancedSettings.timepicker.last24Hours', { + defaultMessage: 'Last 24 hours', + }), + }, + { + from: 'now-7d', + to: 'now', + display: i18n.translate('data.advancedSettings.timepicker.last7Days', { + defaultMessage: 'Last 7 days', + }), + }, + { + from: 'now-30d', + to: 'now', + display: i18n.translate('data.advancedSettings.timepicker.last30Days', { + defaultMessage: 'Last 30 days', + }), + }, + { + from: 'now-90d', + to: 'now', + display: i18n.translate('data.advancedSettings.timepicker.last90Days', { + defaultMessage: 'Last 90 days', + }), + }, + { + from: 'now-1y', + to: 'now', + display: i18n.translate('data.advancedSettings.timepicker.last1Year', { + defaultMessage: 'Last 1 year', + }), + }, + ], + null, + 2 + ), + type: 'json', + description: i18n.translate('data.advancedSettings.timepicker.quickRangesText', { + defaultMessage: + 'The list of ranges to show in the Quick section of the time filter. This should be an array of objects, ' + + 'with each object containing "from", "to" (see {acceptedFormatsLink}), and ' + + '"display" (the title to be displayed).', + description: + 'Part of composite text: data.advancedSettings.timepicker.quickRangesText + ' + + 'data.advancedSettings.timepicker.quickRanges.acceptedFormatsLinkText', + values: { + acceptedFormatsLink: + `` + + i18n.translate('data.advancedSettings.timepicker.quickRanges.acceptedFormatsLinkText', { + defaultMessage: 'accepted formats', + }) + + '', + }, + }), + schema: schema.arrayOf( + schema.object({ + from: schema.string(), + to: schema.string(), + display: schema.string(), + }) + ), + }, + [UI_SETTINGS.INDEXPATTERN_PLACEHOLDER]: { + name: i18n.translate('data.advancedSettings.indexPatternPlaceholderTitle', { + defaultMessage: 'Index pattern placeholder', + }), + value: '', + description: i18n.translate('data.advancedSettings.indexPatternPlaceholderText', { + defaultMessage: + 'The placeholder for the "Index pattern name" field in "Management > Index Patterns > Create Index Pattern".', + }), + schema: schema.string(), + }, + [UI_SETTINGS.FILTERS_PINNED_BY_DEFAULT]: { + name: i18n.translate('data.advancedSettings.pinFiltersTitle', { + defaultMessage: 'Pin filters by default', + }), + value: false, + description: i18n.translate('data.advancedSettings.pinFiltersText', { + defaultMessage: 'Whether the filters should have a global state (be pinned) by default', + }), + schema: schema.boolean(), + }, + [UI_SETTINGS.FILTERS_EDITOR_SUGGEST_VALUES]: { + name: i18n.translate('data.advancedSettings.suggestFilterValuesTitle', { + defaultMessage: 'Filter editor suggest values', + description: '"Filter editor" refers to the UI you create filters in.', + }), + value: true, + description: i18n.translate('data.advancedSettings.suggestFilterValuesText', { + defaultMessage: + 'Set this property to false to prevent the filter editor from suggesting values for fields.', + }), + schema: schema.boolean(), + }, + }; +} diff --git a/src/plugins/discover/kibana.json b/src/plugins/discover/kibana.json index 0b3a07e98624e..14dd399697b56 100644 --- a/src/plugins/discover/kibana.json +++ b/src/plugins/discover/kibana.json @@ -1,6 +1,7 @@ { "id": "discover", "version": "kibana", + "optionalPlugins": ["share"], "server": true, "ui": true, "requiredPlugins": [ diff --git a/src/plugins/discover/public/application/angular/discover.js b/src/plugins/discover/public/application/angular/discover.js index 1a2bff8211db5..88885b3eb211b 100644 --- a/src/plugins/discover/public/application/angular/discover.js +++ b/src/plugins/discover/public/application/angular/discover.js @@ -72,6 +72,7 @@ import { syncQueryStateWithUrl, getDefaultQuery, search, + UI_SETTINGS, } from '../../../../data/public'; import { getIndexPatternId } from '../helpers/get_index_pattern_id'; import { addFatalError } from '../../../../kibana_legacy/public'; @@ -592,7 +593,8 @@ function discoverController( const query = $scope.searchSource.getField('query') || getDefaultQuery( - localStorage.get('kibana.userQueryLanguage') || config.get('search:queryLanguage') + localStorage.get('kibana.userQueryLanguage') || + config.get(UI_SETTINGS.SEARCH_QUERY_LANGUAGE) ); return { query, @@ -750,6 +752,13 @@ function discoverController( // Update defaults so that "reload saved query" functions correctly setAppState(getStateDefaults()); chrome.docTitle.change(savedSearch.lastSavedTitle); + chrome.setBreadcrumbs([ + { + text: discoverBreadcrumbsTitle, + href: '#/', + }, + { text: savedSearch.title }, + ]); } } }); diff --git a/src/plugins/discover/public/application/angular/doc_table/components/table_header.ts b/src/plugins/discover/public/application/angular/doc_table/components/table_header.ts index 60dfb69e85e74..82bfcc8bc42f9 100644 --- a/src/plugins/discover/public/application/angular/doc_table/components/table_header.ts +++ b/src/plugins/discover/public/application/angular/doc_table/components/table_header.ts @@ -19,6 +19,7 @@ import { TableHeader } from './table_header/table_header'; import { getServices } from '../../../../kibana_services'; import { SORT_DEFAULT_ORDER_SETTING, DOC_HIDE_TIME_COLUMN_SETTING } from '../../../../../common'; +import { UI_SETTINGS } from '../../../../../../data/public'; export function createTableHeaderDirective(reactDirective: any) { const { uiSettings: config } = getServices(); @@ -38,7 +39,7 @@ export function createTableHeaderDirective(reactDirective: any) { { restrict: 'A' }, { hideTimeColumn: config.get(DOC_HIDE_TIME_COLUMN_SETTING, false), - isShortDots: config.get('shortDots:enable'), + isShortDots: config.get(UI_SETTINGS.SHORT_DOTS_ENABLE), defaultSortOrder: config.get(SORT_DEFAULT_ORDER_SETTING, 'desc'), } ); diff --git a/src/plugins/discover/public/application/components/sidebar/discover_field.tsx b/src/plugins/discover/public/application/components/sidebar/discover_field.tsx index 9e5429882e3c3..5f40c55e30e7e 100644 --- a/src/plugins/discover/public/application/components/sidebar/discover_field.tsx +++ b/src/plugins/discover/public/application/components/sidebar/discover_field.tsx @@ -17,7 +17,7 @@ * under the License. */ import React from 'react'; -import { EuiButton, EuiToolTip, EuiText } from '@elastic/eui'; +import { EuiButton, EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { DiscoverFieldDetails } from './discover_field_details'; import { FieldIcon } from '../../../../../kibana_react/public'; @@ -125,16 +125,14 @@ export function DiscoverField({ /> - - - {useShortDots ? shortenDottedString(field.name) : field.displayName} - - + {useShortDots ? shortenDottedString(field.name) : field.displayName} + {field.name !== '_source' && !selected && ( diff --git a/src/plugins/discover/public/application/components/sidebar/discover_sidebar.scss b/src/plugins/discover/public/application/components/sidebar/discover_sidebar.scss index fe04d42d614ff..9f7700c7f395c 100644 --- a/src/plugins/discover/public/application/components/sidebar/discover_sidebar.scss +++ b/src/plugins/discover/public/application/components/sidebar/discover_sidebar.scss @@ -107,6 +107,7 @@ */ .dscSidebarItem__action { opacity: 0; /* 1 */ + transition: none; &:focus { opacity: 1; /* 2 */ diff --git a/src/plugins/discover/public/application/components/sidebar/discover_sidebar.tsx b/src/plugins/discover/public/application/components/sidebar/discover_sidebar.tsx index 99a5547ed0760..5a319d30b2515 100644 --- a/src/plugins/discover/public/application/components/sidebar/discover_sidebar.tsx +++ b/src/plugins/discover/public/application/components/sidebar/discover_sidebar.tsx @@ -33,6 +33,7 @@ import { IIndexPatternFieldList, IndexPatternField, IndexPattern, + UI_SETTINGS, } from '../../../../../data/public'; import { AppState } from '../../angular/discover_state'; import { getDetails } from './lib/get_details'; @@ -133,7 +134,7 @@ export function DiscoverSidebar({ ); const popularLimit = services.uiSettings.get(FIELDS_LIMIT_SETTING); - const useShortDots = services.uiSettings.get('shortDots:enable'); + const useShortDots = services.uiSettings.get(UI_SETTINGS.SHORT_DOTS_ENABLE); const { selected: selectedFields, diff --git a/src/plugins/discover/public/index.ts b/src/plugins/discover/public/index.ts index 359d91325f064..4154fdfeb3ff4 100644 --- a/src/plugins/discover/public/index.ts +++ b/src/plugins/discover/public/index.ts @@ -27,3 +27,4 @@ export function plugin(initializerContext: PluginInitializerContext) { export { SavedSearch, SavedSearchLoader, createSavedSearchesLoader } from './saved_searches'; export { ISearchEmbeddable, SEARCH_EMBEDDABLE_TYPE, SearchInput } from './application/embeddable'; +export { DISCOVER_APP_URL_GENERATOR } from './url_generator'; diff --git a/src/plugins/discover/public/mocks.ts b/src/plugins/discover/public/mocks.ts index c394fe2c11a71..e4314426bfce5 100644 --- a/src/plugins/discover/public/mocks.ts +++ b/src/plugins/discover/public/mocks.ts @@ -34,6 +34,9 @@ const createSetupContract = (): Setup => { const createStartContract = (): Start => { const startContract: Start = { savedSearchLoader: {} as any, + urlGenerator: { + createUrl: jest.fn(), + } as any, }; return startContract; }; diff --git a/src/plugins/discover/public/plugin.ts b/src/plugins/discover/public/plugin.ts index 4323e3d8deda4..091288e3e65aa 100644 --- a/src/plugins/discover/public/plugin.ts +++ b/src/plugins/discover/public/plugin.ts @@ -34,7 +34,7 @@ import { UiActionsStart, UiActionsSetup } from 'src/plugins/ui_actions/public'; import { EmbeddableStart, EmbeddableSetup } from 'src/plugins/embeddable/public'; import { ChartsPluginStart } from 'src/plugins/charts/public'; import { NavigationPublicPluginStart as NavigationStart } from 'src/plugins/navigation/public'; -import { SharePluginStart } from 'src/plugins/share/public'; +import { SharePluginStart, SharePluginSetup, UrlGeneratorContract } from 'src/plugins/share/public'; import { VisualizationsStart, VisualizationsSetup } from 'src/plugins/visualizations/public'; import { KibanaLegacySetup } from 'src/plugins/kibana_legacy/public'; import { HomePublicPluginSetup } from 'src/plugins/home/public'; @@ -43,7 +43,7 @@ import { DataPublicPluginStart, DataPublicPluginSetup, esFilters } from '../../d import { SavedObjectLoader } from '../../saved_objects/public'; import { createKbnUrlTracker } from '../../kibana_utils/public'; import { DEFAULT_APP_CATEGORIES } from '../../../core/public'; - +import { UrlGeneratorState } from '../../share/public'; import { DocViewInput, DocViewInputFn } from './application/doc_views/doc_views_types'; import { DocViewsRegistry } from './application/doc_views/doc_views_registry'; import { DocViewTable } from './application/components/table/table'; @@ -59,6 +59,17 @@ import { import { createSavedSearchesLoader } from './saved_searches'; import { registerFeature } from './register_feature'; import { buildServices } from './build_services'; +import { + DiscoverUrlGeneratorState, + DISCOVER_APP_URL_GENERATOR, + DiscoverUrlGenerator, +} from './url_generator'; + +declare module '../../share/public' { + export interface UrlGeneratorStateMapping { + [DISCOVER_APP_URL_GENERATOR]: UrlGeneratorState; + } +} /** * @public @@ -76,12 +87,31 @@ export interface DiscoverSetup { export interface DiscoverStart { savedSearchLoader: SavedObjectLoader; + + /** + * `share` plugin URL generator for Discover app. Use it to generate links into + * Discover application, example: + * + * ```ts + * const url = await plugins.discover.urlGenerator.createUrl({ + * savedSearchId: '571aaf70-4c88-11e8-b3d7-01146121b73d', + * indexPatternId: 'c367b774-a4c2-11ea-bb37-0242ac130002', + * timeRange: { + * to: 'now', + * from: 'now-15m', + * mode: 'relative', + * }, + * }); + * ``` + */ + readonly urlGenerator: undefined | UrlGeneratorContract<'DISCOVER_APP_URL_GENERATOR'>; } /** * @internal */ export interface DiscoverSetupPlugins { + share?: SharePluginSetup; uiActions: UiActionsSetup; embeddable: EmbeddableSetup; kibanaLegacy: KibanaLegacySetup; @@ -122,6 +152,7 @@ export class DiscoverPlugin private stopUrlTracking: (() => void) | undefined = undefined; private servicesInitialized: boolean = false; private innerAngularInitialized: boolean = false; + private urlGenerator?: DiscoverStart['urlGenerator']; /** * why are those functions public? they are needed for some mocha tests @@ -131,6 +162,17 @@ export class DiscoverPlugin public initializeServices?: () => Promise<{ core: CoreStart; plugins: DiscoverStartPlugins }>; setup(core: CoreSetup, plugins: DiscoverSetupPlugins) { + const baseUrl = core.http.basePath.prepend('/app/discover'); + + if (plugins.share) { + this.urlGenerator = plugins.share.urlGenerators.registerUrlGenerator( + new DiscoverUrlGenerator({ + appBasePath: baseUrl, + useHash: core.uiSettings.get('state:storeInSessionStorage'), + }) + ); + } + this.docViewsRegistry = new DocViewsRegistry(); setDocViewsRegistry(this.docViewsRegistry); this.docViewsRegistry.addDocView({ @@ -158,7 +200,7 @@ export class DiscoverPlugin // so history is lazily created (when app is mounted) // this prevents redundant `#` when not in discover app getHistory: getScopedHistory, - baseUrl: core.http.basePath.prepend('/app/discover'), + baseUrl, defaultSubUrl: '#/', storageKey: `lastUrl:${core.http.basePath.get()}:discover`, navLinkUpdater$: this.appStateUpdater, @@ -266,6 +308,7 @@ export class DiscoverPlugin }; return { + urlGenerator: this.urlGenerator, savedSearchLoader: createSavedSearchesLoader({ savedObjectsClient: core.savedObjects.client, indexPatterns: plugins.data.indexPatterns, diff --git a/src/plugins/discover/public/url_generator.test.ts b/src/plugins/discover/public/url_generator.test.ts new file mode 100644 index 0000000000000..cf9beb246fea2 --- /dev/null +++ b/src/plugins/discover/public/url_generator.test.ts @@ -0,0 +1,259 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { DiscoverUrlGenerator } from './url_generator'; +import { hashedItemStore, getStatesFromKbnUrl } from '../../kibana_utils/public'; +// eslint-disable-next-line +import { mockStorage } from '../../kibana_utils/public/storage/hashed_item_store/mock'; +import { FilterStateStore } from '../../data/common'; + +const appBasePath: string = 'xyz/app/discover'; +const indexPatternId: string = 'c367b774-a4c2-11ea-bb37-0242ac130002'; +const savedSearchId: string = '571aaf70-4c88-11e8-b3d7-01146121b73d'; + +interface SetupParams { + useHash?: boolean; +} + +const setup = async ({ useHash = false }: SetupParams = {}) => { + const generator = new DiscoverUrlGenerator({ + appBasePath, + useHash, + }); + + return { + generator, + }; +}; + +beforeEach(() => { + // @ts-ignore + hashedItemStore.storage = mockStorage; +}); + +describe('Discover url generator', () => { + test('can create a link to Discover with no state and no saved search', async () => { + const { generator } = await setup(); + const url = await generator.createUrl({}); + const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']); + + expect(url.startsWith(appBasePath)).toBe(true); + expect(_a).toEqual({}); + expect(_g).toEqual({}); + }); + + test('can create a link to a saved search in Discover', async () => { + const { generator } = await setup(); + const url = await generator.createUrl({ savedSearchId }); + const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']); + + expect(url.startsWith(`${appBasePath}#/${savedSearchId}`)).toBe(true); + expect(_a).toEqual({}); + expect(_g).toEqual({}); + }); + + test('can specify specific index pattern', async () => { + const { generator } = await setup(); + const url = await generator.createUrl({ + indexPatternId, + }); + const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']); + + expect(_a).toEqual({ + index: indexPatternId, + }); + expect(_g).toEqual({}); + }); + + test('can specify specific time range', async () => { + const { generator } = await setup(); + const url = await generator.createUrl({ + timeRange: { to: 'now', from: 'now-15m', mode: 'relative' }, + }); + const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']); + + expect(_a).toEqual({}); + expect(_g).toEqual({ + time: { + from: 'now-15m', + mode: 'relative', + to: 'now', + }, + }); + }); + + test('can specify query', async () => { + const { generator } = await setup(); + const url = await generator.createUrl({ + query: { + language: 'kuery', + query: 'foo', + }, + }); + const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']); + + expect(_a).toEqual({ + query: { + language: 'kuery', + query: 'foo', + }, + }); + expect(_g).toEqual({}); + }); + + test('can specify local and global filters', async () => { + const { generator } = await setup(); + const url = await generator.createUrl({ + filters: [ + { + meta: { + alias: 'foo', + disabled: false, + negate: false, + }, + $state: { + store: FilterStateStore.APP_STATE, + }, + }, + { + meta: { + alias: 'bar', + disabled: false, + negate: false, + }, + $state: { + store: FilterStateStore.GLOBAL_STATE, + }, + }, + ], + }); + const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']); + + expect(_a).toEqual({ + filters: [ + { + $state: { + store: 'appState', + }, + meta: { + alias: 'foo', + disabled: false, + negate: false, + }, + }, + ], + }); + expect(_g).toEqual({ + filters: [ + { + $state: { + store: 'globalState', + }, + meta: { + alias: 'bar', + disabled: false, + negate: false, + }, + }, + ], + }); + }); + + test('can set refresh interval', async () => { + const { generator } = await setup(); + const url = await generator.createUrl({ + refreshInterval: { + pause: false, + value: 666, + }, + }); + const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']); + + expect(_a).toEqual({}); + expect(_g).toEqual({ + refreshInterval: { + pause: false, + value: 666, + }, + }); + }); + + test('can set time range', async () => { + const { generator } = await setup(); + const url = await generator.createUrl({ + timeRange: { + from: 'now-3h', + to: 'now', + }, + }); + const { _a, _g } = getStatesFromKbnUrl(url, ['_a', '_g']); + + expect(_a).toEqual({}); + expect(_g).toEqual({ + time: { + from: 'now-3h', + to: 'now', + }, + }); + }); + + describe('useHash property', () => { + describe('when default useHash is set to false', () => { + test('when using default, sets index pattern ID in the generated URL', async () => { + const { generator } = await setup(); + const url = await generator.createUrl({ + indexPatternId, + }); + + expect(url.indexOf(indexPatternId) > -1).toBe(true); + }); + + test('when enabling useHash, does not set index pattern ID in the generated URL', async () => { + const { generator } = await setup(); + const url = await generator.createUrl({ + useHash: true, + indexPatternId, + }); + + expect(url.indexOf(indexPatternId) > -1).toBe(false); + }); + }); + + describe('when default useHash is set to true', () => { + test('when using default, does not set index pattern ID in the generated URL', async () => { + const { generator } = await setup({ useHash: true }); + const url = await generator.createUrl({ + indexPatternId, + }); + + expect(url.indexOf(indexPatternId) > -1).toBe(false); + }); + + test('when disabling useHash, sets index pattern ID in the generated URL', async () => { + const { generator } = await setup(); + const url = await generator.createUrl({ + useHash: false, + indexPatternId, + }); + + expect(url.indexOf(indexPatternId) > -1).toBe(true); + }); + }); + }); +}); diff --git a/src/plugins/discover/public/url_generator.ts b/src/plugins/discover/public/url_generator.ts new file mode 100644 index 0000000000000..42d689050d5ad --- /dev/null +++ b/src/plugins/discover/public/url_generator.ts @@ -0,0 +1,114 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + TimeRange, + Filter, + Query, + esFilters, + QueryState, + RefreshInterval, +} from '../../data/public'; +import { setStateToKbnUrl } from '../../kibana_utils/public'; +import { UrlGeneratorsDefinition } from '../../share/public'; + +export const DISCOVER_APP_URL_GENERATOR = 'DISCOVER_APP_URL_GENERATOR'; + +export interface DiscoverUrlGeneratorState { + /** + * Optionally set saved search ID. + */ + savedSearchId?: string; + + /** + * Optionally set index pattern ID. + */ + indexPatternId?: string; + + /** + * Optionally set the time range in the time picker. + */ + timeRange?: TimeRange; + + /** + * Optionally set the refresh interval. + */ + refreshInterval?: RefreshInterval; + + /** + * Optionally apply filers. + */ + filters?: Filter[]; + + /** + * Optionally set a query. NOTE: if given and used in conjunction with `dashboardId`, and the + * saved dashboard has a query saved with it, this will _replace_ that query. + */ + query?: Query; + + /** + * If not given, will use the uiSettings configuration for `storeInSessionStorage`. useHash determines + * whether to hash the data in the url to avoid url length issues. + */ + useHash?: boolean; +} + +interface Params { + appBasePath: string; + useHash: boolean; +} + +export class DiscoverUrlGenerator + implements UrlGeneratorsDefinition { + constructor(private readonly params: Params) {} + + public readonly id = DISCOVER_APP_URL_GENERATOR; + + public readonly createUrl = async ({ + filters, + indexPatternId, + query, + refreshInterval, + savedSearchId, + timeRange, + useHash = this.params.useHash, + }: DiscoverUrlGeneratorState): Promise => { + const savedSearchPath = savedSearchId ? encodeURIComponent(savedSearchId) : ''; + const appState: { + query?: Query; + filters?: Filter[]; + index?: string; + } = {}; + const queryState: QueryState = {}; + + if (query) appState.query = query; + if (filters) appState.filters = filters?.filter((f) => !esFilters.isFilterPinned(f)); + if (indexPatternId) appState.index = indexPatternId; + + if (timeRange) queryState.time = timeRange; + if (filters) queryState.filters = filters?.filter((f) => esFilters.isFilterPinned(f)); + if (refreshInterval) queryState.refreshInterval = refreshInterval; + + let url = `${this.params.appBasePath}#/${savedSearchPath}`; + url = setStateToKbnUrl('_g', queryState, { useHash }, url); + url = setStateToKbnUrl('_a', appState, { useHash }, url); + + return url; + }; +} diff --git a/src/plugins/embeddable/public/lib/containers/embeddable_child_panel.test.tsx b/src/plugins/embeddable/public/lib/containers/embeddable_child_panel.test.tsx index b046376a304ae..e29e941e898fb 100644 --- a/src/plugins/embeddable/public/lib/containers/embeddable_child_panel.test.tsx +++ b/src/plugins/embeddable/public/lib/containers/embeddable_child_panel.test.tsx @@ -31,7 +31,7 @@ import { // eslint-disable-next-line import { inspectorPluginMock } from '../../../../inspector/public/mocks'; import { mount } from 'enzyme'; -import { embeddablePluginMock } from '../../mocks'; +import { embeddablePluginMock, createEmbeddablePanelMock } from '../../mocks'; test('EmbeddableChildPanel renders an embeddable when it is done loading', async () => { const inspector = inspectorPluginMock.createStartContract(); @@ -58,18 +58,17 @@ test('EmbeddableChildPanel renders an embeddable when it is done loading', async expect(newEmbeddable.id).toBeDefined(); + const testPanel = createEmbeddablePanelMock({ + getAllEmbeddableFactories: start.getEmbeddableFactories, + getEmbeddableFactory, + inspector, + }); + const component = mount( Promise.resolve([])} - getAllEmbeddableFactories={start.getEmbeddableFactories} - getEmbeddableFactory={getEmbeddableFactory} - notifications={{} as any} - application={{} as any} - overlays={{} as any} - inspector={inspector} - SavedObjectFinder={() => null} + PanelComponent={testPanel} /> ); @@ -97,19 +96,9 @@ test(`EmbeddableChildPanel renders an error message if the factory doesn't exist { getEmbeddableFactory } as any ); + const testPanel = createEmbeddablePanelMock({ inspector }); const component = mount( - Promise.resolve([])} - getAllEmbeddableFactories={(() => []) as any} - getEmbeddableFactory={(() => undefined) as any} - notifications={{} as any} - overlays={{} as any} - application={{} as any} - inspector={inspector} - SavedObjectFinder={() => null} - /> + ); await nextTick(); diff --git a/src/plugins/embeddable/public/lib/containers/embeddable_child_panel.tsx b/src/plugins/embeddable/public/lib/containers/embeddable_child_panel.tsx index 70628665e6e8c..be8ff2c95fe09 100644 --- a/src/plugins/embeddable/public/lib/containers/embeddable_child_panel.tsx +++ b/src/plugins/embeddable/public/lib/containers/embeddable_child_panel.tsx @@ -22,12 +22,7 @@ import React from 'react'; import { EuiLoadingChart } from '@elastic/eui'; import { Subscription } from 'rxjs'; -import { CoreStart } from 'src/core/public'; -import { UiActionsService } from 'src/plugins/ui_actions/public'; - -import { Start as InspectorStartContract } from 'src/plugins/inspector/public'; import { ErrorEmbeddable, IEmbeddable } from '../embeddables'; -import { EmbeddablePanel } from '../panel'; import { IContainer } from './i_container'; import { EmbeddableStart } from '../../plugin'; @@ -35,14 +30,7 @@ export interface EmbeddableChildPanelProps { embeddableId: string; className?: string; container: IContainer; - getActions: UiActionsService['getTriggerCompatibleActions']; - getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory']; - getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories']; - overlays: CoreStart['overlays']; - notifications: CoreStart['notifications']; - application: CoreStart['application']; - inspector: InspectorStartContract; - SavedObjectFinder: React.ComponentType; + PanelComponent: EmbeddableStart['EmbeddablePanel']; } interface State { @@ -87,6 +75,7 @@ export class EmbeddableChildPanel extends React.Component ) : ( - + )} ); diff --git a/src/plugins/embeddable/public/lib/test_samples/embeddables/hello_world_container.tsx b/src/plugins/embeddable/public/lib/test_samples/embeddables/hello_world_container.tsx index 31e14a0af59d7..913c3a0b30826 100644 --- a/src/plugins/embeddable/public/lib/test_samples/embeddables/hello_world_container.tsx +++ b/src/plugins/embeddable/public/lib/test_samples/embeddables/hello_world_container.tsx @@ -19,9 +19,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { I18nProvider } from '@kbn/i18n/react'; -import { CoreStart } from 'src/core/public'; -import { UiActionsService } from 'src/plugins/ui_actions/public'; -import { Start as InspectorStartContract } from 'src/plugins/inspector/public'; import { Container, ViewMode, ContainerInput } from '../..'; import { HelloWorldContainerComponent } from './hello_world_container_component'; import { EmbeddableStart } from '../../../plugin'; @@ -45,14 +42,8 @@ interface HelloWorldContainerInput extends ContainerInput { } interface HelloWorldContainerOptions { - getActions: UiActionsService['getTriggerCompatibleActions']; getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory']; - getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories']; - overlays: CoreStart['overlays']; - application: CoreStart['application']; - notifications: CoreStart['notifications']; - inspector: InspectorStartContract; - SavedObjectFinder: React.ComponentType; + panelComponent: EmbeddableStart['EmbeddablePanel']; } export class HelloWorldContainer extends Container { @@ -78,14 +69,7 @@ export class HelloWorldContainer extends Container , node diff --git a/src/plugins/embeddable/public/lib/test_samples/embeddables/hello_world_container_component.tsx b/src/plugins/embeddable/public/lib/test_samples/embeddables/hello_world_container_component.tsx index 6453046b86e20..5fefa1fc90720 100644 --- a/src/plugins/embeddable/public/lib/test_samples/embeddables/hello_world_container_component.tsx +++ b/src/plugins/embeddable/public/lib/test_samples/embeddables/hello_world_container_component.tsx @@ -20,22 +20,12 @@ import React, { Component, RefObject } from 'react'; import { Subscription } from 'rxjs'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; -import { CoreStart } from 'src/core/public'; -import { UiActionsService } from 'src/plugins/ui_actions/public'; -import { Start as InspectorStartContract } from 'src/plugins/inspector/public'; import { IContainer, PanelState, EmbeddableChildPanel } from '../..'; import { EmbeddableStart } from '../../../plugin'; interface Props { container: IContainer; - getActions: UiActionsService['getTriggerCompatibleActions']; - getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory']; - getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories']; - overlays: CoreStart['overlays']; - application: CoreStart['application']; - notifications: CoreStart['notifications']; - inspector: InspectorStartContract; - SavedObjectFinder: React.ComponentType; + panelComponent: EmbeddableStart['EmbeddablePanel']; } interface State { @@ -108,14 +98,7 @@ export class HelloWorldContainerComponent extends Component { ); diff --git a/src/plugins/embeddable/public/mocks.ts b/src/plugins/embeddable/public/mocks.ts deleted file mode 100644 index f5487c381cfcb..0000000000000 --- a/src/plugins/embeddable/public/mocks.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import { - EmbeddableStart, - EmbeddableSetup, - EmbeddableSetupDependencies, - EmbeddableStartDependencies, -} from '.'; -import { EmbeddablePublicPlugin } from './plugin'; -import { coreMock } from '../../../core/public/mocks'; - -// eslint-disable-next-line -import { inspectorPluginMock } from '../../inspector/public/mocks'; -// eslint-disable-next-line -import { uiActionsPluginMock } from '../../ui_actions/public/mocks'; - -export type Setup = jest.Mocked; -export type Start = jest.Mocked; - -const createSetupContract = (): Setup => { - const setupContract: Setup = { - registerEmbeddableFactory: jest.fn(), - setCustomEmbeddableFactoryProvider: jest.fn(), - }; - return setupContract; -}; - -const createStartContract = (): Start => { - const startContract: Start = { - getEmbeddableFactories: jest.fn(), - getEmbeddableFactory: jest.fn(), - EmbeddablePanel: jest.fn(), - }; - return startContract; -}; - -const createInstance = (setupPlugins: Partial = {}) => { - const plugin = new EmbeddablePublicPlugin({} as any); - const setup = plugin.setup(coreMock.createSetup(), { - uiActions: setupPlugins.uiActions || uiActionsPluginMock.createSetupContract(), - }); - const doStart = (startPlugins: Partial = {}) => - plugin.start(coreMock.createStart(), { - uiActions: startPlugins.uiActions || uiActionsPluginMock.createStartContract(), - inspector: inspectorPluginMock.createStartContract(), - }); - return { - plugin, - setup, - doStart, - }; -}; - -export const embeddablePluginMock = { - createSetupContract, - createStartContract, - createInstance, -}; diff --git a/src/plugins/embeddable/public/mocks.tsx b/src/plugins/embeddable/public/mocks.tsx new file mode 100644 index 0000000000000..9da0b7602c4f8 --- /dev/null +++ b/src/plugins/embeddable/public/mocks.tsx @@ -0,0 +1,116 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { + EmbeddableStart, + EmbeddableSetup, + EmbeddableSetupDependencies, + EmbeddableStartDependencies, + IEmbeddable, + EmbeddablePanel, +} from '.'; +import { EmbeddablePublicPlugin } from './plugin'; +import { coreMock } from '../../../core/public/mocks'; +import { UiActionsService } from './lib/ui_actions'; +import { CoreStart } from '../../../core/public'; +import { Start as InspectorStart } from '../../inspector/public'; + +// eslint-disable-next-line +import { inspectorPluginMock } from '../../inspector/public/mocks'; +// eslint-disable-next-line +import { uiActionsPluginMock } from '../../ui_actions/public/mocks'; + +export type Setup = jest.Mocked; +export type Start = jest.Mocked; + +interface CreateEmbeddablePanelMockArgs { + getActions: UiActionsService['getTriggerCompatibleActions']; + getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory']; + getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories']; + overlays: CoreStart['overlays']; + notifications: CoreStart['notifications']; + application: CoreStart['application']; + inspector: InspectorStart; + SavedObjectFinder: React.ComponentType; +} + +export const createEmbeddablePanelMock = ({ + getActions, + getEmbeddableFactory, + getAllEmbeddableFactories, + overlays, + notifications, + application, + inspector, + SavedObjectFinder, +}: Partial) => { + return ({ embeddable }: { embeddable: IEmbeddable }) => ( + Promise.resolve([]))} + getAllEmbeddableFactories={getAllEmbeddableFactories || ((() => []) as any)} + getEmbeddableFactory={getEmbeddableFactory || ((() => undefined) as any)} + notifications={notifications || ({} as any)} + application={application || ({} as any)} + overlays={overlays || ({} as any)} + inspector={inspector || ({} as any)} + SavedObjectFinder={SavedObjectFinder || (() => null)} + /> + ); +}; + +const createSetupContract = (): Setup => { + const setupContract: Setup = { + registerEmbeddableFactory: jest.fn(), + setCustomEmbeddableFactoryProvider: jest.fn(), + }; + return setupContract; +}; + +const createStartContract = (): Start => { + const startContract: Start = { + getEmbeddableFactories: jest.fn(), + getEmbeddableFactory: jest.fn(), + EmbeddablePanel: jest.fn(), + }; + return startContract; +}; + +const createInstance = (setupPlugins: Partial = {}) => { + const plugin = new EmbeddablePublicPlugin({} as any); + const setup = plugin.setup(coreMock.createSetup(), { + uiActions: setupPlugins.uiActions || uiActionsPluginMock.createSetupContract(), + }); + const doStart = (startPlugins: Partial = {}) => + plugin.start(coreMock.createStart(), { + uiActions: startPlugins.uiActions || uiActionsPluginMock.createStartContract(), + inspector: inspectorPluginMock.createStartContract(), + }); + return { + plugin, + setup, + doStart, + }; +}; + +export const embeddablePluginMock = { + createSetupContract, + createStartContract, + createInstance, +}; diff --git a/src/plugins/embeddable/public/tests/apply_filter_action.test.ts b/src/plugins/embeddable/public/tests/apply_filter_action.test.ts index ebb76c743393b..ec92f334267f5 100644 --- a/src/plugins/embeddable/public/tests/apply_filter_action.test.ts +++ b/src/plugins/embeddable/public/tests/apply_filter_action.test.ts @@ -31,8 +31,7 @@ import { FilterableEmbeddableInput, } from '../lib/test_samples'; // eslint-disable-next-line -import { inspectorPluginMock } from '../../../../plugins/inspector/public/mocks'; -import { esFilters } from '../../../../plugins/data/public'; +import { esFilters } from '../../../data/public'; test('ApplyFilterAction applies the filter to the root of the container tree', async () => { const { doStart, setup } = testPlugin(); @@ -95,26 +94,16 @@ test('ApplyFilterAction applies the filter to the root of the container tree', a }); test('ApplyFilterAction is incompatible if the root container does not accept a filter as input', async () => { - const { doStart, coreStart, setup } = testPlugin(); - const inspector = inspectorPluginMock.createStartContract(); + const { doStart, setup } = testPlugin(); const factory = new FilterableEmbeddableFactory(); setup.registerEmbeddableFactory(factory.type, factory); const api = doStart(); const applyFilterAction = createFilterAction(); - const parent = new HelloWorldContainer( - { id: 'root', panels: {} }, - { - getActions: () => Promise.resolve([]), - getEmbeddableFactory: api.getEmbeddableFactory, - getAllEmbeddableFactories: api.getEmbeddableFactories, - overlays: coreStart.overlays, - notifications: coreStart.notifications, - application: coreStart.application, - inspector, - SavedObjectFinder: () => null, - } - ); + + const parent = new HelloWorldContainer({ id: 'root', panels: {} }, { + getEmbeddableFactory: api.getEmbeddableFactory, + } as any); const embeddable = await parent.addNewEmbeddable< FilterableContainerInput, EmbeddableOutput, @@ -130,27 +119,17 @@ test('ApplyFilterAction is incompatible if the root container does not accept a }); test('trying to execute on incompatible context throws an error ', async () => { - const { doStart, coreStart, setup } = testPlugin(); - const inspector = inspectorPluginMock.createStartContract(); + const { doStart, setup } = testPlugin(); const factory = new FilterableEmbeddableFactory(); setup.registerEmbeddableFactory(factory.type, factory); const api = doStart(); const applyFilterAction = createFilterAction(); - const parent = new HelloWorldContainer( - { id: 'root', panels: {} }, - { - getActions: () => Promise.resolve([]), - getEmbeddableFactory: api.getEmbeddableFactory, - getAllEmbeddableFactories: api.getEmbeddableFactories, - overlays: coreStart.overlays, - notifications: coreStart.notifications, - application: coreStart.application, - inspector, - SavedObjectFinder: () => null, - } - ); + + const parent = new HelloWorldContainer({ id: 'root', panels: {} }, { + getEmbeddableFactory: api.getEmbeddableFactory, + } as any); const embeddable = await parent.addNewEmbeddable< FilterableContainerInput, diff --git a/src/plugins/embeddable/public/tests/container.test.ts b/src/plugins/embeddable/public/tests/container.test.ts index 4cd01abaf7995..490f0c00c7c4d 100644 --- a/src/plugins/embeddable/public/tests/container.test.ts +++ b/src/plugins/embeddable/public/tests/container.test.ts @@ -48,6 +48,7 @@ import { coreMock } from '../../../../core/public/mocks'; import { testPlugin } from './test_plugin'; import { of } from './helpers'; import { esFilters, Filter } from '../../../../plugins/data/public'; +import { createEmbeddablePanelMock } from '../mocks'; async function creatHelloWorldContainerAndEmbeddable( containerInput: ContainerInput = { id: 'hello', panels: {} }, @@ -68,15 +69,18 @@ async function creatHelloWorldContainerAndEmbeddable( const start = doStart(); - const container = new HelloWorldContainer(containerInput, { + const testPanel = createEmbeddablePanelMock({ getActions: uiActions.getTriggerCompatibleActions, getEmbeddableFactory: start.getEmbeddableFactory, getAllEmbeddableFactories: start.getEmbeddableFactories, overlays: coreStart.overlays, notifications: coreStart.notifications, application: coreStart.application, - inspector: {} as any, - SavedObjectFinder: () => null, + }); + + const container = new HelloWorldContainer(containerInput, { + getEmbeddableFactory: start.getEmbeddableFactory, + panelComponent: testPanel, }); const embeddable = await container.addNewEmbeddable< ContactCardEmbeddableInput, @@ -88,7 +92,7 @@ async function creatHelloWorldContainerAndEmbeddable( throw new Error('Error adding embeddable'); } - return { container, embeddable, coreSetup, coreStart, setup, start, uiActions }; + return { container, embeddable, coreSetup, coreStart, setup, start, uiActions, testPanel }; } test('Container initializes embeddables', async (done) => { @@ -131,7 +135,8 @@ test('Container.addNewEmbeddable', async () => { }); test('Container.removeEmbeddable removes and cleans up', async (done) => { - const { start, coreStart, uiActions } = await creatHelloWorldContainerAndEmbeddable(); + const { start, testPanel } = await creatHelloWorldContainerAndEmbeddable(); + const container = new HelloWorldContainer( { id: 'hello', @@ -143,14 +148,8 @@ test('Container.removeEmbeddable removes and cleans up', async (done) => { }, }, { - getActions: uiActions.getTriggerCompatibleActions, getEmbeddableFactory: start.getEmbeddableFactory, - getAllEmbeddableFactories: start.getEmbeddableFactories, - overlays: coreStart.overlays, - notifications: coreStart.notifications, - application: coreStart.application, - inspector: {} as any, - SavedObjectFinder: () => null, + panelComponent: testPanel, } ); const embeddable = await container.addNewEmbeddable< @@ -323,15 +322,17 @@ test(`Container updates its state when a child's input is updated`, async (done) // Make sure a brand new container built off the output of container also creates an embeddable // with "Dr.", not the default the embeddable was first added with. Makes sure changed input // is preserved with the container. - const containerClone = new HelloWorldContainer(container.getInput(), { + const testPanel = createEmbeddablePanelMock({ getActions: uiActions.getTriggerCompatibleActions, - getAllEmbeddableFactories: start.getEmbeddableFactories, getEmbeddableFactory: start.getEmbeddableFactory, - notifications: coreStart.notifications, + getAllEmbeddableFactories: start.getEmbeddableFactories, overlays: coreStart.overlays, + notifications: coreStart.notifications, application: coreStart.application, - inspector: {} as any, - SavedObjectFinder: () => null, + }); + const containerClone = new HelloWorldContainer(container.getInput(), { + getEmbeddableFactory: start.getEmbeddableFactory, + panelComponent: testPanel, }); const cloneSubscription = Rx.merge( containerClone.getOutput$(), @@ -575,6 +576,14 @@ test('Container changes made directly after adding a new embeddable are propagat const start = doStart(); + const testPanel = createEmbeddablePanelMock({ + getActions: uiActions.getTriggerCompatibleActions, + getEmbeddableFactory: start.getEmbeddableFactory, + getAllEmbeddableFactories: start.getEmbeddableFactories, + overlays: coreStart.overlays, + notifications: coreStart.notifications, + application: coreStart.application, + }); const container = new HelloWorldContainer( { id: 'hello', @@ -582,14 +591,8 @@ test('Container changes made directly after adding a new embeddable are propagat viewMode: ViewMode.EDIT, }, { - getActions: uiActions.getTriggerCompatibleActions, getEmbeddableFactory: start.getEmbeddableFactory, - getAllEmbeddableFactories: start.getEmbeddableFactories, - overlays: coreStart.overlays, - notifications: coreStart.notifications, - application: coreStart.application, - inspector: {} as any, - SavedObjectFinder: () => null, + panelComponent: testPanel, } ); @@ -701,20 +704,22 @@ test('untilEmbeddableLoaded() throws an error if there is no such child panel in coreMock.createStart() ); const start = doStart(); + const testPanel = createEmbeddablePanelMock({ + getActions: uiActions.getTriggerCompatibleActions, + getEmbeddableFactory: start.getEmbeddableFactory, + getAllEmbeddableFactories: start.getEmbeddableFactories, + overlays: coreStart.overlays, + notifications: coreStart.notifications, + application: coreStart.application, + }); const container = new HelloWorldContainer( { id: 'hello', panels: {}, }, { - getActions: uiActions.getTriggerCompatibleActions, getEmbeddableFactory: start.getEmbeddableFactory, - getAllEmbeddableFactories: start.getEmbeddableFactories, - overlays: coreStart.overlays, - notifications: coreStart.notifications, - application: coreStart.application, - inspector: {} as any, - SavedObjectFinder: () => null, + panelComponent: testPanel, } ); @@ -731,6 +736,14 @@ test('untilEmbeddableLoaded() resolves if child is loaded in the container', asy const factory = new HelloWorldEmbeddableFactory(); setup.registerEmbeddableFactory(factory.type, factory); const start = doStart(); + const testPanel = createEmbeddablePanelMock({ + getActions: uiActions.getTriggerCompatibleActions, + getEmbeddableFactory: start.getEmbeddableFactory, + getAllEmbeddableFactories: start.getEmbeddableFactories, + overlays: coreStart.overlays, + notifications: coreStart.notifications, + application: coreStart.application, + }); const container = new HelloWorldContainer( { id: 'hello', @@ -742,14 +755,8 @@ test('untilEmbeddableLoaded() resolves if child is loaded in the container', asy }, }, { - getActions: uiActions.getTriggerCompatibleActions, getEmbeddableFactory: start.getEmbeddableFactory, - getAllEmbeddableFactories: start.getEmbeddableFactories, - overlays: coreStart.overlays, - notifications: coreStart.notifications, - application: coreStart.application, - inspector: {} as any, - SavedObjectFinder: () => null, + panelComponent: testPanel, } ); @@ -771,6 +778,14 @@ test('untilEmbeddableLoaded resolves with undefined if child is subsequently rem setup.registerEmbeddableFactory(factory.type, factory); const start = doStart(); + const testPanel = createEmbeddablePanelMock({ + getActions: uiActions.getTriggerCompatibleActions, + getEmbeddableFactory: start.getEmbeddableFactory, + getAllEmbeddableFactories: start.getEmbeddableFactories, + overlays: coreStart.overlays, + notifications: coreStart.notifications, + application: coreStart.application, + }); const container = new HelloWorldContainer( { id: 'hello', @@ -782,14 +797,8 @@ test('untilEmbeddableLoaded resolves with undefined if child is subsequently rem }, }, { - getActions: uiActions.getTriggerCompatibleActions, getEmbeddableFactory: start.getEmbeddableFactory, - getAllEmbeddableFactories: start.getEmbeddableFactories, - overlays: coreStart.overlays, - notifications: coreStart.notifications, - application: coreStart.application, - inspector: {} as any, - SavedObjectFinder: () => null, + panelComponent: testPanel, } ); @@ -812,6 +821,14 @@ test('adding a panel then subsequently removing it before its loaded removes the }); setup.registerEmbeddableFactory(factory.type, factory); const start = doStart(); + const testPanel = createEmbeddablePanelMock({ + getActions: uiActions.getTriggerCompatibleActions, + getEmbeddableFactory: start.getEmbeddableFactory, + getAllEmbeddableFactories: start.getEmbeddableFactories, + overlays: coreStart.overlays, + notifications: coreStart.notifications, + application: coreStart.application, + }); const container = new HelloWorldContainer( { id: 'hello', @@ -823,14 +840,8 @@ test('adding a panel then subsequently removing it before its loaded removes the }, }, { - getActions: uiActions.getTriggerCompatibleActions, getEmbeddableFactory: start.getEmbeddableFactory, - getAllEmbeddableFactories: start.getEmbeddableFactories, - overlays: coreStart.overlays, - notifications: coreStart.notifications, - application: coreStart.application, - inspector: {} as any, - SavedObjectFinder: () => null, + panelComponent: testPanel, } ); diff --git a/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx b/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx index a9cb83504d958..311efae49f735 100644 --- a/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx +++ b/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx @@ -37,6 +37,7 @@ import { testPlugin } from './test_plugin'; import { CustomizePanelModal } from '../lib/panel/panel_header/panel_actions/customize_title/customize_panel_modal'; import { mount } from 'enzyme'; import { EmbeddableStart } from '../plugin'; +import { createEmbeddablePanelMock } from '../mocks'; let api: EmbeddableStart; let container: Container; @@ -55,17 +56,20 @@ beforeEach(async () => { setup.registerEmbeddableFactory(contactCardFactory.type, contactCardFactory); api = doStart(); + + const testPanel = createEmbeddablePanelMock({ + getActions: uiActions.getTriggerCompatibleActions, + getEmbeddableFactory: api.getEmbeddableFactory, + getAllEmbeddableFactories: api.getEmbeddableFactories, + overlays: coreStart.overlays, + notifications: coreStart.notifications, + application: coreStart.application, + }); container = new HelloWorldContainer( { id: '123', panels: {} }, { - getActions: uiActions.getTriggerCompatibleActions, getEmbeddableFactory: api.getEmbeddableFactory, - getAllEmbeddableFactories: api.getEmbeddableFactories, - overlays: coreStart.overlays, - notifications: coreStart.notifications, - application: coreStart.application, - inspector: {} as any, - SavedObjectFinder: () => null, + panelComponent: testPanel, } ); const contactCardEmbeddable = await container.addNewEmbeddable< diff --git a/src/plugins/embeddable/public/tests/explicit_input.test.ts b/src/plugins/embeddable/public/tests/explicit_input.test.ts index 6bea4fe46a497..d64ff94d71800 100644 --- a/src/plugins/embeddable/public/tests/explicit_input.test.ts +++ b/src/plugins/embeddable/public/tests/explicit_input.test.ts @@ -36,6 +36,7 @@ import { HelloWorldContainer } from '../lib/test_samples/embeddables/hello_world // eslint-disable-next-line import { coreMock } from '../../../../core/public/mocks'; import { esFilters, Filter } from '../../../../plugins/data/public'; +import { createEmbeddablePanelMock } from '../mocks'; const { setup, doStart, coreStart, uiActions } = testPlugin( coreMock.createSetup(), @@ -80,17 +81,19 @@ test('Explicit embeddable input mapped to undefined will default to inherited', }); test('Explicit embeddable input mapped to undefined with no inherited value will get passed to embeddable', async (done) => { + const testPanel = createEmbeddablePanelMock({ + getActions: uiActions.getTriggerCompatibleActions, + getEmbeddableFactory: start.getEmbeddableFactory, + getAllEmbeddableFactories: start.getEmbeddableFactories, + overlays: coreStart.overlays, + notifications: coreStart.notifications, + application: coreStart.application, + }); const container = new HelloWorldContainer( { id: 'hello', panels: {} }, { - getActions: uiActions.getTriggerCompatibleActions, - getAllEmbeddableFactories: start.getEmbeddableFactories, getEmbeddableFactory: start.getEmbeddableFactory, - notifications: coreStart.notifications, - overlays: coreStart.overlays, - application: coreStart.application, - inspector: {} as any, - SavedObjectFinder: () => null, + panelComponent: testPanel, } ); @@ -121,6 +124,14 @@ test('Explicit embeddable input mapped to undefined with no inherited value will // but before the embeddable factory returns the embeddable, that the `inheritedChildInput` and // embeddable input comparisons won't cause explicit input to be set when it shouldn't. test('Explicit input tests in async situations', (done: () => void) => { + const testPanel = createEmbeddablePanelMock({ + getActions: uiActions.getTriggerCompatibleActions, + getEmbeddableFactory: start.getEmbeddableFactory, + getAllEmbeddableFactories: start.getEmbeddableFactories, + overlays: coreStart.overlays, + notifications: coreStart.notifications, + application: coreStart.application, + }); const container = new HelloWorldContainer( { id: 'hello', @@ -132,14 +143,8 @@ test('Explicit input tests in async situations', (done: () => void) => { }, }, { - getActions: uiActions.getTriggerCompatibleActions, - getAllEmbeddableFactories: start.getEmbeddableFactories, getEmbeddableFactory: start.getEmbeddableFactory, - notifications: coreStart.notifications, - overlays: coreStart.overlays, - application: coreStart.application, - inspector: {} as any, - SavedObjectFinder: () => null, + panelComponent: testPanel, } ); diff --git a/src/plugins/es_ui_shared/__packages_do_not_import__/monaco/index.ts b/src/plugins/es_ui_shared/__packages_do_not_import__/monaco/index.ts new file mode 100644 index 0000000000000..a9c6ea1e01d54 --- /dev/null +++ b/src/plugins/es_ui_shared/__packages_do_not_import__/monaco/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { useXJsonMode } from './use_xjson_mode'; diff --git a/src/plugins/es_ui_shared/__packages_do_not_import__/monaco/use_xjson_mode.ts b/src/plugins/es_ui_shared/__packages_do_not_import__/monaco/use_xjson_mode.ts new file mode 100644 index 0000000000000..b783045492f05 --- /dev/null +++ b/src/plugins/es_ui_shared/__packages_do_not_import__/monaco/use_xjson_mode.ts @@ -0,0 +1,32 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { XJsonLang } from '@kbn/monaco'; +import { useXJsonMode as useBaseXJsonMode } from '../xjson'; + +interface ReturnValue extends ReturnType { + XJsonLang: typeof XJsonLang; +} + +export const useXJsonMode = (json: Parameters[0]): ReturnValue => { + return { + ...useBaseXJsonMode(json), + XJsonLang, + }; +}; diff --git a/src/plugins/es_ui_shared/__packages_do_not_import__/xjson/index.ts b/src/plugins/es_ui_shared/__packages_do_not_import__/xjson/index.ts new file mode 100644 index 0000000000000..a9c6ea1e01d54 --- /dev/null +++ b/src/plugins/es_ui_shared/__packages_do_not_import__/xjson/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { useXJsonMode } from './use_xjson_mode'; diff --git a/src/plugins/es_ui_shared/__packages_do_not_import__/xjson/use_xjson_mode.ts b/src/plugins/es_ui_shared/__packages_do_not_import__/xjson/use_xjson_mode.ts new file mode 100644 index 0000000000000..7dcc7c9ed83bc --- /dev/null +++ b/src/plugins/es_ui_shared/__packages_do_not_import__/xjson/use_xjson_mode.ts @@ -0,0 +1,41 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { useState, Dispatch } from 'react'; +import { collapseLiteralStrings, expandLiteralStrings } from '../../public'; + +interface ReturnValue { + xJson: string; + setXJson: Dispatch; + convertToJson: typeof collapseLiteralStrings; +} + +export const useXJsonMode = (json: Record | string | null): ReturnValue => { + const [xJson, setXJson] = useState(() => + json === null + ? '' + : expandLiteralStrings(typeof json === 'string' ? json : JSON.stringify(json, null, 2)) + ); + + return { + xJson, + setXJson, + convertToJson: collapseLiteralStrings, + }; +}; diff --git a/src/plugins/es_ui_shared/public/index.ts b/src/plugins/es_ui_shared/public/index.ts index 7e5510d7c9c65..4ab791289dd88 100644 --- a/src/plugins/es_ui_shared/public/index.ts +++ b/src/plugins/es_ui_shared/public/index.ts @@ -47,6 +47,10 @@ export { expandLiteralStrings, } from './console_lang'; +import * as Monaco from './monaco'; + +export { Monaco }; + export { AuthorizationContext, AuthorizationProvider, diff --git a/src/plugins/es_ui_shared/public/monaco/index.ts b/src/plugins/es_ui_shared/public/monaco/index.ts new file mode 100644 index 0000000000000..23ba93e913234 --- /dev/null +++ b/src/plugins/es_ui_shared/public/monaco/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { useXJsonMode } from '../../__packages_do_not_import__/monaco'; diff --git a/src/plugins/es_ui_shared/static/ace_x_json/hooks/use_x_json.ts b/src/plugins/es_ui_shared/static/ace_x_json/hooks/use_x_json.ts index 2b0bf0c8a3a7c..3a093ac6869d0 100644 --- a/src/plugins/es_ui_shared/static/ace_x_json/hooks/use_x_json.ts +++ b/src/plugins/es_ui_shared/static/ace_x_json/hooks/use_x_json.ts @@ -16,23 +16,18 @@ * specific language governing permissions and limitations * under the License. */ - -import { useState } from 'react'; -import { XJsonMode, collapseLiteralStrings, expandLiteralStrings } from '../../../public'; +import { XJsonMode } from '../../../public'; +import { useXJsonMode as useBaseXJsonMode } from '../../../__packages_do_not_import__/xjson'; const xJsonMode = new XJsonMode(); -export const useXJsonMode = (json: Record | string | null) => { - const [xJson, setXJson] = useState(() => - json === null - ? '' - : expandLiteralStrings(typeof json === 'string' ? json : JSON.stringify(json, null, 2)) - ); +interface ReturnValue extends ReturnType { + xJsonMode: typeof xJsonMode; +} +export const useXJsonMode = (json: Parameters[0]): ReturnValue => { return { - xJson, - setXJson, + ...useBaseXJsonMode(json), xJsonMode, - convertToJson: collapseLiteralStrings, }; }; diff --git a/src/plugins/home/public/application/components/__snapshots__/add_data.test.js.snap b/src/plugins/home/public/application/components/__snapshots__/add_data.test.js.snap index 3b3f86e579f1a..2545bbcb5114d 100644 --- a/src/plugins/home/public/application/components/__snapshots__/add_data.test.js.snap +++ b/src/plugins/home/public/application/components/__snapshots__/add_data.test.js.snap @@ -202,17 +202,17 @@ exports[`apmUiEnabled 1`] = ` } textAlign="left" - title="SIEM" + title="Security" titleSize="xs" /> @@ -468,17 +468,17 @@ exports[`isNewKibanaInstance 1`] = ` } textAlign="left" - title="SIEM" + title="Security" titleSize="xs" /> @@ -765,17 +765,17 @@ exports[`mlEnabled 1`] = ` } textAlign="left" - title="SIEM" + title="Security" titleSize="xs" /> @@ -1067,17 +1067,17 @@ exports[`render 1`] = ` } textAlign="left" - title="SIEM" + title="Security" titleSize="xs" /> diff --git a/src/plugins/home/public/application/components/add_data.js b/src/plugins/home/public/application/components/add_data.js index 2f7f07a0e4549..fa1327b3fcd08 100644 --- a/src/plugins/home/public/application/components/add_data.js +++ b/src/plugins/home/public/application/components/add_data.js @@ -80,11 +80,11 @@ const AddDataUi = ({ apmUiEnabled, isNewKibanaInstance, intl, mlEnabled }) => { }; const siemData = { title: intl.formatMessage({ - id: 'home.addData.siem.nameTitle', - defaultMessage: 'SIEM', + id: 'home.addData.securitySolution.nameTitle', + defaultMessage: 'Security', }), description: intl.formatMessage({ - id: 'home.addData.siem.nameDescription', + id: 'home.addData.securitySolution.nameDescription', defaultMessage: 'Centralize security events for interactive investigation in ready-to-go visualizations.', }), @@ -221,11 +221,11 @@ const AddDataUi = ({ apmUiEnabled, isNewKibanaInstance, intl, mlEnabled }) => { footer={ diff --git a/src/plugins/home/public/application/components/tutorial_directory.js b/src/plugins/home/public/application/components/tutorial_directory.js index 4d2cec158f63e..774b23af11ac8 100644 --- a/src/plugins/home/public/application/components/tutorial_directory.js +++ b/src/plugins/home/public/application/components/tutorial_directory.js @@ -75,10 +75,10 @@ class TutorialDirectoryUi extends React.Component { }), }, { - id: 'siem', + id: 'security', name: this.props.intl.formatMessage({ - id: 'home.tutorial.tabs.siemTitle', - defaultMessage: 'SIEM', + id: 'home.tutorial.tabs.securitySolutionTitle', + defaultMessage: 'Security', }), }, { diff --git a/src/plugins/home/server/services/sample_data/data_sets/ecommerce/ecommerce.json.gz b/src/plugins/home/server/services/sample_data/data_sets/ecommerce/ecommerce.json.gz index b1a5dff7b2b5f..d47426df12ddf 100644 Binary files a/src/plugins/home/server/services/sample_data/data_sets/ecommerce/ecommerce.json.gz and b/src/plugins/home/server/services/sample_data/data_sets/ecommerce/ecommerce.json.gz differ diff --git a/src/plugins/home/server/services/sample_data/data_sets/ecommerce/field_mappings.ts b/src/plugins/home/server/services/sample_data/data_sets/ecommerce/field_mappings.ts index 5fecf8699bec8..c29df2c88fd74 100644 --- a/src/plugins/home/server/services/sample_data/data_sets/ecommerce/field_mappings.ts +++ b/src/plugins/home/server/services/sample_data/data_sets/ecommerce/field_mappings.ts @@ -173,4 +173,11 @@ export const fieldMappings = { city_name: { type: 'keyword' }, }, }, + event: { + properties: { + dataset: { + type: 'keyword', + }, + }, + }, }; diff --git a/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts b/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts index b2392742c0197..f680329045625 100644 --- a/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts +++ b/src/plugins/home/server/services/sample_data/data_sets/ecommerce/saved_objects.ts @@ -296,7 +296,7 @@ export const getSavedObjects = (): SavedObject[] => [ title: 'kibana_sample_data_ecommerce', timeFieldName: 'order_date', fields: - '[{"name":"_id","type":"string","esTypes":["_id"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"name":"_index","type":"string","esTypes":["_index"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"name":"_score","type":"number","count":0,"scripted":false,"searchable":false,"aggregatable":false,"readFromDocValues":false},{"name":"_source","type":"_source","esTypes":["_source"],"count":0,"scripted":false,"searchable":false,"aggregatable":false,"readFromDocValues":false},{"name":"_type","type":"string","esTypes":["_type"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"name":"category","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"category.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent": "category"}}},{"name":"currency","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"customer_birth_date","type":"date","esTypes":["date"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"customer_first_name","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"customer_first_name.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent": "customer_first_name"}}},{"name":"customer_full_name","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"customer_full_name.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent": "customer_full_name"}}},{"name":"customer_gender","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"customer_id","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"customer_last_name","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"customer_last_name.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent": "customer_last_name"}}},{"name":"customer_phone","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"day_of_week","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"day_of_week_i","type":"number","esTypes":["integer"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"email","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"geoip.city_name","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"geoip.continent_name","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"geoip.country_iso_code","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"geoip.location","type":"geo_point","esTypes":["geo_point"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"geoip.region_name","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"manufacturer","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"manufacturer.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent": "manufacturer"}}},{"name":"order_date","type":"date","esTypes":["date"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"order_id","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products._id","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"products._id.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent": "products._id"}}},{"name":"products.base_price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.base_unit_price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.category","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"products.category.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent": "products.category"}}},{"name":"products.created_on","type":"date","esTypes":["date"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.discount_amount","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.discount_percentage","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.manufacturer","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"products.manufacturer.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent": "products.manufacturer"}}},{"name":"products.min_price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.product_id","type":"number","esTypes":["long"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.product_name","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"products.product_name.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent": "products.product_name"}}},{"name":"products.quantity","type":"number","esTypes":["integer"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.sku","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.tax_amount","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.taxful_price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.taxless_price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.unit_discount_amount","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"sku","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"taxful_total_price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"taxless_total_price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"total_quantity","type":"number","esTypes":["integer"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"total_unique_products","type":"number","esTypes":["integer"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"type","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"user","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true}]', + '[{"name":"_id","type":"string","esTypes":["_id"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"name":"_index","type":"string","esTypes":["_index"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"name":"_score","type":"number","count":0,"scripted":false,"searchable":false,"aggregatable":false,"readFromDocValues":false},{"name":"_source","type":"_source","esTypes":["_source"],"count":0,"scripted":false,"searchable":false,"aggregatable":false,"readFromDocValues":false},{"name":"_type","type":"string","esTypes":["_type"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":false},{"name":"category","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"category.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"category"}}},{"name":"currency","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"customer_birth_date","type":"date","esTypes":["date"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"customer_first_name","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"customer_first_name.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"customer_first_name"}}},{"name":"customer_full_name","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"customer_full_name.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"customer_full_name"}}},{"name":"customer_gender","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"customer_id","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"customer_last_name","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"customer_last_name.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"customer_last_name"}}},{"name":"customer_phone","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"day_of_week","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"day_of_week_i","type":"number","esTypes":["integer"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"email","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"event.dataset","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"geoip.city_name","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"geoip.continent_name","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"geoip.country_iso_code","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"geoip.location","type":"geo_point","esTypes":["geo_point"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"geoip.region_name","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"manufacturer","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"manufacturer.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"manufacturer"}}},{"name":"order_date","type":"date","esTypes":["date"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"order_id","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products._id","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"products._id.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"products._id"}}},{"name":"products.base_price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.base_unit_price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.category","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"products.category.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"products.category"}}},{"name":"products.created_on","type":"date","esTypes":["date"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.discount_amount","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.discount_percentage","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.manufacturer","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"products.manufacturer.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"products.manufacturer"}}},{"name":"products.min_price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.product_id","type":"number","esTypes":["long"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.product_name","type":"string","esTypes":["text"],"count":0,"scripted":false,"searchable":true,"aggregatable":false,"readFromDocValues":false},{"name":"products.product_name.keyword","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true,"subType":{"multi":{"parent":"products.product_name"}}},{"name":"products.quantity","type":"number","esTypes":["integer"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.sku","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.tax_amount","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.taxful_price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.taxless_price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"products.unit_discount_amount","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"sku","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"taxful_total_price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"taxless_total_price","type":"number","esTypes":["half_float"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"total_quantity","type":"number","esTypes":["integer"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"total_unique_products","type":"number","esTypes":["integer"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"type","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true},{"name":"user","type":"string","esTypes":["keyword"],"count":0,"scripted":false,"searchable":true,"aggregatable":true,"readFromDocValues":true}]', fieldFormatMap: '{"taxful_total_price":{"id":"number","params":{"pattern":"$0,0.[00]"}}}', }, references: [], diff --git a/src/plugins/home/server/services/tutorials/lib/tutorial_schema.ts b/src/plugins/home/server/services/tutorials/lib/tutorial_schema.ts index 24f5a39feb4c5..32e5483b8b070 100644 --- a/src/plugins/home/server/services/tutorials/lib/tutorial_schema.ts +++ b/src/plugins/home/server/services/tutorials/lib/tutorial_schema.ts @@ -26,7 +26,7 @@ const PARAM_TYPES = { const TUTORIAL_CATEGORY = { LOGGING: 'logging', - SIEM: 'siem', + SECURITY_SOLUTION: 'security solution', METRICS: 'metrics', OTHER: 'other', }; diff --git a/src/plugins/home/server/services/tutorials/lib/tutorials_registry_types.ts b/src/plugins/home/server/services/tutorials/lib/tutorials_registry_types.ts index 80849513a3fad..3325240147640 100644 --- a/src/plugins/home/server/services/tutorials/lib/tutorials_registry_types.ts +++ b/src/plugins/home/server/services/tutorials/lib/tutorials_registry_types.ts @@ -22,7 +22,7 @@ import { KibanaRequest } from 'src/core/server'; /** @public */ export enum TutorialsCategory { LOGGING = 'logging', - SIEM = 'siem', + SECURITY_SOLUTION = 'security', METRICS = 'metrics', OTHER = 'other', } diff --git a/src/plugins/home/server/tutorials/auditbeat/index.ts b/src/plugins/home/server/tutorials/auditbeat/index.ts index dadbf913d5ed5..214fda5a7cc53 100644 --- a/src/plugins/home/server/tutorials/auditbeat/index.ts +++ b/src/plugins/home/server/tutorials/auditbeat/index.ts @@ -36,7 +36,7 @@ export function auditbeatSpecProvider(context: TutorialContext): TutorialSchema name: i18n.translate('home.tutorials.auditbeat.nameTitle', { defaultMessage: 'Auditbeat', }), - category: TutorialsCategory.SIEM, + category: TutorialsCategory.SECURITY_SOLUTION, shortDescription: i18n.translate('home.tutorials.auditbeat.shortDescription', { defaultMessage: 'Collect audit data from your hosts.', }), @@ -53,9 +53,9 @@ processes, users, logins, sockets information, file accesses, and more. \ artifacts: { dashboards: [], application: { - path: '/app/siem', + path: '/app/security', label: i18n.translate('home.tutorials.auditbeat.artifacts.dashboards.linkLabel', { - defaultMessage: 'SIEM App', + defaultMessage: 'Security App', }), }, exportedFields: { diff --git a/src/plugins/home/server/tutorials/cisco_logs/index.ts b/src/plugins/home/server/tutorials/cisco_logs/index.ts index 4514b61570b07..2322f503b80ce 100644 --- a/src/plugins/home/server/tutorials/cisco_logs/index.ts +++ b/src/plugins/home/server/tutorials/cisco_logs/index.ts @@ -37,7 +37,7 @@ export function ciscoLogsSpecProvider(context: TutorialContext): TutorialSchema name: i18n.translate('home.tutorials.ciscoLogs.nameTitle', { defaultMessage: 'Cisco', }), - category: TutorialsCategory.SIEM, + category: TutorialsCategory.SECURITY_SOLUTION, shortDescription: i18n.translate('home.tutorials.ciscoLogs.shortDescription', { defaultMessage: 'Collect and parse logs received from Cisco ASA firewalls.', }), @@ -54,9 +54,9 @@ supports the "asa" fileset for Cisco ASA firewall logs received over syslog or r artifacts: { dashboards: [], application: { - path: '/app/siem', + path: '/app/security', label: i18n.translate('home.tutorials.ciscoLogs.artifacts.dashboards.linkLabel', { - defaultMessage: 'SIEM App', + defaultMessage: 'Security App', }), }, exportedFields: { diff --git a/src/plugins/home/server/tutorials/coredns_logs/index.ts b/src/plugins/home/server/tutorials/coredns_logs/index.ts index 1c62366251661..4304fb7acb907 100644 --- a/src/plugins/home/server/tutorials/coredns_logs/index.ts +++ b/src/plugins/home/server/tutorials/coredns_logs/index.ts @@ -37,7 +37,7 @@ export function corednsLogsSpecProvider(context: TutorialContext): TutorialSchem name: i18n.translate('home.tutorials.corednsLogs.nameTitle', { defaultMessage: 'CoreDNS logs', }), - category: TutorialsCategory.SIEM, + category: TutorialsCategory.SECURITY_SOLUTION, shortDescription: i18n.translate('home.tutorials.corednsLogs.shortDescription', { defaultMessage: 'Collect the logs created by Coredns.', }), diff --git a/src/plugins/home/server/tutorials/envoyproxy_logs/index.ts b/src/plugins/home/server/tutorials/envoyproxy_logs/index.ts index 3d88cce36d752..a9b9c33d61bdf 100644 --- a/src/plugins/home/server/tutorials/envoyproxy_logs/index.ts +++ b/src/plugins/home/server/tutorials/envoyproxy_logs/index.ts @@ -37,7 +37,7 @@ export function envoyproxyLogsSpecProvider(context: TutorialContext): TutorialSc name: i18n.translate('home.tutorials.envoyproxyLogs.nameTitle', { defaultMessage: 'Envoyproxy', }), - category: TutorialsCategory.SIEM, + category: TutorialsCategory.SECURITY_SOLUTION, shortDescription: i18n.translate('home.tutorials.envoyproxyLogs.shortDescription', { defaultMessage: 'Collect and parse logs received from the Envoy proxy.', }), @@ -54,9 +54,9 @@ It supports both standalone deployment and Envoy proxy deployment in Kubernetes. artifacts: { dashboards: [], application: { - path: '/app/siem', + path: '/app/security', label: i18n.translate('home.tutorials.envoyproxyLogs.artifacts.dashboards.linkLabel', { - defaultMessage: 'SIEM App', + defaultMessage: 'Security App', }), }, exportedFields: { diff --git a/src/plugins/home/server/tutorials/iptables_logs/index.ts b/src/plugins/home/server/tutorials/iptables_logs/index.ts index e72e0ef300e04..fd84894dae850 100644 --- a/src/plugins/home/server/tutorials/iptables_logs/index.ts +++ b/src/plugins/home/server/tutorials/iptables_logs/index.ts @@ -37,7 +37,7 @@ export function iptablesLogsSpecProvider(context: TutorialContext): TutorialSche name: i18n.translate('home.tutorials.iptablesLogs.nameTitle', { defaultMessage: 'Iptables / Ubiquiti', }), - category: TutorialsCategory.SIEM, + category: TutorialsCategory.SECURITY_SOLUTION, shortDescription: i18n.translate('home.tutorials.iptablesLogs.shortDescription', { defaultMessage: 'Collect and parse iptables and ip6tables logs or from Ubiqiti firewalls.', }), @@ -56,9 +56,9 @@ number and the action performed on the traffic (allow/deny).. \ artifacts: { dashboards: [], application: { - path: '/app/siem', + path: '/app/security', label: i18n.translate('home.tutorials.iptablesLogs.artifacts.dashboards.linkLabel', { - defaultMessage: 'SIEM App', + defaultMessage: 'Security App', }), }, exportedFields: { diff --git a/src/plugins/home/server/tutorials/netflow/index.ts b/src/plugins/home/server/tutorials/netflow/index.ts index 7c6fcadcff625..ec0aa8953b146 100644 --- a/src/plugins/home/server/tutorials/netflow/index.ts +++ b/src/plugins/home/server/tutorials/netflow/index.ts @@ -28,7 +28,7 @@ export function netflowSpecProvider() { return { id: 'netflow', name: 'Netflow', - category: TutorialsCategory.SIEM, + category: TutorialsCategory.SECURITY_SOLUTION, shortDescription: i18n.translate('home.tutorials.netflow.tutorialShortDescription', { defaultMessage: 'Collect Netflow records sent by a Netflow exporter.', }), diff --git a/src/plugins/home/server/tutorials/osquery_logs/index.ts b/src/plugins/home/server/tutorials/osquery_logs/index.ts index 34a1b9e7f619d..8781d6201a771 100644 --- a/src/plugins/home/server/tutorials/osquery_logs/index.ts +++ b/src/plugins/home/server/tutorials/osquery_logs/index.ts @@ -37,7 +37,7 @@ export function osqueryLogsSpecProvider(context: TutorialContext): TutorialSchem name: i18n.translate('home.tutorials.osqueryLogs.nameTitle', { defaultMessage: 'Osquery logs', }), - category: TutorialsCategory.SIEM, + category: TutorialsCategory.SECURITY_SOLUTION, shortDescription: i18n.translate('home.tutorials.osqueryLogs.shortDescription', { defaultMessage: 'Collect the result logs created by osqueryd.', }), diff --git a/src/plugins/home/server/tutorials/suricata_logs/index.ts b/src/plugins/home/server/tutorials/suricata_logs/index.ts index c02cb05889ebb..6bcfc1d43a250 100644 --- a/src/plugins/home/server/tutorials/suricata_logs/index.ts +++ b/src/plugins/home/server/tutorials/suricata_logs/index.ts @@ -37,7 +37,7 @@ export function suricataLogsSpecProvider(context: TutorialContext): TutorialSche name: i18n.translate('home.tutorials.suricataLogs.nameTitle', { defaultMessage: 'Suricata logs', }), - category: TutorialsCategory.SIEM, + category: TutorialsCategory.SECURITY_SOLUTION, shortDescription: i18n.translate('home.tutorials.suricataLogs.shortDescription', { defaultMessage: 'Collect the result logs created by Suricata IDS/IPS/NSM.', }), diff --git a/src/plugins/home/server/tutorials/windows_event_logs/index.ts b/src/plugins/home/server/tutorials/windows_event_logs/index.ts index 5349bedb21279..c2ea9ff3015e4 100644 --- a/src/plugins/home/server/tutorials/windows_event_logs/index.ts +++ b/src/plugins/home/server/tutorials/windows_event_logs/index.ts @@ -36,7 +36,7 @@ export function windowsEventLogsSpecProvider(context: TutorialContext): Tutorial defaultMessage: 'Windows Event Log', }), isBeta: false, - category: TutorialsCategory.SIEM, + category: TutorialsCategory.SECURITY_SOLUTION, shortDescription: i18n.translate('home.tutorials.windowsEventLogs.shortDescription', { defaultMessage: 'Fetch logs from the Windows Event Log.', }), diff --git a/src/plugins/home/server/tutorials/zeek_logs/index.ts b/src/plugins/home/server/tutorials/zeek_logs/index.ts index 4bd54c96481b6..c273a93b1b0d5 100644 --- a/src/plugins/home/server/tutorials/zeek_logs/index.ts +++ b/src/plugins/home/server/tutorials/zeek_logs/index.ts @@ -37,7 +37,7 @@ export function zeekLogsSpecProvider(context: TutorialContext): TutorialSchema { name: i18n.translate('home.tutorials.zeekLogs.nameTitle', { defaultMessage: 'Zeek logs', }), - category: TutorialsCategory.SIEM, + category: TutorialsCategory.SECURITY_SOLUTION, shortDescription: i18n.translate('home.tutorials.zeekLogs.shortDescription', { defaultMessage: 'Collect the logs created by Zeek/Bro.', }), diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx index edb96f119385e..b6205a8731dfa 100644 --- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_index_pattern/step_index_pattern.tsx @@ -21,7 +21,11 @@ import React, { Component } from 'react'; import { EuiPanel, EuiSpacer, EuiCallOut } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { indexPatterns, IndexPatternAttributes } from '../../../../../../../plugins/data/public'; +import { + indexPatterns, + IndexPatternAttributes, + UI_SETTINGS, +} from '../../../../../../../plugins/data/public'; import { MAX_SEARCH_SIZE } from '../../constants'; import { getIndices, @@ -82,7 +86,8 @@ export class StepIndexPattern extends Component fieldWildcardMatcher(filters, uiSettings.get('metaFields')), + (filters: string[]) => fieldWildcardMatcher(filters, uiSettings.get(UI_SETTINGS.META_FIELDS)), [uiSettings] ); diff --git a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.tsx b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.tsx index a1b7289efee21..c97f19f59d340 100644 --- a/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.tsx +++ b/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.tsx @@ -35,7 +35,12 @@ import { import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { esQuery, IndexPattern, Query } from '../../../../../../../plugins/data/public'; +import { + esQuery, + IndexPattern, + Query, + UI_SETTINGS, +} from '../../../../../../../plugins/data/public'; import { context as contextType } from '../../../../../../kibana_react/public'; import { IndexPatternManagmentContextValue } from '../../../../types'; import { ExecuteScript } from '../../types'; @@ -244,7 +249,7 @@ export class TestScript extends Component { showDatePicker={false} showQueryInput={true} query={{ - language: this.context.services.uiSettings.get('search:queryLanguage'), + language: this.context.services.uiSettings.get(UI_SETTINGS.SEARCH_QUERY_LANGUAGE), query: '', }} onQuerySubmit={this.previewScript} diff --git a/src/plugins/inspector/public/views/data/components/data_table.tsx b/src/plugins/inspector/public/views/data/components/data_table.tsx index 69be069272f79..0fdf3d9b13e33 100644 --- a/src/plugins/inspector/public/views/data/components/data_table.tsx +++ b/src/plugins/inspector/public/views/data/components/data_table.tsx @@ -37,6 +37,7 @@ import { DataDownloadOptions } from './download_options'; import { DataViewRow, DataViewColumn } from '../types'; import { TabularData } from '../../../../common/adapters/data/types'; import { IUiSettingsClient } from '../../../../../../core/public'; +import { CSV_SEPARATOR_SETTING, CSV_QUOTE_VALUES_SETTING } from '../../../../../share/public'; interface DataTableFormatState { columns: DataViewColumn[]; @@ -58,8 +59,8 @@ export class DataTableFormat extends Component void); redirectTo?: string; @@ -127,7 +118,6 @@ export const configureAppAngularModule = ( .run($setupBreadcrumbsAutoClear(core, isLocalAngular)) .run($setupBadgeAutoClear(core, isLocalAngular)) .run($setupHelpExtensionAutoClear(core, isLocalAngular)) - .run($setupUrlOverflowHandling(core, isLocalAngular)) .run($setupUICapabilityRedirect(core)); }; @@ -390,68 +380,3 @@ const $setupHelpExtensionAutoClear = (newPlatform: CoreStart, isLocalAngular: bo newPlatform.chrome.setHelpExtension(current.helpExtension); }); }; - -const $setupUrlOverflowHandling = (newPlatform: CoreStart, isLocalAngular: boolean) => ( - $location: ILocationService, - $rootScope: IRootScopeService, - $injector: auto.IInjectorService -) => { - const $route = $injector.has('$route') ? $injector.get('$route') : {}; - const urlOverflow = new UrlOverflowService(); - const check = () => { - if (isDummyRoute($route, isLocalAngular)) { - return; - } - // disable long url checks when storing state in session storage - if (newPlatform.uiSettings.get('state:storeInSessionStorage')) { - return; - } - - if ($location.path() === '/error/url-overflow') { - return; - } - - try { - if (urlOverflow.check($location.absUrl()) <= URL_LIMIT_WARN_WITHIN) { - newPlatform.notifications.toasts.addWarning({ - title: i18n.translate('kibana_legacy.bigUrlWarningNotificationTitle', { - defaultMessage: 'The URL is big and Kibana might stop working', - }), - text: toMountPoint( - - state:storeInSessionStorage, - advancedSettingsLink: ( - - - - ), - }} - /> - - ), - }); - } - } catch (e) { - window.location.href = modifyUrl(window.location.href, (parts: any) => { - parts.hash = '#/error/url-overflow'; - }); - // force the browser to reload to that Kibana's potentially unstable state is unloaded - window.location.reload(); - } - }; - - $rootScope.$on('$routeUpdate', check); - $rootScope.$on('$routeChangeStart', check); -}; diff --git a/src/plugins/kibana_legacy/public/angular/kbn_top_nav.js b/src/plugins/kibana_legacy/public/angular/kbn_top_nav.js index a0faf4a6a071c..b3fbe8baadec3 100644 --- a/src/plugins/kibana_legacy/public/angular/kbn_top_nav.js +++ b/src/plugins/kibana_legacy/public/angular/kbn_top_nav.js @@ -94,11 +94,11 @@ export const createTopNavHelper = ({ TopNavMenu }) => (reactDirective) => { // All modifiers default to true. // Set to false to hide subcomponents. 'showSearchBar', - 'showFilterBar', 'showQueryBar', 'showQueryInput', - 'showDatePicker', 'showSaveQuery', + 'showDatePicker', + 'showFilterBar', 'appName', 'screenTitle', diff --git a/src/plugins/kibana_legacy/public/utils/index.ts b/src/plugins/kibana_legacy/public/utils/index.ts index 886ae0e877c38..339079d3ac352 100644 --- a/src/plugins/kibana_legacy/public/utils/index.ts +++ b/src/plugins/kibana_legacy/public/utils/index.ts @@ -19,7 +19,6 @@ export * from './migrate_legacy_query'; export * from './system_api'; -export * from './url_overflow_service'; // @ts-ignore export { KbnAccessibleClickProvider } from './kbn_accessible_click'; // @ts-ignore diff --git a/src/plugins/kibana_legacy/public/utils/url_overflow_service.ts b/src/plugins/kibana_legacy/public/utils/url_overflow_service.ts deleted file mode 100644 index e0c0f93bf36cd..0000000000000 --- a/src/plugins/kibana_legacy/public/utils/url_overflow_service.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -const URL_MAX_IE = 2000; -const URL_MAX_OTHERS = 25000; -export const IE_REGEX = /(; ?MSIE |Edge\/\d|Trident\/[\d+\.]+;.*rv:*11\.\d+)/; - -export class UrlOverflowService { - private readonly _ieLike: boolean; - private _val?: string | null; - private readonly _sync: () => void; - constructor() { - const key = 'error/url-overflow/url'; - const store = window.sessionStorage || { - getItem() {}, - setItem() {}, - removeItem() {}, - }; - - // FIXME: Couldn't find a way to test for browser compatibility without - // complex redirect and cookie based "feature-detection" page, so going - // with user-agent detection for now. - this._ieLike = IE_REGEX.test(window.navigator.userAgent); - - this._val = store.getItem(key); - this._sync = () => { - if (typeof this._val === 'string') { - store.setItem(key, this._val); - } else { - store.removeItem(key); - } - }; - } - - failLength() { - return this._ieLike ? URL_MAX_IE : URL_MAX_OTHERS; - } - - set(v: string) { - this._val = v; - this._sync(); - } - - get() { - return this._val; - } - - check(absUrl: string) { - if (!this.get()) { - const urlLength = absUrl.length; - const remaining = this.failLength() - urlLength; - - if (remaining > 0) { - return remaining; - } - - this.set(absUrl); - } - - throw new Error(` - The URL has gotten too big and kibana can no longer - continue. Please refresh to return to your previous state. - `); - } - - clear() { - this._val = undefined; - this._sync(); - } -} diff --git a/src/plugins/kibana_react/public/code_editor/code_editor.examples.tsx b/src/plugins/kibana_react/public/code_editor/code_editor.examples.tsx index b6d5f2c5460f6..892c97e0ffae0 100644 --- a/src/plugins/kibana_react/public/code_editor/code_editor.examples.tsx +++ b/src/plugins/kibana_react/public/code_editor/code_editor.examples.tsx @@ -20,7 +20,7 @@ import { action } from '@storybook/addon-actions'; import { storiesOf } from '@storybook/react'; import React from 'react'; -import { monaco as monacoEditor } from '@kbn/ui-shared-deps/monaco'; +import { monaco as monacoEditor } from '@kbn/monaco'; import { CodeEditor } from './code_editor'; // A sample language definition with a few example tokens diff --git a/src/plugins/kibana_react/public/code_editor/code_editor.test.tsx b/src/plugins/kibana_react/public/code_editor/code_editor.test.tsx index bcb46fac36856..2f0670226cf46 100644 --- a/src/plugins/kibana_react/public/code_editor/code_editor.test.tsx +++ b/src/plugins/kibana_react/public/code_editor/code_editor.test.tsx @@ -19,9 +19,11 @@ import React from 'react'; import { CodeEditor } from './code_editor'; -import { monaco } from '@kbn/ui-shared-deps/monaco'; +import { monaco } from '@kbn/monaco'; import { shallow } from 'enzyme'; +// disabled because this is a test, but also it seems we shouldn't need this? +/* eslint-disable-next-line @kbn/eslint/module_migration */ import 'monaco-editor/esm/vs/basic-languages/html/html.contribution.js'; // A sample language definition with a few example tokens diff --git a/src/plugins/kibana_react/public/code_editor/code_editor.tsx b/src/plugins/kibana_react/public/code_editor/code_editor.tsx index e8b118b804347..f049085ccff61 100644 --- a/src/plugins/kibana_react/public/code_editor/code_editor.tsx +++ b/src/plugins/kibana_react/public/code_editor/code_editor.tsx @@ -21,7 +21,7 @@ import React from 'react'; import ReactResizeDetector from 'react-resize-detector'; import MonacoEditor from 'react-monaco-editor'; -import { monaco } from '@kbn/ui-shared-deps/monaco'; +import { monaco } from '@kbn/monaco'; import { LIGHT_THEME, DARK_THEME } from './editor_theme'; diff --git a/src/plugins/kibana_react/public/code_editor/editor_theme.ts b/src/plugins/kibana_react/public/code_editor/editor_theme.ts index 586b4a568c348..91d66ce8cbf81 100644 --- a/src/plugins/kibana_react/public/code_editor/editor_theme.ts +++ b/src/plugins/kibana_react/public/code_editor/editor_theme.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { monaco } from '@kbn/ui-shared-deps/monaco'; +import { monaco } from '@kbn/monaco'; import darkTheme from '@elastic/eui/dist/eui_theme_dark.json'; import lightTheme from '@elastic/eui/dist/eui_theme_light.json'; diff --git a/src/plugins/kibana_utils/public/core/create_start_service_getter.ts b/src/plugins/kibana_utils/public/core/create_start_service_getter.ts index 14e2588a0a9cf..5e4a0f2bc7aeb 100644 --- a/src/plugins/kibana_utils/public/core/create_start_service_getter.ts +++ b/src/plugins/kibana_utils/public/core/create_start_service_getter.ts @@ -19,16 +19,17 @@ import { CoreStart, StartServicesAccessor } from '../../../../core/public'; -export interface StartServices { +export interface StartServices { plugins: Plugins; self: OwnContract; - core: CoreStart; + core: Core; } -export type StartServicesGetter = () => StartServices< - Plugins, - OwnContract ->; +export type StartServicesGetter< + Plugins = unknown, + OwnContract = unknown, + Core = CoreStart +> = () => StartServices; /** * Use this utility to create a synchronous *start* service getter in *setup* diff --git a/src/plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx b/src/plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx index 74cfd125c2e3a..46384fb3f27d5 100644 --- a/src/plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx +++ b/src/plugins/navigation/public/top_nav_menu/top_nav_menu.test.tsx @@ -29,6 +29,7 @@ const dataShim = { }; describe('TopNavMenu', () => { + const WRAPPER_SELECTOR = '.kbnTopNavMenu__wrapper'; const TOP_NAV_ITEM_SELECTOR = 'TopNavMenuItem'; const SEARCH_BAR_SELECTOR = 'SearchBar'; const menuItems: TopNavMenuData[] = [ @@ -51,18 +52,28 @@ describe('TopNavMenu', () => { it('Should render nothing when no config is provided', () => { const component = shallowWithIntl(); + expect(component.find(WRAPPER_SELECTOR).length).toBe(0); + expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(0); + expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(0); + }); + + it('Should not render menu items when config is empty', () => { + const component = shallowWithIntl(); + expect(component.find(WRAPPER_SELECTOR).length).toBe(0); expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(0); expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(0); }); it('Should render 1 menu item', () => { const component = shallowWithIntl(); + expect(component.find(WRAPPER_SELECTOR).length).toBe(1); expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(1); expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(0); }); it('Should render multiple menu items', () => { const component = shallowWithIntl(); + expect(component.find(WRAPPER_SELECTOR).length).toBe(1); expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(menuItems.length); expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(0); }); @@ -71,15 +82,25 @@ describe('TopNavMenu', () => { const component = shallowWithIntl( ); - + expect(component.find(WRAPPER_SELECTOR).length).toBe(1); expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(0); expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(1); }); + it('Should render menu items and search bar', () => { + const component = shallowWithIntl( + + ); + expect(component.find(WRAPPER_SELECTOR).length).toBe(1); + expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(menuItems.length); + expect(component.find(SEARCH_BAR_SELECTOR).length).toBe(1); + }); + it('Should render with a class name', () => { const component = shallowWithIntl( { return ( + {renderItems()} + + ); + } + + function renderSearchBar(): ReactElement | null { // Validate presense of all required fields - if (!showSearchBar || !props.data) return; + if (!showSearchBar || !props.data) return null; const { SearchBar } = props.data.ui; return ; } @@ -70,16 +95,7 @@ export function TopNavMenu(props: TopNavMenuProps) { const className = classNames('kbnTopNavMenu', props.className); return ( - - {renderItems()} - + {renderMenu(className)} {renderSearchBar()} ); diff --git a/src/plugins/saved_objects_management/public/lib/resolve_saved_objects.ts b/src/plugins/saved_objects_management/public/lib/resolve_saved_objects.ts index 952e9628d2846..79b8c33b84cfe 100644 --- a/src/plugins/saved_objects_management/public/lib/resolve_saved_objects.ts +++ b/src/plugins/saved_objects_management/public/lib/resolve_saved_objects.ts @@ -27,6 +27,7 @@ import { IIndexPattern, injectSearchSourceReferences, } from '../../../data/public'; +import { FailedImport } from './process_import_response'; type SavedObjectsRawDoc = Record; @@ -277,7 +278,7 @@ export async function resolveSavedObjects( // Keep track of how many we actually import because the user // can cancel an override let importedObjectCount = 0; - const failedImports: any[] = []; + const failedImports: FailedImport[] = []; // Start with the index patterns since everything is dependent on them await awaitEachItemInParallel(docTypes.indexPatterns, async (indexPatternDoc) => { try { @@ -291,7 +292,7 @@ export async function resolveSavedObjects( importedObjectCount++; } } catch (error) { - failedImports.push({ indexPatternDoc, error }); + failedImports.push({ obj: indexPatternDoc as any, error }); } }); diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap b/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap index 26ddb0809d24b..707e65d60870c 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/__snapshots__/saved_objects_table.test.tsx.snap @@ -277,6 +277,7 @@ exports[`SavedObjectsTable import should show the flyout 1`] = ` "getMetrics": [Function], }, }, + "getSearchStrategy": [MockFunction], "search": [MockFunction], "searchSource": Object { "create": [MockFunction], diff --git a/src/plugins/share/common/constants.ts b/src/plugins/share/common/constants.ts new file mode 100644 index 0000000000000..7ad8e39c279d3 --- /dev/null +++ b/src/plugins/share/common/constants.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const CSV_SEPARATOR_SETTING = 'csv:separator'; +export const CSV_QUOTE_VALUES_SETTING = 'csv:quoteValues'; diff --git a/src/plugins/share/public/components/__snapshots__/url_panel_content.test.tsx.snap b/src/plugins/share/public/components/__snapshots__/url_panel_content.test.tsx.snap index 8787e0c027375..cae7aa96a7c0e 100644 --- a/src/plugins/share/public/components/__snapshots__/url_panel_content.test.tsx.snap +++ b/src/plugins/share/public/components/__snapshots__/url_panel_content.test.tsx.snap @@ -44,7 +44,9 @@ exports[`share url panel content render 1`] = ` gutterSize="none" responsive={false} > - + - + - + - + - + - + - + - + `; + +exports[`should show url param extensions 1`] = ` + + + + } + labelType="label" + > + + + + + + + } + position="bottom" + /> + + , + }, + Object { + "data-test-subj": "exportAsSavedObject", + "disabled": false, + "id": "savedObject", + "label": + + + + + + } + position="bottom" + /> + + , + }, + ] + } + /> + + + + + + + + + } + onChange={[Function]} + /> + + + + } + position="bottom" + /> + + + + + + + + + +`; diff --git a/src/plugins/share/public/components/share_context_menu.tsx b/src/plugins/share/public/components/share_context_menu.tsx index c12e9dabd1938..26426853ddabe 100644 --- a/src/plugins/share/public/components/share_context_menu.tsx +++ b/src/plugins/share/public/components/share_context_menu.tsx @@ -26,7 +26,7 @@ import { EuiContextMenu, EuiContextMenuPanelDescriptor } from '@elastic/eui'; import { HttpStart } from 'kibana/public'; import { UrlPanelContent } from './url_panel_content'; -import { ShareMenuItem, ShareContextMenuPanelItem } from '../types'; +import { ShareMenuItem, ShareContextMenuPanelItem, UrlParamExtension } from '../types'; interface Props { allowEmbed: boolean; @@ -39,6 +39,7 @@ interface Props { onClose: () => void; basePath: string; post: HttpStart['post']; + embedUrlParamExtensions?: UrlParamExtension[]; } export class ShareContextMenu extends Component { @@ -100,6 +101,7 @@ export class ShareContextMenu extends Component { basePath={this.props.basePath} post={this.props.post} shareableUrl={this.props.shareableUrl} + urlParamExtensions={this.props.embedUrlParamExtensions} /> ), }; diff --git a/src/plugins/share/public/components/url_panel_content.test.tsx b/src/plugins/share/public/components/url_panel_content.test.tsx index bd30dbf002df8..481f8312f4262 100644 --- a/src/plugins/share/public/components/url_panel_content.test.tsx +++ b/src/plugins/share/public/components/url_panel_content.test.tsx @@ -202,3 +202,13 @@ describe('share url panel content', () => { }); }); }); + +test('should show url param extensions', () => { + const TestExtension = () =>
; + const extensions = [{ paramName: 'testExtension', component: TestExtension }]; + const component = shallow( + + ); + expect(component.find('TestExtension').length).toBe(1); + expect(component).toMatchSnapshot(); +}); diff --git a/src/plugins/share/public/components/url_panel_content.tsx b/src/plugins/share/public/components/url_panel_content.tsx index 2ece2052c4b95..65a8538693a49 100644 --- a/src/plugins/share/public/components/url_panel_content.tsx +++ b/src/plugins/share/public/components/url_panel_content.tsx @@ -17,7 +17,7 @@ * under the License. */ -import React, { Component } from 'react'; +import React, { Component, ReactElement } from 'react'; import { EuiButton, @@ -41,6 +41,7 @@ import { HttpStart } from 'kibana/public'; import { i18n } from '@kbn/i18n'; import { shortenUrl } from '../lib/url_shortener'; +import { UrlParamExtension } from '../types'; interface Props { allowShortUrl: boolean; @@ -50,6 +51,7 @@ interface Props { shareableUrl?: string; basePath: string; post: HttpStart['post']; + urlParamExtensions?: UrlParamExtension[]; } export enum ExportUrlAsType { @@ -57,12 +59,19 @@ export enum ExportUrlAsType { EXPORT_URL_AS_SNAPSHOT = 'snapshot', } +interface UrlParams { + [extensionName: string]: { + [queryParam: string]: boolean; + }; +} + interface State { exportUrlAs: ExportUrlAsType; useShortUrl: boolean; isCreatingShortUrl: boolean; url?: string; shortUrlErrorMsg?: string; + urlParams?: UrlParams; } export class UrlPanelContent extends Component { @@ -100,7 +109,7 @@ export class UrlPanelContent extends Component { {this.renderExportAsRadioGroup()} - + {this.renderUrlParamExtensions()} {this.renderShortUrlSwitch()} @@ -151,6 +160,13 @@ export class UrlPanelContent extends Component { } }; + private updateUrlParams = (url: string) => { + const embedUrl = this.props.isEmbedded ? this.makeUrlEmbeddable(url) : url; + const extendUrl = this.state.urlParams ? this.getUrlParamExtensions(embedUrl) : embedUrl; + + return extendUrl; + }; + private getSavedObjectUrl = () => { if (this.isNotSaved()) { return; @@ -166,7 +182,7 @@ export class UrlPanelContent extends Component { // Get the application route, after the hash, and remove the #. const parsedAppUrl = parseUrl(parsedUrl.hash.slice(1), true); - let formattedUrl = formatUrl({ + const formattedUrl = formatUrl({ protocol: parsedUrl.protocol, auth: parsedUrl.auth, host: parsedUrl.host, @@ -180,28 +196,42 @@ export class UrlPanelContent extends Component { }, }), }); - if (this.props.isEmbedded) { - formattedUrl = this.makeUrlEmbeddable(formattedUrl); - } - return formattedUrl; + return this.updateUrlParams(formattedUrl); }; private getSnapshotUrl = () => { - let url = this.props.shareableUrl || window.location.href; - if (this.props.isEmbedded) { - url = this.makeUrlEmbeddable(url); - } - return url; + const url = this.props.shareableUrl || window.location.href; + + return this.updateUrlParams(url); }; - private makeUrlEmbeddable = (url: string) => { - const embedQueryParam = '?embed=true'; + private makeUrlEmbeddable = (url: string): string => { + const embedParam = '?embed=true'; const urlHasQueryString = url.indexOf('?') !== -1; + if (urlHasQueryString) { - return url.replace('?', `${embedQueryParam}&`); + return url.replace('?', `${embedParam}&`); } - return `${url}${embedQueryParam}`; + + return `${url}${embedParam}`; + }; + + private getUrlParamExtensions = (url: string): string => { + const { urlParams } = this.state; + return urlParams + ? Object.keys(urlParams).reduce((urlAccumulator, key) => { + const urlParam = urlParams[key]; + return urlParam + ? Object.keys(urlParam).reduce((queryAccumulator, queryParam) => { + const isQueryParamEnabled = urlParam[queryParam]; + return isQueryParamEnabled + ? queryAccumulator + `&${queryParam}=true` + : queryAccumulator; + }, urlAccumulator) + : urlAccumulator; + }, url) + : url; }; private makeIframeTag = (url?: string) => { @@ -247,6 +277,10 @@ export class UrlPanelContent extends Component { } // "Use short URL" is checked but shortUrl has not been generated yet so one needs to be created. + this.createShortUrl(); + }; + + private createShortUrl = async () => { this.setState({ isCreatingShortUrl: true, shortUrlErrorMsg: undefined, @@ -262,7 +296,7 @@ export class UrlPanelContent extends Component { this.setState( { isCreatingShortUrl: false, - useShortUrl: isChecked, + useShortUrl: true, }, this.setUrl ); @@ -321,7 +355,7 @@ export class UrlPanelContent extends Component { private renderWithIconTip = (child: React.ReactNode, tipContent: React.ReactNode) => { return ( - {child} + {child} @@ -397,4 +431,34 @@ export class UrlPanelContent extends Component { ); }; + + private renderUrlParamExtensions = (): ReactElement | void => { + if (!this.props.urlParamExtensions) { + return; + } + + const setParamValue = (paramName: string) => ( + values: { [queryParam: string]: boolean } = {} + ): void => { + const stateUpdate = { + urlParams: { + ...this.state.urlParams, + [paramName]: { + ...values, + }, + }, + }; + this.setState(stateUpdate, this.state.useShortUrl ? this.createShortUrl : this.setUrl); + }; + + return ( + + {this.props.urlParamExtensions.map(({ paramName, component: UrlParamComponent }) => ( + + + + ))} + + ); + }; } diff --git a/src/plugins/share/public/index.ts b/src/plugins/share/public/index.ts index 183219645467e..e3d6c41a278cd 100644 --- a/src/plugins/share/public/index.ts +++ b/src/plugins/share/public/index.ts @@ -17,6 +17,8 @@ * under the License. */ +export { CSV_QUOTE_VALUES_SETTING, CSV_SEPARATOR_SETTING } from '../common/constants'; + export { UrlGeneratorStateMapping } from './url_generators/url_generator_definition'; export { SharePluginSetup, SharePluginStart } from './plugin'; diff --git a/src/plugins/share/public/services/share_menu_manager.tsx b/src/plugins/share/public/services/share_menu_manager.tsx index 35116efa85961..3325c5503fe89 100644 --- a/src/plugins/share/public/services/share_menu_manager.tsx +++ b/src/plugins/share/public/services/share_menu_manager.tsx @@ -67,6 +67,7 @@ export class ShareMenuManager { shareableUrl, post, basePath, + embedUrlParamExtensions, }: ShowShareMenuOptions & { menuItems: ShareMenuItem[]; post: HttpStart['post']; @@ -102,6 +103,7 @@ export class ShareMenuManager { onClose={this.onClose} post={post} basePath={basePath} + embedUrlParamExtensions={embedUrlParamExtensions} /> diff --git a/src/plugins/share/public/types.ts b/src/plugins/share/public/types.ts index 6b20f1f53a28c..8dda9f1195a39 100644 --- a/src/plugins/share/public/types.ts +++ b/src/plugins/share/public/types.ts @@ -17,6 +17,7 @@ * under the License. */ +import { ComponentType } from 'react'; import { EuiContextMenuPanelDescriptor, EuiContextMenuPanelItemDescriptor } from '@elastic/eui'; /** @@ -80,9 +81,19 @@ export interface ShareMenuProvider { getShareMenuItems: (context: ShareContext) => ShareMenuItem[]; } +interface UrlParamExtensionProps { + setParamValue: (values: {}) => void; +} + +export interface UrlParamExtension { + paramName: string; + component: ComponentType; +} + /** @public */ export interface ShowShareMenuOptions extends Omit { anchorElement: HTMLElement; allowEmbed: boolean; allowShortUrl: boolean; + embedUrlParamExtensions?: UrlParamExtension[]; } diff --git a/src/plugins/share/public/url_generators/url_generator_service.ts b/src/plugins/share/public/url_generators/url_generator_service.ts index 13c1b94acdd07..b63e2a45d6812 100644 --- a/src/plugins/share/public/url_generators/url_generator_service.ts +++ b/src/plugins/share/public/url_generators/url_generator_service.ts @@ -24,7 +24,7 @@ import { UrlGeneratorInternal } from './url_generator_internal'; import { UrlGeneratorContract } from './url_generator_contract'; export interface UrlGeneratorsStart { - getUrlGenerator: (urlGeneratorId: UrlGeneratorId) => UrlGeneratorContract; + getUrlGenerator: (urlGeneratorId: T) => UrlGeneratorContract; } export interface UrlGeneratorsSetup { diff --git a/src/plugins/share/server/index.ts b/src/plugins/share/server/index.ts index 9e574314f8000..ff419ce68d46b 100644 --- a/src/plugins/share/server/index.ts +++ b/src/plugins/share/server/index.ts @@ -20,6 +20,8 @@ import { PluginInitializerContext } from '../../../core/server'; import { SharePlugin } from './plugin'; +export { CSV_QUOTE_VALUES_SETTING, CSV_SEPARATOR_SETTING } from '../common/constants'; + export function plugin(initializerContext: PluginInitializerContext) { return new SharePlugin(initializerContext); } diff --git a/src/plugins/share/server/plugin.ts b/src/plugins/share/server/plugin.ts index 0d9f183d13404..e444cb1658d95 100644 --- a/src/plugins/share/server/plugin.ts +++ b/src/plugins/share/server/plugin.ts @@ -17,9 +17,12 @@ * under the License. */ +import { i18n } from '@kbn/i18n'; +import { schema } from '@kbn/config-schema'; import { CoreSetup, Plugin, PluginInitializerContext } from 'kibana/server'; import { createRoutes } from './routes/create_routes'; import { url } from './saved_objects'; +import { CSV_SEPARATOR_SETTING, CSV_QUOTE_VALUES_SETTING } from '../common/constants'; export class SharePlugin implements Plugin { constructor(private readonly initializerContext: PluginInitializerContext) {} @@ -27,6 +30,28 @@ export class SharePlugin implements Plugin { public async setup(core: CoreSetup) { createRoutes(core, this.initializerContext.logger.get()); core.savedObjects.registerType(url); + core.uiSettings.register({ + [CSV_SEPARATOR_SETTING]: { + name: i18n.translate('share.advancedSettings.csv.separatorTitle', { + defaultMessage: 'CSV separator', + }), + value: ',', + description: i18n.translate('share.advancedSettings.csv.separatorText', { + defaultMessage: 'Separate exported values with this string', + }), + schema: schema.string(), + }, + [CSV_QUOTE_VALUES_SETTING]: { + name: i18n.translate('share.advancedSettings.csv.quoteValuesTitle', { + defaultMessage: 'Quote CSV values', + }), + value: true, + description: i18n.translate('share.advancedSettings.csv.quoteValuesText', { + defaultMessage: 'Should values be quoted in csv exports?', + }), + schema: schema.boolean(), + }, + }); } public start() { diff --git a/src/plugins/vis_default_editor/public/components/controls/filters.tsx b/src/plugins/vis_default_editor/public/components/controls/filters.tsx index 7a655b935a45e..9a9933b5e1e83 100644 --- a/src/plugins/vis_default_editor/public/components/controls/filters.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/filters.tsx @@ -23,7 +23,7 @@ import { htmlIdGenerator, EuiButton, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { useMount } from 'react-use'; -import { Query } from 'src/plugins/data/public'; +import { Query, UI_SETTINGS } from '../../../../data/public'; import { useKibana } from '../../../../kibana_react/public'; import { FilterRow } from './filter'; import { AggParamEditorProps } from '../agg_param_props'; @@ -68,7 +68,7 @@ function FiltersParamEditor({ agg, value = [], setValue }: AggParamEditorProps) { setValue(value && agg.params.min_doc_count); } + /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [agg.params.min_doc_count, setValue, value]); return ( diff --git a/src/plugins/vis_default_editor/public/components/controls/number_interval.tsx b/src/plugins/vis_default_editor/public/components/controls/number_interval.tsx index 02bf680734526..0d21eb04c12b2 100644 --- a/src/plugins/vis_default_editor/public/components/controls/number_interval.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/number_interval.tsx @@ -23,6 +23,7 @@ import React, { useEffect, useCallback } from 'react'; import { EuiFieldNumber, EuiFormRow, EuiIconTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +import { UI_SETTINGS } from '../../../../data/public'; import { AggParamEditorProps } from '../agg_param_props'; @@ -38,7 +39,7 @@ const label = ( } type="questionInCircle" diff --git a/src/plugins/vis_default_editor/public/components/controls/utils/agg_utils.ts b/src/plugins/vis_default_editor/public/components/controls/utils/agg_utils.ts index ee24e2b42113d..950c856349230 100644 --- a/src/plugins/vis_default_editor/public/components/controls/utils/agg_utils.ts +++ b/src/plugins/vis_default_editor/public/components/controls/utils/agg_utils.ts @@ -33,6 +33,7 @@ const CUSTOM_METRIC = { }; function useCompatibleAggCallback(aggFilter: AggFilter) { + /* eslint-disable-next-line react-hooks/exhaustive-deps */ return useCallback(isCompatibleAggregation(aggFilter), [aggFilter]); } diff --git a/src/plugins/vis_type_table/public/agg_table/agg_table.js b/src/plugins/vis_type_table/public/agg_table/agg_table.js index f67dcf42adff6..bd7626a493338 100644 --- a/src/plugins/vis_type_table/public/agg_table/agg_table.js +++ b/src/plugins/vis_type_table/public/agg_table/agg_table.js @@ -17,6 +17,7 @@ * under the License. */ import _ from 'lodash'; +import { CSV_SEPARATOR_SETTING, CSV_QUOTE_VALUES_SETTING } from '../../../share/public'; import aggTableTemplate from './agg_table.html'; import { getFormatService } from '../services'; import { i18n } from '@kbn/i18n'; @@ -47,8 +48,8 @@ export function KbnAggTable(config, RecursionHelper) { self._saveAs = require('@elastic/filesaver').saveAs; self.csv = { - separator: config.get('csv:separator'), - quoteValues: config.get('csv:quoteValues'), + separator: config.get(CSV_SEPARATOR_SETTING), + quoteValues: config.get(CSV_QUOTE_VALUES_SETTING), }; self.exportAsCsv = function (formatted) { diff --git a/src/plugins/vis_type_timelion/public/components/panel.tsx b/src/plugins/vis_type_timelion/public/components/panel.tsx index 4c28e4e5a18ab..99c5532c04832 100644 --- a/src/plugins/vis_type_timelion/public/components/panel.tsx +++ b/src/plugins/vis_type_timelion/public/components/panel.tsx @@ -102,6 +102,7 @@ function Panel({ interval, seriesList, renderComplete }: PanelProps) { [chartElem] ); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const highlightSeries = useCallback( debounce(({ currentTarget }: JQuery.TriggeredEvent) => { const id = Number(currentTarget.getAttribute(SERIES_ID_ATTR)); @@ -295,6 +296,7 @@ function Panel({ interval, seriesList, renderComplete }: PanelProps) { [plot, legendValueNumbers, unhighlightSeries, legendCaption] ); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const debouncedSetLegendNumbers = useCallback( debounce(setLegendNumbers, DEBOUNCE_DELAY, { maxWait: DEBOUNCE_DELAY, diff --git a/src/plugins/vis_type_timelion/public/components/timelion_expression_input.tsx b/src/plugins/vis_type_timelion/public/components/timelion_expression_input.tsx index 8c76b41df0ced..8258b92b096c1 100644 --- a/src/plugins/vis_type_timelion/public/components/timelion_expression_input.tsx +++ b/src/plugins/vis_type_timelion/public/components/timelion_expression_input.tsx @@ -20,7 +20,7 @@ import React, { useEffect, useCallback, useRef, useMemo } from 'react'; import { EuiFormLabel } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { monaco } from '@kbn/ui-shared-deps/monaco'; +import { monaco } from '@kbn/monaco'; import { CodeEditor, useKibana } from '../../../kibana_react/public'; import { suggest, getSuggestion } from './timelion_expression_input_helpers'; diff --git a/src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.ts b/src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.ts index f7b3433105b76..8db057cdb3cc5 100644 --- a/src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.ts +++ b/src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.ts @@ -19,7 +19,7 @@ import { get, startsWith } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { monaco } from '@kbn/ui-shared-deps/monaco'; +import { monaco } from '@kbn/monaco'; import { Parser } from 'pegjs'; diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js b/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js index 1bc979399b1b1..a624ff72ead69 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js +++ b/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js @@ -30,6 +30,7 @@ import _ from 'lodash'; import { expect } from 'chai'; import sinon from 'sinon'; import invoke from '../helpers/invoke_series_fn.js'; +import { UI_SETTINGS } from '../../../../data/server'; function stubRequestAndServer(response, indexPatternSavedObjects = []) { return { @@ -216,14 +217,14 @@ describe('es', () => { it('sets ignore_throttled=true on the request', () => { config.index = 'beer'; - tlConfig.settings['search:includeFrozen'] = false; + tlConfig.settings[UI_SETTINGS.SEARCH_INCLUDE_FROZEN] = false; const request = fn(config, tlConfig, emptyScriptedFields); expect(request.ignore_throttled).to.equal(true); }); it('sets no timeout if elasticsearch.shardTimeout is set to 0', () => { - tlConfig.settings['search:includeFrozen'] = true; + tlConfig.settings[UI_SETTINGS.SEARCH_INCLUDE_FROZEN] = true; config.index = 'beer'; const request = fn(config, tlConfig, emptyScriptedFields); diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/lib/build_request.js b/src/plugins/vis_type_timelion/server/series_functions/es/lib/build_request.js index 65b28fb833279..bc0e368fbdab1 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/es/lib/build_request.js +++ b/src/plugins/vis_type_timelion/server/series_functions/es/lib/build_request.js @@ -21,6 +21,7 @@ import _ from 'lodash'; import moment from 'moment'; import { buildAggBody } from './agg_body'; import createDateAgg from './create_date_agg'; +import { UI_SETTINGS } from '../../../../../data/server'; export default function buildRequest(config, tlConfig, scriptedFields, timeout) { const bool = { must: [] }; @@ -78,7 +79,7 @@ export default function buildRequest(config, tlConfig, scriptedFields, timeout) const request = { index: config.index, - ignore_throttled: !tlConfig.settings['search:includeFrozen'], + ignore_throttled: !tlConfig.settings[UI_SETTINGS.SEARCH_INCLUDE_FROZEN], body: { query: { bool: bool, diff --git a/src/plugins/vis_type_timeseries/public/application/components/lib/get_default_query_language.js b/src/plugins/vis_type_timeseries/public/application/components/lib/get_default_query_language.js index 972f937ad109d..84da28718e323 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/lib/get_default_query_language.js +++ b/src/plugins/vis_type_timeseries/public/application/components/lib/get_default_query_language.js @@ -18,7 +18,8 @@ */ import { getUISettings } from '../../../services'; +import { UI_SETTINGS } from '../../../../../data/public'; export function getDefaultQueryLanguage() { - return getUISettings().get('search:queryLanguage'); + return getUISettings().get(UI_SETTINGS.SEARCH_QUERY_LANGUAGE); } diff --git a/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.test.js b/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.test.js index 71e82770bfa03..308579126eeb1 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.test.js +++ b/src/plugins/vis_type_timeseries/public/application/components/lib/tick_formatter.test.js @@ -20,6 +20,7 @@ import { createTickFormatter } from './tick_formatter'; import { getFieldFormatsRegistry } from '../../../../../../test_utils/public/stub_field_formats'; import { setFieldFormats } from '../../../services'; +import { UI_SETTINGS } from '../../../../../data/public'; const mockUiSettings = { get: (item) => { @@ -28,11 +29,11 @@ const mockUiSettings = { getUpdate$: () => ({ subscribe: jest.fn(), }), - 'query:allowLeadingWildcards': true, - 'query:queryString:options': {}, - 'courier:ignoreFilterIfFieldNotInIndex': true, + [UI_SETTINGS.QUERY_ALLOW_LEADING_WILDCARDS]: true, + [UI_SETTINGS.QUERY_STRING_OPTIONS]: {}, + [UI_SETTINGS.COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX]: true, 'dateFormat:tz': 'Browser', - 'format:defaultTypeMap': {}, + [UI_SETTINGS.FORMAT_DEFAULT_TYPE_MAP]: {}, }; const mockCore = { @@ -55,7 +56,7 @@ describe('createTickFormatter(format, template)', () => { test('returns a percent with percent formatter', () => { const config = { - 'format:percent:defaultPattern': '0.[00]%', + [UI_SETTINGS.FORMAT_PERCENT_DEFAULT_PATTERN]: '0.[00]%', }; const fn = createTickFormatter('percent', null, (key) => config[key]); expect(fn(0.5556)).toEqual('55.56%'); @@ -63,7 +64,7 @@ describe('createTickFormatter(format, template)', () => { test('returns a byte formatted string with byte formatter', () => { const config = { - 'format:bytes:defaultPattern': '0.0b', + [UI_SETTINGS.FORMAT_BYTES_DEFAULT_PATTERN]: '0.0b', }; const fn = createTickFormatter('bytes', null, (key) => config[key]); expect(fn(1500 ^ 10)).toEqual('1.5KB'); @@ -76,7 +77,7 @@ describe('createTickFormatter(format, template)', () => { test('returns a located string with custom locale setting', () => { const config = { - 'format:number:defaultLocale': 'fr', + [UI_SETTINGS.FORMAT_NUMBER_DEFAULT_LOCALE]: 'fr', }; const fn = createTickFormatter('0,0.0', null, (key) => config[key]); expect(fn(1500)).toEqual('1 500,0'); @@ -99,7 +100,7 @@ describe('createTickFormatter(format, template)', () => { test('returns formatted value if passed a bad template', () => { const config = { - 'format:number:defaultPattern': '0,0.[00]', + [UI_SETTINGS.FORMAT_NUMBER_DEFAULT_PATTERN]: '0,0.[00]', }; const fn = createTickFormatter('number', '{{value', (key) => config[key]); expect(fn(1.5556)).toEqual('1.56'); diff --git a/src/plugins/vis_type_timeseries/public/application/components/panel_config/timeseries.js b/src/plugins/vis_type_timeseries/public/application/components/panel_config/timeseries.js index 0b8b4be67b7a0..3e5e335a9ea39 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/panel_config/timeseries.js +++ b/src/plugins/vis_type_timeseries/public/application/components/panel_config/timeseries.js @@ -61,6 +61,7 @@ class TimeseriesPanelConfigUi extends Component { axis_min: '', legend_position: 'right', show_grid: 1, + tooltip_mode: 'show_all', }; const model = { ...defaults, ...this.props.model }; const { selectedTab } = this.state; @@ -85,6 +86,22 @@ class TimeseriesPanelConfigUi extends Component { value: 'left', }, ]; + const tooltipModeOptions = [ + { + label: intl.formatMessage({ + id: 'visTypeTimeseries.timeseries.tooltipOptions.showAll', + defaultMessage: 'Show all values', + }), + value: 'show_all', + }, + { + label: intl.formatMessage({ + id: 'visTypeTimeseries.timeseries.tooltipOptions.showFocused', + defaultMessage: 'Show focused values', + }), + value: 'show_focused', + }, + ]; const selectedPositionOption = positionOptions.find((option) => { return model.axis_position === option.value; }); @@ -134,6 +151,10 @@ class TimeseriesPanelConfigUi extends Component { return model.legend_position === option.value; }); + const selectedTooltipMode = tooltipModeOptions.find((option) => { + return model.tooltip_mode === option.value; + }); + let view; if (selectedTab === 'data') { view = ( @@ -356,6 +377,24 @@ class TimeseriesPanelConfigUi extends Component { + + + + + + + +
diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js b/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js index 0c53ddd3f0ba8..a96890d4d1502 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js @@ -29,7 +29,7 @@ import { PanelConfig } from './panel_config'; import { createBrushHandler } from '../lib/create_brush_handler'; import { fetchFields } from '../lib/fetch_fields'; import { extractIndexPatterns } from '../../../../../plugins/vis_type_timeseries/common/extract_index_patterns'; -import { esKuery } from '../../../../../plugins/data/public'; +import { esKuery, UI_SETTINGS } from '../../../../../plugins/data/public'; import { getSavedObjectsClient, getUISettings, getDataStart, getCoreStart } from '../../services'; import { CoreStartContextProvider } from '../contexts/query_input_bar_context'; @@ -89,7 +89,9 @@ export class VisEditor extends Component { isValidKueryQuery = (filterQuery) => { if (filterQuery && filterQuery.language === 'kuery') { try { - const queryOptions = this.coreContext.uiSettings.get('query:allowLeadingWildcards'); + const queryOptions = this.coreContext.uiSettings.get( + UI_SETTINGS.QUERY_ALLOW_LEADING_WILDCARDS + ); esKuery.fromKueryExpression(filterQuery.query, { allowLeadingWildcards: queryOptions }); } catch (error) { return false; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js index b4c563f3c11fd..ddfaf3c1428d9 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js @@ -250,6 +250,7 @@ export class TimeseriesVisualization extends Component { showGrid={Boolean(model.show_grid)} legend={Boolean(model.show_legend)} legendPosition={model.legend_position} + tooltipMode={model.tooltip_mode} xAxisLabel={getAxisLabelString(interval)} xAxisFormatter={this.xAxisFormatter(interval)} annotations={this.prepareAnnotations()} diff --git a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js index 274b46bce2715..c53482b5db075 100644 --- a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js +++ b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js @@ -61,6 +61,7 @@ export const TimeSeries = ({ showGrid, legend, legendPosition, + tooltipMode, xAxisLabel, series, yAxis, @@ -131,7 +132,7 @@ export const TimeSeries = ({ baseTheme={theme} tooltip={{ snap: true, - type: TooltipType.VerticalCursor, + type: tooltipMode === 'show_focused' ? TooltipType.Follow : TooltipType.VerticalCursor, headerFormatter: tooltipFormatter, }} /> diff --git a/src/plugins/vis_type_timeseries/public/metrics_type.ts b/src/plugins/vis_type_timeseries/public/metrics_type.ts index 2b0734ceb4d4d..c06f94efb3c49 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_type.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_type.ts @@ -69,6 +69,7 @@ export const metricsVisDefinition = { axis_scale: 'normal', show_legend: 1, show_grid: 1, + tooltip_mode: 'show_all', }, component: VisEditor, }, diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.js index 93a4eaba4ad9e..9ada39e359589 100644 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.js +++ b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.js @@ -17,12 +17,15 @@ * under the License. */ import { AbstractSearchRequest } from './abstract_request'; +import { UI_SETTINGS } from '../../../../../data/server'; const SEARCH_METHOD = 'msearch'; export class MultiSearchRequest extends AbstractSearchRequest { async search(searches) { - const includeFrozen = await this.req.getUiSettingsService().get('search:includeFrozen'); + const includeFrozen = await this.req + .getUiSettingsService() + .get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); const multiSearchBody = searches.reduce( (acc, { body, index }) => [ ...acc, diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.test.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.test.js index 1e28965a35793..c113db76332b7 100644 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/multi_search_request.test.js @@ -17,6 +17,7 @@ * under the License. */ import { MultiSearchRequest } from './multi_search_request'; +import { UI_SETTINGS } from '../../../../../data/server'; describe('MultiSearchRequest', () => { let searchRequest; @@ -51,7 +52,7 @@ describe('MultiSearchRequest', () => { expect(responses).toEqual([]); expect(req.getUiSettingsService).toHaveBeenCalled(); - expect(getServiceMock).toHaveBeenCalledWith('search:includeFrozen'); + expect(getServiceMock).toHaveBeenCalledWith(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); expect(callWithRequest).toHaveBeenCalledWith(req, 'msearch', { body: [ { ignoreUnavailable: true, index: 'index' }, diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.js index 110deb6a9bc1b..7d8b60a7e4595 100644 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.js +++ b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.js @@ -17,12 +17,15 @@ * under the License. */ import { AbstractSearchRequest } from './abstract_request'; +import { UI_SETTINGS } from '../../../../../data/server'; const SEARCH_METHOD = 'search'; export class SingleSearchRequest extends AbstractSearchRequest { async search([{ body, index }]) { - const includeFrozen = await this.req.getUiSettingsService().get('search:includeFrozen'); + const includeFrozen = await this.req + .getUiSettingsService() + .get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); const resp = await this.callWithRequest(this.req, SEARCH_METHOD, { ignore_throttled: !includeFrozen, body, diff --git a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.test.js b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.test.js index 043bd52d87aad..b899814f2fe13 100644 --- a/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/search_strategies/search_requests/single_search_request.test.js @@ -17,6 +17,7 @@ * under the License. */ import { SingleSearchRequest } from './single_search_request'; +import { UI_SETTINGS } from '../../../../../data/server'; describe('SingleSearchRequest', () => { let searchRequest; @@ -48,7 +49,7 @@ describe('SingleSearchRequest', () => { expect(responses).toEqual([{}]); expect(req.getUiSettingsService).toHaveBeenCalled(); - expect(getServiceMock).toHaveBeenCalledWith('search:includeFrozen'); + expect(getServiceMock).toHaveBeenCalledWith(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); expect(callWithRequest).toHaveBeenCalledWith(req, 'search', { body: 'body', index: 'index', diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_es_query_uisettings.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_es_query_uisettings.js index 42b8681f142e0..b427e5f12cadc 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_es_query_uisettings.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_es_query_uisettings.js @@ -17,12 +17,14 @@ * under the License. */ +import { UI_SETTINGS } from '../../../../../data/server'; + export async function getEsQueryConfig(req) { const uiSettings = req.getUiSettingsService(); - const allowLeadingWildcards = await uiSettings.get('query:allowLeadingWildcards'); - const queryStringOptions = await uiSettings.get('query:queryString:options'); + const allowLeadingWildcards = await uiSettings.get(UI_SETTINGS.QUERY_ALLOW_LEADING_WILDCARDS); + const queryStringOptions = await uiSettings.get(UI_SETTINGS.QUERY_STRING_OPTIONS); const ignoreFilterIfFieldNotInIndex = await uiSettings.get( - 'courier:ignoreFilterIfFieldNotInIndex' + UI_SETTINGS.COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX ); return { allowLeadingWildcards, diff --git a/src/plugins/vis_type_timeseries/server/routes/post_vis_schema.ts b/src/plugins/vis_type_timeseries/server/routes/post_vis_schema.ts index e8838f57ae365..bf2ea8651c5a2 100644 --- a/src/plugins/vis_type_timeseries/server/routes/post_vis_schema.ts +++ b/src/plugins/vis_type_timeseries/server/routes/post_vis_schema.ts @@ -247,6 +247,9 @@ export const visPayloadSchema = schema.object({ series: schema.arrayOf(seriesItems), show_grid: numberIntegerRequired, show_legend: numberIntegerRequired, + tooltip_mode: schema.maybe( + schema.oneOf([schema.literal('show_all'), schema.literal('show_focused')]) + ), time_field: stringOptionalNullable, time_range_mode: stringOptionalNullable, type: stringRequired, diff --git a/src/plugins/visualizations/common/constants.ts b/src/plugins/visualizations/common/constants.ts new file mode 100644 index 0000000000000..9129f060c5eef --- /dev/null +++ b/src/plugins/visualizations/common/constants.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const VISUALIZE_ENABLE_LABS_SETTING = 'visualize:enableLabs'; diff --git a/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts b/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts index 81794c31527ad..45c750de05ae1 100644 --- a/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts +++ b/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts @@ -29,6 +29,7 @@ import { getCapabilities, } from '../services'; import { VisualizeEmbeddableFactoryDeps } from './visualize_embeddable_factory'; +import { VISUALIZE_ENABLE_LABS_SETTING } from '../../common/constants'; export const createVisEmbeddableFromObject = (deps: VisualizeEmbeddableFactoryDeps) => async ( vis: Vis, @@ -44,7 +45,7 @@ export const createVisEmbeddableFromObject = (deps: VisualizeEmbeddableFactoryDe const editUrl = visId ? getHttp().basePath.prepend(`/app/visualize${savedVisualizations.urlFor(visId)}`) : ''; - const isLabsEnabled = getUISettings().get('visualize:enableLabs'); + const isLabsEnabled = getUISettings().get(VISUALIZE_ENABLE_LABS_SETTING); if (!isLabsEnabled && vis.type.stage === 'experimental') { return new DisabledLabEmbeddable(vis.title, input); diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx index c4aa4c262edb0..c4267c9a36f78 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx @@ -43,6 +43,7 @@ import { convertToSerializedVis } from '../saved_visualizations/_saved_vis'; import { createVisEmbeddableFromObject } from './create_vis_embeddable_from_object'; import { StartServicesGetter } from '../../../kibana_utils/public'; import { VisualizationsStartDeps } from '../plugin'; +import { VISUALIZE_ENABLE_LABS_SETTING } from '../../common/constants'; interface VisualizationAttributes extends SavedObjectAttributes { visState: string; @@ -82,7 +83,7 @@ export class VisualizeEmbeddableFactory if (!visType) { return false; } - if (getUISettings().get('visualize:enableLabs')) { + if (getUISettings().get(VISUALIZE_ENABLE_LABS_SETTING)) { return true; } return visType.stage !== 'experimental'; diff --git a/src/plugins/visualizations/public/index.ts b/src/plugins/visualizations/public/index.ts index e475684ed5934..0bbf862216ed5 100644 --- a/src/plugins/visualizations/public/index.ts +++ b/src/plugins/visualizations/public/index.ts @@ -17,8 +17,6 @@ * under the License. */ -import './index.scss'; - import { PublicContract } from '@kbn/utility-types'; import { PluginInitializerContext } from 'src/core/public'; import { VisualizationsPlugin, VisualizationsSetup, VisualizationsStart } from './plugin'; @@ -53,3 +51,4 @@ export { VisSavedObject, VisResponseValue, } from './types'; +export { VISUALIZE_ENABLE_LABS_SETTING } from '../common/constants'; diff --git a/src/plugins/visualizations/public/mocks.ts b/src/plugins/visualizations/public/mocks.ts index 70c3bc2c1ed05..05644eddc5fca 100644 --- a/src/plugins/visualizations/public/mocks.ts +++ b/src/plugins/visualizations/public/mocks.ts @@ -66,6 +66,7 @@ const createInstance = async () => { inspector: inspectorPluginMock.createStartContract(), uiActions: uiActionsPluginMock.createStartContract(), application: applicationServiceMock.createStartContract(), + embeddable: embeddablePluginMock.createStartContract(), }); return { diff --git a/src/plugins/visualizations/public/plugin.ts b/src/plugins/visualizations/public/plugin.ts index ef64eccfea31f..3546fa4056491 100644 --- a/src/plugins/visualizations/public/plugin.ts +++ b/src/plugins/visualizations/public/plugin.ts @@ -17,6 +17,8 @@ * under the License. */ +import './index.scss'; + import { PluginInitializerContext, CoreSetup, @@ -45,6 +47,7 @@ import { setChrome, setOverlays, setSavedSearchLoader, + setEmbeddable, } from './services'; import { VISUALIZE_EMBEDDABLE_TYPE, @@ -52,7 +55,7 @@ import { createVisEmbeddableFromObject, } from './embeddable'; import { ExpressionsSetup, ExpressionsStart } from '../../expressions/public'; -import { EmbeddableSetup } from '../../embeddable/public'; +import { EmbeddableSetup, EmbeddableStart } from '../../embeddable/public'; import { visualization as visualizationFunction } from './expressions/visualization_function'; import { visualization as visualizationRenderer } from './expressions/visualization_renderer'; import { range as rangeExpressionFunction } from './expression_functions/range'; @@ -102,6 +105,7 @@ export interface VisualizationsSetupDeps { export interface VisualizationsStartDeps { data: DataPublicPluginStart; expressions: ExpressionsStart; + embeddable: EmbeddableStart; inspector: InspectorStart; uiActions: UiActionsStart; application: ApplicationStart; @@ -151,11 +155,12 @@ export class VisualizationsPlugin public start( core: CoreStart, - { data, expressions, uiActions }: VisualizationsStartDeps + { data, expressions, uiActions, embeddable }: VisualizationsStartDeps ): VisualizationsStart { const types = this.types.start(); setI18n(core.i18n); setTypes(types); + setEmbeddable(embeddable); setApplication(core.application); setCapabilities(core.application.capabilities); setHttp(core.http); diff --git a/src/plugins/visualizations/public/services.ts b/src/plugins/visualizations/public/services.ts index 15055022af8aa..0761b8862e8e3 100644 --- a/src/plugins/visualizations/public/services.ts +++ b/src/plugins/visualizations/public/services.ts @@ -40,6 +40,7 @@ import { ExpressionsStart } from '../../../plugins/expressions/public'; import { UiActionsStart } from '../../../plugins/ui_actions/public'; import { SavedVisualizationsLoader } from './saved_visualizations'; import { SavedObjectLoader } from '../../saved_objects/public'; +import { EmbeddableStart } from '../../embeddable/public'; export const [getUISettings, setUISettings] = createGetterSetter('UISettings'); @@ -49,6 +50,8 @@ export const [getHttp, setHttp] = createGetterSetter('Http'); export const [getApplication, setApplication] = createGetterSetter('Application'); +export const [getEmbeddable, setEmbeddable] = createGetterSetter('Embeddable'); + export const [getSavedObjects, setSavedObjects] = createGetterSetter( 'SavedObjects' ); diff --git a/src/plugins/visualizations/public/wizard/new_vis_modal.tsx b/src/plugins/visualizations/public/wizard/new_vis_modal.tsx index cea92b1db93aa..1a970e505b7c7 100644 --- a/src/plugins/visualizations/public/wizard/new_vis_modal.tsx +++ b/src/plugins/visualizations/public/wizard/new_vis_modal.tsx @@ -29,6 +29,7 @@ import { TypeSelection } from './type_selection'; import { TypesStart, VisType, VisTypeAlias } from '../vis_types'; import { UsageCollectionSetup } from '../../../../plugins/usage_collection/public'; import { EMBEDDABLE_ORIGINATING_APP_PARAM } from '../../../embeddable/public'; +import { VISUALIZE_ENABLE_LABS_SETTING } from '../../common/constants'; interface TypeSelectionProps { isOpen: boolean; @@ -65,7 +66,7 @@ class NewVisModal extends React.Component originatingApp; const visStateToEditorState = () => { diff --git a/src/plugins/visualize/public/application/listing/visualize_listing.js b/src/plugins/visualize/public/application/listing/visualize_listing.js index 228cfa1e9e492..e8e8d92034113 100644 --- a/src/plugins/visualize/public/application/listing/visualize_listing.js +++ b/src/plugins/visualize/public/application/listing/visualize_listing.js @@ -25,6 +25,8 @@ import { i18n } from '@kbn/i18n'; import { getServices } from '../../kibana_services'; import { syncQueryStateWithUrl } from '../../../../data/public'; +import { VISUALIZE_ENABLE_LABS_SETTING } from '../../../../visualizations/public'; + import { EuiLink } from '@elastic/eui'; import React from 'react'; @@ -120,7 +122,7 @@ export function VisualizeListingController($scope, createNewVis, kbnUrlStateStor } this.fetchItems = (filter) => { - const isLabsEnabled = uiSettings.get('visualize:enableLabs'); + const isLabsEnabled = uiSettings.get(VISUALIZE_ENABLE_LABS_SETTING); return savedVisualizations .findListItems(filter, savedObjectsPublic.settings.getListingLimit()) .then((result) => { diff --git a/test/plugin_functional/test_suites/bfetch_explorer/batched_function.ts b/test/examples/bfetch_explorer/batched_function.ts similarity index 93% rename from test/plugin_functional/test_suites/bfetch_explorer/batched_function.ts rename to test/examples/bfetch_explorer/batched_function.ts index 25c5ba4a7ca3e..3fe17169dde7e 100644 --- a/test/plugin_functional/test_suites/bfetch_explorer/batched_function.ts +++ b/test/examples/bfetch_explorer/batched_function.ts @@ -18,15 +18,14 @@ */ import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../../functional/ftr_provider_context'; +import { FtrProviderContext } from '../../functional/ftr_provider_context'; +// eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); - const appsMenu = getService('appsMenu'); describe('batchedFunction', () => { beforeEach(async () => { - await appsMenu.clickLink('bfetch explorer'); await testSubjects.click('count-until'); await testSubjects.click('double-integers'); }); diff --git a/test/examples/bfetch_explorer/index.ts b/test/examples/bfetch_explorer/index.ts new file mode 100644 index 0000000000000..1f039a2ea415c --- /dev/null +++ b/test/examples/bfetch_explorer/index.ts @@ -0,0 +1,35 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { FtrProviderContext } from '../../functional/ftr_provider_context'; + +// eslint-disable-next-line import/no-default-export +export default function ({ getService, getPageObjects, loadTestFile }: FtrProviderContext) { + const browser = getService('browser'); + const PageObjects = getPageObjects(['common', 'header']); + + describe('bfetch explorer', function () { + before(async () => { + await browser.setWindowSize(1300, 900); + await PageObjects.common.navigateToApp('bfetch-explorer', { insertTimestamp: false }); + }); + + loadTestFile(require.resolve('./batched_function')); + }); +} diff --git a/test/examples/config.js b/test/examples/config.js index aedd06c31d413..228af71a1f5d0 100644 --- a/test/examples/config.js +++ b/test/examples/config.js @@ -27,6 +27,7 @@ export default async function ({ readConfigFile }) { testFiles: [ require.resolve('./search'), require.resolve('./embeddables'), + require.resolve('./bfetch_explorer'), require.resolve('./ui_actions'), require.resolve('./state_sync'), ], diff --git a/test/examples/embeddables/adding_children.ts b/test/examples/embeddables/adding_children.ts index 25fe7ee607f72..a26ce4c40e2ea 100644 --- a/test/examples/embeddables/adding_children.ts +++ b/test/examples/embeddables/adding_children.ts @@ -25,8 +25,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { const testSubjects = getService('testSubjects'); const flyout = getService('flyout'); - // FLAKY: https://github.com/elastic/kibana/issues/58692 - describe.skip('creating and adding children', () => { + describe('creating and adding children', () => { before(async () => { await testSubjects.click('embeddablePanelExamplae'); }); diff --git a/test/examples/embeddables/index.ts b/test/examples/embeddables/index.ts index 878b1b9277ba1..d0d7d4a01fbae 100644 --- a/test/examples/embeddables/index.ts +++ b/test/examples/embeddables/index.ts @@ -26,14 +26,12 @@ export default function ({ loadTestFile, }: PluginFunctionalProviderContext) { const browser = getService('browser'); - const appsMenu = getService('appsMenu'); const PageObjects = getPageObjects(['common', 'header']); describe('embeddable explorer', function () { before(async () => { await browser.setWindowSize(1300, 900); - await PageObjects.common.navigateToApp('settings'); - await appsMenu.clickLink('Embeddable explorer'); + await PageObjects.common.navigateToApp('embeddableExplorer'); }); loadTestFile(require.resolve('./hello_world_embeddable')); diff --git a/test/examples/search/index.ts b/test/examples/search/index.ts index 2fb37afd248e2..706e9659fc010 100644 --- a/test/examples/search/index.ts +++ b/test/examples/search/index.ts @@ -22,7 +22,6 @@ import { FtrProviderContext } from 'test/functional/ftr_provider_context'; // eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects, loadTestFile }: FtrProviderContext) { const browser = getService('browser'); - const appsMenu = getService('appsMenu'); const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); const PageObjects = getPageObjects(['common', 'header']); @@ -36,8 +35,7 @@ export default function ({ getService, getPageObjects, loadTestFile }: FtrProvid defaultIndex: 'logstash-*', }); await browser.setWindowSize(1300, 900); - await PageObjects.common.navigateToApp('settings'); - await appsMenu.clickLink('Search Explorer'); + await PageObjects.common.navigateToApp('searchExplorer'); }); after(async function () { diff --git a/test/examples/state_sync/index.ts b/test/examples/state_sync/index.ts index ea1c7692f64fe..297cd8f472b95 100644 --- a/test/examples/state_sync/index.ts +++ b/test/examples/state_sync/index.ts @@ -26,12 +26,10 @@ export default function ({ loadTestFile, }: PluginFunctionalProviderContext) { const browser = getService('browser'); - const PageObjects = getPageObjects(['common']); describe('state sync examples', function () { before(async () => { await browser.setWindowSize(1300, 900); - await PageObjects.common.navigateToApp('settings'); }); loadTestFile(require.resolve('./todo_app')); diff --git a/test/examples/state_sync/todo_app.ts b/test/examples/state_sync/todo_app.ts index 71b491a05ae2f..1ac5376b9ed8d 100644 --- a/test/examples/state_sync/todo_app.ts +++ b/test/examples/state_sync/todo_app.ts @@ -26,7 +26,6 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide const testSubjects = getService('testSubjects'); const find = getService('find'); const retry = getService('retry'); - const appsMenu = getService('appsMenu'); const browser = getService('browser'); const PageObjects = getPageObjects(['common']); const log = getService('log'); @@ -38,7 +37,7 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide before(async () => { base = await PageObjects.common.getHostPort(); - await appsMenu.clickLink('State containers example - browser history routing'); + await PageObjects.common.navigateToApp(appId, { insertTimestamp: false }); }); it('links are rendered correctly and state is preserved in links', async () => { @@ -119,7 +118,9 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide describe('TODO app with hash history ', async () => { before(async () => { - await appsMenu.clickLink('State containers example - hash history routing'); + await PageObjects.common.navigateToApp('stateContainersExampleHashHistory', { + insertTimestamp: false, + }); }); it('Links are rendered correctly and state is preserved in links', async () => { diff --git a/test/examples/ui_actions/index.ts b/test/examples/ui_actions/index.ts index 55137e2acc2b7..957cd0c46e1d0 100644 --- a/test/examples/ui_actions/index.ts +++ b/test/examples/ui_actions/index.ts @@ -26,14 +26,12 @@ export default function ({ loadTestFile, }: PluginFunctionalProviderContext) { const browser = getService('browser'); - const appsMenu = getService('appsMenu'); const PageObjects = getPageObjects(['common', 'header']); describe('ui actions explorer', function () { before(async () => { await browser.setWindowSize(1300, 900); - await PageObjects.common.navigateToApp('settings'); - await appsMenu.clickLink('Ui Actions Explorer'); + await PageObjects.common.navigateToApp('uiActionsExplorer'); }); loadTestFile(require.resolve('./ui_actions')); diff --git a/test/functional/apps/bundles/index.js b/test/functional/apps/bundles/index.js index 503517a98c69e..ead6412564751 100644 --- a/test/functional/apps/bundles/index.js +++ b/test/functional/apps/bundles/index.js @@ -25,7 +25,7 @@ export default function ({ getService }) { const supertest = getService('supertest'); describe('bundle compression', function () { - this.tags('ciGroup12'); + this.tags(['ciGroup12', 'skipCoverage']); let buildNum; before(async () => { diff --git a/test/functional/apps/context/_filters.js b/test/functional/apps/context/_filters.js index 470ef462b9d9d..66888d441954e 100644 --- a/test/functional/apps/context/_filters.js +++ b/test/functional/apps/context/_filters.js @@ -17,8 +17,6 @@ * under the License. */ -import expect from '@kbn/expect'; - const TEST_INDEX_PATTERN = 'logstash-*'; const TEST_ANCHOR_ID = 'AU_x3_BrGFA8no6QjjaI'; const TEST_ANCHOR_FILTER_FIELD = 'geo.src'; @@ -40,20 +38,19 @@ export default function ({ getService, getPageObjects }) { }); it('inclusive filter should be addable via expanded doc table rows', async function () { - await docTable.toggleRowExpanded({ isAnchorRow: true }); - - await retry.try(async () => { + await retry.waitFor(`filter ${TEST_ANCHOR_FILTER_FIELD} in filterbar`, async () => { + await docTable.toggleRowExpanded({ isAnchorRow: true }); const anchorDetailsRow = await docTable.getAnchorDetailsRow(); await docTable.addInclusiveFilter(anchorDetailsRow, TEST_ANCHOR_FILTER_FIELD); await PageObjects.context.waitUntilContextLoadingHasFinished(); - expect( - await filterBar.hasFilter(TEST_ANCHOR_FILTER_FIELD, TEST_ANCHOR_FILTER_VALUE, true) - ).to.be(true); + + return await filterBar.hasFilter(TEST_ANCHOR_FILTER_FIELD, TEST_ANCHOR_FILTER_VALUE, true); + }); + await retry.waitFor(`filter matching docs in docTable`, async () => { const fields = await docTable.getFields(); - const hasOnlyFilteredRows = fields + return fields .map((row) => row[2]) .every((fieldContent) => fieldContent === TEST_ANCHOR_FILTER_VALUE); - expect(hasOnlyFilteredRows).to.be(true); }); }); @@ -64,26 +61,27 @@ export default function ({ getService, getPageObjects }) { await filterBar.toggleFilterEnabled(TEST_ANCHOR_FILTER_FIELD); await PageObjects.context.waitUntilContextLoadingHasFinished(); - await retry.try(async () => { - expect( - await filterBar.hasFilter(TEST_ANCHOR_FILTER_FIELD, TEST_ANCHOR_FILTER_VALUE, false) - ).to.be(true); + await retry.waitFor(`a disabled filter in filterbar`, async () => { + return await filterBar.hasFilter(TEST_ANCHOR_FILTER_FIELD, TEST_ANCHOR_FILTER_VALUE, false); + }); + + await retry.waitFor('filters are disabled', async () => { const fields = await docTable.getFields(); const hasOnlyFilteredRows = fields .map((row) => row[2]) .every((fieldContent) => fieldContent === TEST_ANCHOR_FILTER_VALUE); - expect(hasOnlyFilteredRows).to.be(false); + return hasOnlyFilteredRows === false; }); }); it('filter for presence should be addable via expanded doc table rows', async function () { await docTable.toggleRowExpanded({ isAnchorRow: true }); - await retry.try(async () => { + await retry.waitFor('an exists filter in the filterbar', async () => { const anchorDetailsRow = await docTable.getAnchorDetailsRow(); await docTable.addExistsFilter(anchorDetailsRow, TEST_ANCHOR_FILTER_FIELD); await PageObjects.context.waitUntilContextLoadingHasFinished(); - expect(await filterBar.hasFilter(TEST_ANCHOR_FILTER_FIELD, 'exists', true)).to.be(true); + return await filterBar.hasFilter(TEST_ANCHOR_FILTER_FIELD, 'exists', true); }); }); }); diff --git a/test/functional/apps/context/_size.js b/test/functional/apps/context/_size.js index 3beb070b50deb..067a23daacb4a 100644 --- a/test/functional/apps/context/_size.js +++ b/test/functional/apps/context/_size.js @@ -16,69 +16,69 @@ * specific language governing permissions and limitations * under the License. */ - -import expect from '@kbn/expect'; - const TEST_INDEX_PATTERN = 'logstash-*'; const TEST_ANCHOR_ID = 'AU_x3_BrGFA8no6QjjaI'; -const TEST_DEFAULT_CONTEXT_SIZE = 7; -const TEST_STEP_SIZE = 3; +const TEST_DEFAULT_CONTEXT_SIZE = 2; +const TEST_STEP_SIZE = 2; export default function ({ getService, getPageObjects }) { const kibanaServer = getService('kibanaServer'); const retry = getService('retry'); const docTable = getService('docTable'); const PageObjects = getPageObjects(['context']); + let expectedRowLength = 2 * TEST_DEFAULT_CONTEXT_SIZE + 1; - // FLAKY: https://github.com/elastic/kibana/issues/53888 - describe.skip('context size', function contextSize() { + describe('context size', function contextSize() { before(async function () { await kibanaServer.uiSettings.update({ 'context:defaultSize': `${TEST_DEFAULT_CONTEXT_SIZE}`, 'context:step': `${TEST_STEP_SIZE}`, }); + await PageObjects.context.navigateTo(TEST_INDEX_PATTERN, TEST_ANCHOR_ID); }); it('should default to the `context:defaultSize` setting', async function () { - await PageObjects.context.navigateTo(TEST_INDEX_PATTERN, TEST_ANCHOR_ID); - - await retry.try(async function () { - expect(await docTable.getRowsText()).to.have.length(2 * TEST_DEFAULT_CONTEXT_SIZE + 1); - }); - await retry.try(async function () { - const predecessorCountPicker = await PageObjects.context.getPredecessorCountPicker(); - expect(await predecessorCountPicker.getAttribute('value')).to.equal( - `${TEST_DEFAULT_CONTEXT_SIZE}` - ); - }); - await retry.try(async function () { - const successorCountPicker = await PageObjects.context.getSuccessorCountPicker(); - expect(await successorCountPicker.getAttribute('value')).to.equal( - `${TEST_DEFAULT_CONTEXT_SIZE}` - ); - }); + await retry.waitFor( + `number of rows displayed initially is ${expectedRowLength}`, + async function () { + const rows = await docTable.getRowsText(); + return rows.length === expectedRowLength; + } + ); + await retry.waitFor( + `predecessor count picker is set to ${TEST_DEFAULT_CONTEXT_SIZE}`, + async function () { + const predecessorCountPicker = await PageObjects.context.getPredecessorCountPicker(); + const value = await predecessorCountPicker.getAttribute('value'); + return value === String(TEST_DEFAULT_CONTEXT_SIZE); + } + ); }); it('should increase according to the `context:step` setting when clicking the `load newer` button', async function () { - await PageObjects.context.navigateTo(TEST_INDEX_PATTERN, TEST_ANCHOR_ID); await PageObjects.context.clickPredecessorLoadMoreButton(); + expectedRowLength += TEST_STEP_SIZE; - await retry.try(async function () { - expect(await docTable.getRowsText()).to.have.length( - 2 * TEST_DEFAULT_CONTEXT_SIZE + TEST_STEP_SIZE + 1 - ); - }); + await retry.waitFor( + `number of rows displayed after clicking load more predecessors is ${expectedRowLength}`, + async function () { + const rows = await docTable.getRowsText(); + return rows.length === expectedRowLength; + } + ); }); it('should increase according to the `context:step` setting when clicking the `load older` button', async function () { - await PageObjects.context.navigateTo(TEST_INDEX_PATTERN, TEST_ANCHOR_ID); await PageObjects.context.clickSuccessorLoadMoreButton(); + expectedRowLength += TEST_STEP_SIZE; - await retry.try(async function () { - expect(await docTable.getRowsText()).to.have.length( - 2 * TEST_DEFAULT_CONTEXT_SIZE + TEST_STEP_SIZE + 1 - ); - }); + await retry.waitFor( + `number of rows displayed after clicking load more successors is ${expectedRowLength}`, + async function () { + const rows = await docTable.getRowsText(); + return rows.length === expectedRowLength; + } + ); }); }); } diff --git a/test/functional/apps/dashboard/create_and_add_embeddables.js b/test/functional/apps/dashboard/create_and_add_embeddables.js index ba715f3472b98..f5c2496a9a5aa 100644 --- a/test/functional/apps/dashboard/create_and_add_embeddables.js +++ b/test/functional/apps/dashboard/create_and_add_embeddables.js @@ -20,6 +20,7 @@ import expect from '@kbn/expect'; import { VisualizeConstants } from '../../../../src/plugins/visualize/public/application/visualize_constants'; +import { VISUALIZE_ENABLE_LABS_SETTING } from '../../../../src/plugins/visualizations/common/constants'; export default function ({ getService, getPageObjects }) { const retry = getService('retry'); @@ -102,7 +103,7 @@ export default function ({ getService, getPageObjects }) { before(async () => { await PageObjects.header.clickStackManagement(); await PageObjects.settings.clickKibanaSettings(); - await PageObjects.settings.toggleAdvancedSettingCheckbox('visualize:enableLabs'); + await PageObjects.settings.toggleAdvancedSettingCheckbox(VISUALIZE_ENABLE_LABS_SETTING); }); it('should not display lab visualizations in add panel', async () => { @@ -117,7 +118,7 @@ export default function ({ getService, getPageObjects }) { after(async () => { await PageObjects.header.clickStackManagement(); await PageObjects.settings.clickKibanaSettings(); - await PageObjects.settings.clearAdvancedSettings('visualize:enableLabs'); + await PageObjects.settings.clearAdvancedSettings(VISUALIZE_ENABLE_LABS_SETTING); await PageObjects.header.clickDashboard(); }); }); diff --git a/test/functional/apps/dashboard/dashboard_filter_bar.js b/test/functional/apps/dashboard/dashboard_filter_bar.js index 6bc34a8b998a4..c931e6763f483 100644 --- a/test/functional/apps/dashboard/dashboard_filter_bar.js +++ b/test/functional/apps/dashboard/dashboard_filter_bar.js @@ -217,6 +217,11 @@ export default function ({ getService, getPageObjects }) { const hasWarningFieldFilter = await filterBar.hasFilter('extension', 'warn', true); expect(hasWarningFieldFilter).to.be(true); }); + + it('filter without an index pattern is rendred as a warning, if the dashboard has an index pattern', async function () { + const noIndexPatternFilter = await filterBar.hasFilter('banana', 'warn', true); + expect(noIndexPatternFilter).to.be(true); + }); }); }); } diff --git a/test/functional/apps/dashboard/embed_mode.js b/test/functional/apps/dashboard/embed_mode.js index 65ef75f3f65e1..a1828143555b0 100644 --- a/test/functional/apps/dashboard/embed_mode.js +++ b/test/functional/apps/dashboard/embed_mode.js @@ -20,6 +20,7 @@ import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { + const testSubjects = getService('testSubjects'); const retry = getService('retry'); const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); @@ -28,6 +29,13 @@ export default function ({ getService, getPageObjects }) { const globalNav = getService('globalNav'); describe('embed mode', () => { + const urlParamExtensions = [ + 'show-top-menu=true', + 'show-query-input=true', + 'show-time-filter=true', + 'hide-filter-bar=true', + ]; + before(async () => { await esArchiver.load('dashboard/current/kibana'); await kibanaServer.uiSettings.replace({ @@ -54,9 +62,28 @@ export default function ({ getService, getPageObjects }) { }); }); + it('shows or hides elements based on URL params', async () => { + await testSubjects.missingOrFail('top-nav'); + await testSubjects.missingOrFail('queryInput'); + await testSubjects.missingOrFail('superDatePickerToggleQuickMenuButton'); + await testSubjects.existOrFail('showFilterActions'); + + const currentUrl = await browser.getCurrentUrl(); + const newUrl = [currentUrl].concat(urlParamExtensions).join('&'); + // Embed parameter only works on a hard refresh. + const useTimeStamp = true; + await browser.get(newUrl.toString(), useTimeStamp); + + await testSubjects.existOrFail('top-nav'); + await testSubjects.existOrFail('queryInput'); + await testSubjects.existOrFail('superDatePickerToggleQuickMenuButton'); + await testSubjects.missingOrFail('showFilterActions'); + }); + after(async function () { const currentUrl = await browser.getCurrentUrl(); - const newUrl = currentUrl.replace('&embed=true', ''); + const replaceParams = ['', 'embed=true'].concat(urlParamExtensions).join('&'); + const newUrl = currentUrl.replace(replaceParams, ''); // First use the timestamp to cause a hard refresh so the new embed parameter works correctly. let useTimeStamp = true; await browser.get(newUrl.toString(), useTimeStamp); diff --git a/test/functional/apps/discover/_discover.js b/test/functional/apps/discover/_discover.js index 9f3ce667d64b5..ecaa5aa2da97f 100644 --- a/test/functional/apps/discover/_discover.js +++ b/test/functional/apps/discover/_discover.js @@ -69,6 +69,16 @@ export default function ({ getService, getPageObjects }) { }); }); + it('renaming a saved query should modify name in breadcrumb', async function () { + const queryName2 = 'Modified Query # 1'; + await PageObjects.discover.loadSavedSearch(queryName1); + await PageObjects.discover.saveSearch(queryName2); + + await retry.try(async function () { + expect(await PageObjects.discover.getCurrentQueryName()).to.be(queryName2); + }); + }); + it('should show the correct hit count', async function () { const expectedHitCount = '14,004'; await retry.try(async function () { diff --git a/test/functional/apps/management/_import_objects.js b/test/functional/apps/management/_import_objects.js index 6b40837808387..6306d11eadb65 100644 --- a/test/functional/apps/management/_import_objects.js +++ b/test/functional/apps/management/_import_objects.js @@ -356,7 +356,6 @@ export default function ({ getService, getPageObjects }) { await PageObjects.settings.importFile( path.join(__dirname, 'exports', '_import_objects_with_index_patterns.json') ); - await PageObjects.settings.checkImportFailedWarning(); await PageObjects.settings.clickImportDone(); const objects = await PageObjects.settings.getSavedObjectsInTable(); diff --git a/test/functional/apps/visualize/_lab_mode.js b/test/functional/apps/visualize/_lab_mode.js index b356d01cdb63b..27c149b9e0e0a 100644 --- a/test/functional/apps/visualize/_lab_mode.js +++ b/test/functional/apps/visualize/_lab_mode.js @@ -18,6 +18,7 @@ */ import expect from '@kbn/expect'; +import { VISUALIZE_ENABLE_LABS_SETTING } from '../../../../src/plugins/visualizations/common/constants'; export default function ({ getService, getPageObjects }) { const log = getService('log'); @@ -37,7 +38,7 @@ export default function ({ getService, getPageObjects }) { // Navigate to advanced setting and disable lab mode await PageObjects.header.clickStackManagement(); await PageObjects.settings.clickKibanaSettings(); - await PageObjects.settings.toggleAdvancedSettingCheckbox('visualize:enableLabs'); + await PageObjects.settings.toggleAdvancedSettingCheckbox(VISUALIZE_ENABLE_LABS_SETTING); // Expect the discover still to list that saved visualization in the open list await PageObjects.header.clickDiscover(); @@ -51,7 +52,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.discover.closeLoadSaveSearchPanel(); await PageObjects.header.clickStackManagement(); await PageObjects.settings.clickKibanaSettings(); - await PageObjects.settings.clearAdvancedSettings('visualize:enableLabs'); + await PageObjects.settings.clearAdvancedSettings(VISUALIZE_ENABLE_LABS_SETTING); }); }); } diff --git a/test/functional/apps/visualize/index.ts b/test/functional/apps/visualize/index.ts index bd427577cd787..42b82486dc13f 100644 --- a/test/functional/apps/visualize/index.ts +++ b/test/functional/apps/visualize/index.ts @@ -18,6 +18,7 @@ */ import { FtrProviderContext } from '../../ftr_provider_context.d'; +import { UI_SETTINGS } from '../../../../src/plugins/data/common'; // eslint-disable-next-line @typescript-eslint/no-namespace, import/no-default-export export default function ({ getService, getPageObjects, loadTestFile }: FtrProviderContext) { @@ -37,7 +38,7 @@ export default function ({ getService, getPageObjects, loadTestFile }: FtrProvid await esArchiver.load('visualize'); await kibanaServer.uiSettings.replace({ defaultIndex: 'logstash-*', - 'format:bytes:defaultPattern': '0,0.[000]b', + [UI_SETTINGS.FORMAT_BYTES_DEFAULT_PATTERN]: '0,0.[000]b', }); isOss = await PageObjects.common.isOss(); }); diff --git a/test/functional/fixtures/es_archiver/dashboard/current/kibana/data.json.gz b/test/functional/fixtures/es_archiver/dashboard/current/kibana/data.json.gz index a052aad9450f5..ae78761fef0d3 100644 Binary files a/test/functional/fixtures/es_archiver/dashboard/current/kibana/data.json.gz and b/test/functional/fixtures/es_archiver/dashboard/current/kibana/data.json.gz differ diff --git a/test/functional/page_objects/common_page.ts b/test/functional/page_objects/common_page.ts index 91e9c020a0e7c..fe5694efc35da 100644 --- a/test/functional/page_objects/common_page.ts +++ b/test/functional/page_objects/common_page.ts @@ -67,17 +67,17 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo * @param appUrl Kibana URL */ private async loginIfPrompted(appUrl: string, insertTimestamp: boolean) { + // Disable the welcome screen. This is relevant for environments + // which don't allow to use the yml setting, e.g. cloud production. + // It is done here so it applies to logins but also to a login re-use. + await browser.setLocalStorageItem('home:welcome:show', 'false'); + let currentUrl = await browser.getCurrentUrl(); log.debug(`currentUrl = ${currentUrl}\n appUrl = ${appUrl}`); await testSubjects.find('kibanaChrome', 6 * defaultFindTimeout); // 60 sec waiting const loginPage = currentUrl.includes('/login'); const wantedLoginPage = appUrl.includes('/login') || appUrl.includes('/logout'); - // Disable the welcome screen. This is relevant for environments - // which don't allow to use the yml setting, e.g. cloud production. - // It is done here so it applies to logins but also to a login re-use. - await browser.setLocalStorageItem('home:welcome:show', 'false'); - if (loginPage && !wantedLoginPage) { log.debug('Found login page'); if (config.get('security.disableTestUser')) { diff --git a/test/plugin_functional/config.js b/test/plugin_functional/config.js index 9039f7e734a6e..74d52b842662b 100644 --- a/test/plugin_functional/config.js +++ b/test/plugin_functional/config.js @@ -37,7 +37,6 @@ export default async function ({ readConfigFile }) { require.resolve('./test_suites/embeddable_explorer'), require.resolve('./test_suites/core_plugins'), require.resolve('./test_suites/management'), - require.resolve('./test_suites/bfetch_explorer'), require.resolve('./test_suites/doc_views'), ], services: { diff --git a/test/plugin_functional/plugins/core_provider_plugin/kibana.json b/test/plugin_functional/plugins/core_provider_plugin/kibana.json index 1d5c5824d6b97..8d9b30acab893 100644 --- a/test/plugin_functional/plugins/core_provider_plugin/kibana.json +++ b/test/plugin_functional/plugins/core_provider_plugin/kibana.json @@ -2,7 +2,7 @@ "id": "core_provider_plugin", "version": "0.0.1", "kibanaVersion": "kibana", - "optionalPlugins": ["core_plugin_a", "core_plugin_b", "licensing"], + "optionalPlugins": ["core_plugin_a", "core_plugin_b", "licensing", "globalSearchTest"], "server": false, "ui": true } diff --git a/test/plugin_functional/plugins/kbn_tp_bfetch_explorer/kibana.json b/test/plugin_functional/plugins/kbn_tp_bfetch_explorer/kibana.json deleted file mode 100644 index 1acc7df871c94..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_bfetch_explorer/kibana.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "id": "kbn_tp_bfetch_explorer", - "version": "0.0.1", - "kibanaVersion": "kibana", - "configPath": ["kbn_tp_bfetch_explorer"], - "server": true, - "ui": true, - "requiredPlugins": ["bfetch"], - "optionalPlugins": [] -} diff --git a/test/plugin_functional/plugins/kbn_tp_bfetch_explorer/package.json b/test/plugin_functional/plugins/kbn_tp_bfetch_explorer/package.json deleted file mode 100644 index e396489a1ffc4..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_bfetch_explorer/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "kbn_tp_bfetch_explorer", - "version": "1.0.0", - "main": "target/examples/kbn_tp_bfetch_explorer", - "kibana": { - "version": "kibana", - "templateVersion": "1.0.0" - }, - "license": "Apache-2.0", - "scripts": { - "kbn": "node ../../scripts/kbn.js", - "build": "rm -rf './target' && tsc" - }, - "devDependencies": { - "typescript": "3.7.2" - } -} diff --git a/test/plugin_functional/plugins/kbn_tp_bfetch_explorer/public/index.ts b/test/plugin_functional/plugins/kbn_tp_bfetch_explorer/public/index.ts deleted file mode 100644 index 547dfe2aa38d2..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_bfetch_explorer/public/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export * from '../../../../../examples/bfetch_explorer/public'; diff --git a/test/plugin_functional/plugins/kbn_tp_bfetch_explorer/server/index.ts b/test/plugin_functional/plugins/kbn_tp_bfetch_explorer/server/index.ts deleted file mode 100644 index b4370eb53311e..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_bfetch_explorer/server/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export * from '../../../../../examples/bfetch_explorer/server'; diff --git a/test/plugin_functional/plugins/kbn_tp_bfetch_explorer/tsconfig.json b/test/plugin_functional/plugins/kbn_tp_bfetch_explorer/tsconfig.json deleted file mode 100644 index 994f81e396763..0000000000000 --- a/test/plugin_functional/plugins/kbn_tp_bfetch_explorer/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "compilerOptions": { - "outDir": "./target", - "skipLibCheck": true, - "types": [ - "node", - "jest", - "react" - ] - }, - "include": [ - "index.ts", - "public/**/*.ts", - "public/**/*.tsx", - "server/**/*.ts", - "server/**/*.tsx", - "../../../../typings/**/*", - ], - "exclude": [] -} diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/app/dashboard_input.ts b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/app/dashboard_input.ts index 6f4e1f052f5e0..21b12e2134767 100644 --- a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/app/dashboard_input.ts +++ b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/public/app/dashboard_input.ts @@ -92,6 +92,7 @@ export const dashboardInput: DashboardContainerInput = { }, }, }, + isEmbeddedExternally: false, isFullScreenMode: false, filters: [], useMargins: true, diff --git a/test/plugin_functional/test_suites/bfetch_explorer/index.ts b/test/plugin_functional/test_suites/bfetch_explorer/index.ts deleted file mode 100644 index a68a5090b9bed..0000000000000 --- a/test/plugin_functional/test_suites/bfetch_explorer/index.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { FtrProviderContext } from '../../../functional/ftr_provider_context'; - -export default function ({ getService, getPageObjects, loadTestFile }: FtrProviderContext) { - const browser = getService('browser'); - const appsMenu = getService('appsMenu'); - const PageObjects = getPageObjects(['common', 'header']); - - describe('bfetch explorer', function () { - before(async () => { - await browser.setWindowSize(1300, 900); - await PageObjects.common.navigateToApp('settings'); - await appsMenu.clickLink('bfetch explorer'); - }); - - loadTestFile(require.resolve('./batched_function')); - }); -} diff --git a/test/scripts/jenkins_ci_group.sh b/test/scripts/jenkins_ci_group.sh index 778142d95e4b4..60d7f0406f4c9 100755 --- a/test/scripts/jenkins_ci_group.sh +++ b/test/scripts/jenkins_ci_group.sh @@ -31,4 +31,12 @@ else mkdir -p ../kibana/target/kibana-coverage/functional mv target/kibana-coverage/functional/* ../kibana/target/kibana-coverage/functional/ fi + + echo " -> moving junit output, silently fail in case of no report" + mkdir -p ../kibana/target/junit + mv target/junit/* ../kibana/target/junit/ || echo "copying junit failed" + + echo " -> copying screenshots and html for failures" + cp -r test/functional/screenshots/* ../kibana/test/functional/screenshots/ || echo "copying screenshots failed" + cp -r test/functional/failure_debug ../kibana/test/functional/ || echo "copying html failed" fi diff --git a/test/scripts/jenkins_security_solution_cypress.sh b/test/scripts/jenkins_security_solution_cypress.sh new file mode 100644 index 0000000000000..23b83cf946d49 --- /dev/null +++ b/test/scripts/jenkins_security_solution_cypress.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +source test/scripts/jenkins_test_setup.sh + +installDir="$PARENT_DIR/install/kibana" +destDir="${installDir}-${CI_WORKER_NUMBER}" +cp -R "$installDir" "$destDir" + +export KIBANA_INSTALL_DIR="$destDir" + +echo " -> Running security solution cypress tests" +cd "$XPACK_DIR" + +checks-reporter-with-killswitch "Security solution Cypress Tests" \ + node scripts/functional_tests \ + --debug --bail \ + --kibana-install-dir "$KIBANA_INSTALL_DIR" \ + --config test/security_solution_cypress/config.ts + +echo "" +echo "" diff --git a/test/scripts/jenkins_siem_cypress.sh b/test/scripts/jenkins_siem_cypress.sh deleted file mode 100644 index c7157e97b36cc..0000000000000 --- a/test/scripts/jenkins_siem_cypress.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup.sh - -installDir="$PARENT_DIR/install/kibana" -destDir="${installDir}-${CI_WORKER_NUMBER}" -cp -R "$installDir" "$destDir" - -export KIBANA_INSTALL_DIR="$destDir" - -echo " -> Running SIEM cypress tests" -cd "$XPACK_DIR" - -checks-reporter-with-killswitch "SIEM Cypress Tests" \ - node scripts/functional_tests \ - --debug --bail \ - --kibana-install-dir "$KIBANA_INSTALL_DIR" \ - --config test/siem_cypress/config.ts - -echo "" -echo "" diff --git a/test/scripts/jenkins_xpack.sh b/test/scripts/jenkins_xpack.sh index 50a92a41e3932..067ed213c49f5 100755 --- a/test/scripts/jenkins_xpack.sh +++ b/test/scripts/jenkins_xpack.sh @@ -17,7 +17,7 @@ if [[ -z "$CODE_COVERAGE" ]] ; then echo " -> Running SIEM cyclic dependency test" cd "$XPACK_DIR" - checks-reporter-with-killswitch "X-Pack SIEM cyclic dependency test" node plugins/siem/scripts/check_circular_deps + checks-reporter-with-killswitch "X-Pack SIEM cyclic dependency test" node plugins/security_solution/scripts/check_circular_deps echo "" echo "" diff --git a/test/scripts/jenkins_xpack_ci_group.sh b/test/scripts/jenkins_xpack_ci_group.sh index a6e600630364e..648605135b359 100755 --- a/test/scripts/jenkins_xpack_ci_group.sh +++ b/test/scripts/jenkins_xpack_ci_group.sh @@ -32,4 +32,12 @@ else mkdir -p ../../kibana/target/kibana-coverage/functional mv ../target/kibana-coverage/functional/* ../../kibana/target/kibana-coverage/functional/ fi + + echo " -> moving junit output, silently fail in case of no report" + mkdir -p ../../kibana/target/junit + mv ../target/junit/* ../../kibana/target/junit/ || echo "copying junit failed" + + echo " -> copying screenshots and html for failures" + cp -r test/functional/screenshots/* ../../kibana/x-pack/test/functional/screenshots/ || echo "copying screenshots failed" + cp -r test/functional/failure_debug ../../kibana/x-pack/test/functional/ || echo "copying html failed" fi \ No newline at end of file diff --git a/test/scripts/jenkins_xpack_page_load_metrics.sh b/test/scripts/jenkins_xpack_page_load_metrics.sh new file mode 100644 index 0000000000000..679f0b8d2ddc5 --- /dev/null +++ b/test/scripts/jenkins_xpack_page_load_metrics.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +source test/scripts/jenkins_test_setup_xpack.sh + +checks-reporter-with-killswitch "Capture Kibana page load metrics" \ + node scripts/functional_tests \ + --debug --bail \ + --kibana-install-dir "$installDir" \ + --config test/page_load_metrics/config.ts; diff --git a/vars/kibanaCoverage.groovy b/vars/kibanaCoverage.groovy index 0305f86475a9a..66b16566418b5 100644 --- a/vars/kibanaCoverage.groovy +++ b/vars/kibanaCoverage.groovy @@ -98,7 +98,7 @@ def collectVcsInfo(title) { def generateReports(title) { kibanaPipeline.bash(""" - source src/dev/ci_setup/setup_env.sh + source src/dev/ci_setup/setup_env.sh true # bootstrap from x-pack folder cd x-pack yarn kbn bootstrap --prefer-offline diff --git a/x-pack/.gitignore b/x-pack/.gitignore index 5245e8a2e95c4..68262c4bf734b 100644 --- a/x-pack/.gitignore +++ b/x-pack/.gitignore @@ -3,8 +3,11 @@ /target /test/functional/failure_debug /test/functional/screenshots +/test/page_load_metrics/screenshots /test/functional/apps/reporting/reports/session /test/reporting/configs/failure_debug/ +/legacy/plugins/reporting/.chromium/ +/legacy/plugins/reporting/.phantom/ /plugins/reporting/.chromium/ /plugins/reporting/.phantom/ /.aws-config.json @@ -12,4 +15,4 @@ /.kibana-plugin-helpers.dev.* !/legacy/plugins/infra/**/target .cache -!/legacy/plugins/siem/**/target +!/legacy/plugins/security_solution/**/target diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index 48dfa341f6385..85b40d33c4089 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -2,8 +2,7 @@ "prefix": "xpack", "paths": { "xpack.actions": "plugins/actions", - "xpack.advancedUiActions": "plugins/advanced_ui_actions", - "xpack.uiActionsEnhanced": "examples/ui_actions_enhanced_examples", + "xpack.uiActionsEnhanced": ["plugins/ui_actions_enhanced", "examples/ui_actions_enhanced_examples"], "xpack.alerts": "plugins/alerts", "xpack.alertingBuiltins": "plugins/alerting_builtins", "xpack.apm": ["legacy/plugins/apm", "plugins/apm"], @@ -18,6 +17,7 @@ "xpack.endpoint": "plugins/endpoint", "xpack.features": "plugins/features", "xpack.fileUpload": "plugins/file_upload", + "xpack.globalSearch": ["plugins/global_search"], "xpack.graph": ["plugins/graph"], "xpack.grokDebugger": "plugins/grokdebugger", "xpack.idxMgmt": "plugins/index_management", @@ -38,9 +38,9 @@ "xpack.reporting": ["plugins/reporting"], "xpack.rollupJobs": ["legacy/plugins/rollup", "plugins/rollup"], "xpack.searchProfiler": "plugins/searchprofiler", - "xpack.security": ["legacy/plugins/security", "plugins/security"], + "xpack.security": "plugins/security", "xpack.server": "legacy/server", - "xpack.siem": "plugins/siem", + "xpack.securitySolution": "plugins/security_solution", "xpack.snapshotRestore": "plugins/snapshot_restore", "xpack.spaces": ["legacy/plugins/spaces", "plugins/spaces"], "xpack.taskManager": "legacy/plugins/task_manager", @@ -48,7 +48,8 @@ "xpack.triggersActionsUI": "plugins/triggers_actions_ui", "xpack.upgradeAssistant": "plugins/upgrade_assistant", "xpack.uptime": ["plugins/uptime"], - "xpack.watcher": "plugins/watcher" + "xpack.watcher": "plugins/watcher", + "xpack.observability": "plugins/observability" }, "translations": [ "plugins/translations/translations/zh-CN.json", diff --git a/x-pack/README.md b/x-pack/README.md index 744d97ca02c75..03d2e3287c0f0 100644 --- a/x-pack/README.md +++ b/x-pack/README.md @@ -25,8 +25,8 @@ Examples: - Run the jest test case whose description matches 'filtering should skip values of null': `cd x-pack && yarn test:jest -t 'filtering should skip values of null' plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container_service.test.js` - Run the x-pack api integration test case whose description matches the given string: - `node scripts/functional_tests_server --config x-pack/test/api_integration/config.js` - `node scripts/functional_test_runner --config x-pack/test/api_integration/config.js --grep='apis Monitoring Beats list with restarted beat instance should load multiple clusters'` + `node scripts/functional_tests_server --config x-pack/test/api_integration/config.ts` + `node scripts/functional_test_runner --config x-pack/test/api_integration/config.ts --grep='apis Monitoring Beats list with restarted beat instance should load multiple clusters'` In addition to to providing a regular expression argument, specific tests can also be run by appeding `.only` to an `it` or `describe` function block. E.g. `describe(` to `describe.only(`. @@ -63,7 +63,7 @@ yarn test:mocha For more info, see [the Elastic functional test development guide](https://www.elastic.co/guide/en/kibana/current/development-functional-tests.html). -The functional UI tests, the API integration tests, and the SAML API integration tests are all run against a live browser, Kibana, and Elasticsearch install. Each set of tests is specified with a unique config that describes how to start the Elasticsearch server, the Kibana server, and what tests to run against them. The sets of tests that exist today are *functional UI tests* ([specified by this config](test/functional/config.js)), *API integration tests* ([specified by this config](test/api_integration/config.js)), and *SAML API integration tests* ([specified by this config](test/saml_api_integration/config.js)). +The functional UI tests, the API integration tests, and the SAML API integration tests are all run against a live browser, Kibana, and Elasticsearch install. Each set of tests is specified with a unique config that describes how to start the Elasticsearch server, the Kibana server, and what tests to run against them. The sets of tests that exist today are *functional UI tests* ([specified by this config](test/functional/config.js)), *API integration tests* ([specified by this config](test/api_integration/config.ts)), and *SAML API integration tests* ([specified by this config](test/saml_api_integration/config.ts)). The script runs all sets of tests sequentially like so: * builds Elasticsearch and X-Pack diff --git a/x-pack/dev-tools/jest/create_jest_config.js b/x-pack/dev-tools/jest/create_jest_config.js index a222e11d28f4a..74553bbde0cd6 100644 --- a/x-pack/dev-tools/jest/create_jest_config.js +++ b/x-pack/dev-tools/jest/create_jest_config.js @@ -24,7 +24,8 @@ export function createJestConfig({ kibanaDirectory, rootDir, xPackKibanaDirector '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': fileMockPath, '\\.module.(css|scss)$': `${kibanaDirectory}/src/dev/jest/mocks/css_module_mock.js`, '\\.(css|less|scss)$': `${kibanaDirectory}/src/dev/jest/mocks/style_mock.js`, - '\\.ace\\.worker.js$': `${kibanaDirectory}/src/dev/jest/mocks/ace_worker_module_mock.js`, + '\\.ace\\.worker.js$': `${kibanaDirectory}/src/dev/jest/mocks/worker_module_mock.js`, + '\\.editor\\.worker.js$': `${kibanaDirectory}/src/dev/jest/mocks/worker_module_mock.js`, '^test_utils/enzyme_helpers': `${xPackKibanaDirectory}/test_utils/enzyme_helpers.tsx`, '^test_utils/find_test_subject': `${xPackKibanaDirectory}/test_utils/find_test_subject.ts`, '^test_utils/stub_web_worker': `${xPackKibanaDirectory}/test_utils/stub_web_worker.ts`, @@ -42,6 +43,7 @@ export function createJestConfig({ kibanaDirectory, rootDir, xPackKibanaDirector '!**/scripts/**', '!**/mocks/**', '!**/plugins/apm/e2e/**', + '!**/plugins/siem/cypress/**', ], coveragePathIgnorePatterns: ['.*\\.d\\.ts'], coverageDirectory: `${kibanaDirectory}/target/kibana-coverage/jest`, diff --git a/x-pack/examples/ui_actions_enhanced_examples/kibana.json b/x-pack/examples/ui_actions_enhanced_examples/kibana.json index e220cdd5cd297..a1cd895bb3cd6 100644 --- a/x-pack/examples/ui_actions_enhanced_examples/kibana.json +++ b/x-pack/examples/ui_actions_enhanced_examples/kibana.json @@ -5,6 +5,6 @@ "configPath": ["ui_actions_enhanced_examples"], "server": false, "ui": true, - "requiredPlugins": ["advancedUiActions", "data"], + "requiredPlugins": ["uiActionsEnhanced", "data", "discover"], "optionalPlugins": [] } diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_hello_world_drilldown/index.tsx b/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_hello_world_drilldown/index.tsx index 847035403da02..bfe853241ae1d 100644 --- a/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_hello_world_drilldown/index.tsx +++ b/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_hello_world_drilldown/index.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { EuiFormRow, EuiFieldText } from '@elastic/eui'; import { reactToUiComponent } from '../../../../../src/plugins/kibana_react/public'; -import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '../../../../plugins/advanced_ui_actions/public'; +import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '../../../../plugins/ui_actions_enhanced/public'; import { RangeSelectTriggerContext, ValueClickTriggerContext, diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_discover_drilldown/components/discover_drilldown_config/discover_drilldown_config.tsx b/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_discover_drilldown/components/discover_drilldown_config/discover_drilldown_config.tsx index 0237e128c5a2f..da9b0e921fb1c 100644 --- a/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_discover_drilldown/components/discover_drilldown_config/discover_drilldown_config.tsx +++ b/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_discover_drilldown/components/discover_drilldown_config/discover_drilldown_config.tsx @@ -31,9 +31,7 @@ export const DiscoverDrilldownConfig: React.FC = ( onIndexPatternSelect, customIndexPattern, onCustomIndexPatternToggle, - carryFiltersAndQuery, onCarryFiltersAndQueryToggle, - carryTimeRange, onCarryTimeRangeToggle, }) => { return ( @@ -82,9 +80,10 @@ export const DiscoverDrilldownConfig: React.FC = ( {!!onCarryFiltersAndQueryToggle && ( @@ -92,9 +91,10 @@ export const DiscoverDrilldownConfig: React.FC = ( {!!onCarryTimeRangeToggle && ( diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_discover_drilldown/drilldown.tsx b/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_discover_drilldown/drilldown.tsx index fef01c9640f0d..ba88f49861ffe 100644 --- a/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_discover_drilldown/drilldown.tsx +++ b/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_discover_drilldown/drilldown.tsx @@ -11,7 +11,7 @@ import { StartServicesGetter } from '../../../../../src/plugins/kibana_utils/pub import { ActionContext, Config, CollectConfigProps } from './types'; import { CollectConfigContainer } from './collect_config_container'; import { SAMPLE_DASHBOARD_TO_DISCOVER_DRILLDOWN } from './constants'; -import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '../../../../plugins/advanced_ui_actions/public'; +import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '../../../../plugins/ui_actions_enhanced/public'; import { txtGoToDiscover } from './i18n'; const isOutputWithIndexPatterns = ( @@ -22,7 +22,7 @@ const isOutputWithIndexPatterns = ( }; export interface Params { - start: StartServicesGetter>; + start: StartServicesGetter>; } export class DashboardToDiscoverDrilldown implements Drilldown { @@ -54,6 +54,10 @@ export class DashboardToDiscoverDrilldown implements Drilldown => { + const { urlGenerator } = this.params.start().plugins.discover; + + if (!urlGenerator) throw new Error('Discover URL generator not available.'); + let indexPatternId = !!config.customIndexPattern && !!config.indexPatternId ? config.indexPatternId : ''; @@ -64,8 +68,9 @@ export class DashboardToDiscoverDrilldown implements Drilldown => { diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_url_drilldown/index.tsx b/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_url_drilldown/index.tsx index 20267a8b7292b..4810fb2d6ad8d 100644 --- a/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_url_drilldown/index.tsx +++ b/x-pack/examples/ui_actions_enhanced_examples/public/dashboard_to_url_drilldown/index.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { EuiFormRow, EuiSwitch, EuiFieldText, EuiCallOut, EuiSpacer } from '@elastic/eui'; import { reactToUiComponent } from '../../../../../src/plugins/kibana_react/public'; -import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '../../../../plugins/advanced_ui_actions/public'; +import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '../../../../plugins/ui_actions_enhanced/public'; import { RangeSelectTriggerContext, ValueClickTriggerContext, diff --git a/x-pack/examples/ui_actions_enhanced_examples/public/plugin.ts b/x-pack/examples/ui_actions_enhanced_examples/public/plugin.ts index 0d4f274caf57f..8034c378cc64f 100644 --- a/x-pack/examples/ui_actions_enhanced_examples/public/plugin.ts +++ b/x-pack/examples/ui_actions_enhanced_examples/public/plugin.ts @@ -9,27 +9,30 @@ import { DataPublicPluginSetup, DataPublicPluginStart } from '../../../../src/pl import { AdvancedUiActionsSetup, AdvancedUiActionsStart, -} from '../../../../x-pack/plugins/advanced_ui_actions/public'; +} from '../../../../x-pack/plugins/ui_actions_enhanced/public'; import { DashboardHelloWorldDrilldown } from './dashboard_hello_world_drilldown'; import { DashboardToUrlDrilldown } from './dashboard_to_url_drilldown'; import { DashboardToDiscoverDrilldown } from './dashboard_to_discover_drilldown'; import { createStartServicesGetter } from '../../../../src/plugins/kibana_utils/public'; +import { DiscoverSetup, DiscoverStart } from '../../../../src/plugins/discover/public'; export interface SetupDependencies { data: DataPublicPluginSetup; - advancedUiActions: AdvancedUiActionsSetup; + discover: DiscoverSetup; + uiActionsEnhanced: AdvancedUiActionsSetup; } export interface StartDependencies { data: DataPublicPluginStart; - advancedUiActions: AdvancedUiActionsStart; + discover: DiscoverStart; + uiActionsEnhanced: AdvancedUiActionsStart; } export class UiActionsEnhancedExamplesPlugin implements Plugin { public setup( core: CoreSetup, - { advancedUiActions: uiActions }: SetupDependencies + { uiActionsEnhanced: uiActions }: SetupDependencies ) { const start = createStartServicesGetter(core.getStartServices); diff --git a/x-pack/legacy/plugins/beats_management/readme.md b/x-pack/legacy/plugins/beats_management/readme.md index 301caad683dd5..3414f09deed46 100644 --- a/x-pack/legacy/plugins/beats_management/readme.md +++ b/x-pack/legacy/plugins/beats_management/readme.md @@ -15,7 +15,7 @@ In one shell, from **~/kibana/x-pack**: `node scripts/functional_tests-server.js` In another shell, from **~kibana/x-pack**: -`node ../scripts/functional_test_runner.js --config test/api_integration/config.js`. +`node ../scripts/functional_test_runner.js --config test/api_integration/config.ts`. ### Manual e2e testing diff --git a/x-pack/legacy/plugins/beats_management/server/lib/adapters/framework/adapter_types.ts b/x-pack/legacy/plugins/beats_management/server/lib/adapters/framework/adapter_types.ts index bb1f68e1c03b3..80599f38d982a 100644 --- a/x-pack/legacy/plugins/beats_management/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/legacy/plugins/beats_management/server/lib/adapters/framework/adapter_types.ts @@ -8,6 +8,7 @@ import { Lifecycle, ResponseToolkit } from 'hapi'; import * as t from 'io-ts'; +import { SecurityPluginSetup } from '../../../../../../../plugins/security/server'; import { LicenseType } from '../../../../common/constants/security'; export const internalAuthData = Symbol('internalAuthData'); @@ -39,6 +40,11 @@ export interface BackendFrameworkAdapter { } export interface KibanaLegacyServer { + newPlatform: { + setup: { + plugins: { security: SecurityPluginSetup }; + }; + }; plugins: { xpack_main: { status: { @@ -53,9 +59,6 @@ export interface KibanaLegacyServer { }; }; }; - security: { - getUser: (request: KibanaServerRequest) => any; - }; elasticsearch: { status: { on: (status: 'green' | 'yellow' | 'red', callback: () => void) => void; diff --git a/x-pack/legacy/plugins/beats_management/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/legacy/plugins/beats_management/server/lib/adapters/framework/kibana_framework_adapter.ts index 589f34ac74601..1bf9bbb22b352 100644 --- a/x-pack/legacy/plugins/beats_management/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/legacy/plugins/beats_management/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -8,6 +8,7 @@ import { ResponseToolkit } from 'hapi'; import { PathReporter } from 'io-ts/lib/PathReporter'; import { get } from 'lodash'; import { isLeft } from 'fp-ts/lib/Either'; +import { KibanaRequest, LegacyRequest } from '../../../../../../../../src/core/server'; // @ts-ignore import { mirrorPluginStatus } from '../../../../../../server/lib/mirror_plugin_status'; import { @@ -128,13 +129,10 @@ export class KibanaBackendFrameworkAdapter implements BackendFrameworkAdapter { } private async getUser(request: KibanaServerRequest): Promise { - let user; - try { - user = await this.server.plugins.security.getUser(request); - } catch (e) { - return null; - } - if (user === null) { + const user = this.server.newPlatform.setup.plugins.security?.authc.getCurrentUser( + KibanaRequest.from((request as unknown) as LegacyRequest) + ); + if (!user) { return null; } const assertKibanaUser = RuntimeKibanaUser.decode(user); diff --git a/x-pack/legacy/plugins/security/index.ts b/x-pack/legacy/plugins/security/index.ts index 41371fcbc4c65..addeef34f63bf 100644 --- a/x-pack/legacy/plugins/security/index.ts +++ b/x-pack/legacy/plugins/security/index.ts @@ -6,64 +6,17 @@ import { Root } from 'joi'; import { resolve } from 'path'; -import { Server } from 'src/legacy/server/kbn_server'; -import { KibanaRequest, LegacyRequest } from '../../../../src/core/server'; -// @ts-ignore -import { watchStatusAndLicenseToInitialize } from '../../server/lib/watch_status_and_license_to_initialize'; -import { AuthenticatedUser, SecurityPluginSetup } from '../../../plugins/security/server'; - -/** - * Public interface of the security plugin. - */ -export interface SecurityPlugin { - getUser: (request: LegacyRequest) => Promise; -} - -function getSecurityPluginSetup(server: Server) { - const securityPlugin = server.newPlatform.setup.plugins.security as SecurityPluginSetup; - if (!securityPlugin) { - throw new Error('Kibana Platform Security plugin is not available.'); - } - - return securityPlugin; -} export const security = (kibana: Record) => new kibana.Plugin({ id: 'security', publicDir: resolve(__dirname, 'public'), - require: ['kibana', 'xpack_main'], + require: ['kibana'], configPrefix: 'xpack.security', - uiExports: { - hacks: ['plugins/security/hacks/legacy'], - injectDefaultVars: (server: Server) => { - return { enableSpaceAwarePrivileges: server.config().get('xpack.spaces.enabled') }; - }, - }, - - config(Joi: Root) { - return Joi.object({ - enabled: Joi.boolean().default(true), - }) + uiExports: { hacks: ['plugins/security/hacks/legacy'] }, + config: (Joi: Root) => + Joi.object({ enabled: Joi.boolean().default(true) }) .unknown() - .default(); - }, - - async postInit(server: Server) { - watchStatusAndLicenseToInitialize(server.plugins.xpack_main, this, async () => { - const xpackInfo = server.plugins.xpack_main.info; - if (xpackInfo.isAvailable() && xpackInfo.feature('security').isEnabled()) { - await getSecurityPluginSetup(server).__legacyCompat.registerPrivilegesWithCluster(); - } - }); - }, - - async init(server: Server) { - const securityPlugin = getSecurityPluginSetup(server); - - server.expose({ - getUser: async (request: LegacyRequest) => - securityPlugin.authc.getCurrentUser(KibanaRequest.from(request)), - }); - }, + .default(), + init() {}, }); diff --git a/x-pack/package.json b/x-pack/package.json index c46d364e0ac46..b3dcde2194d3f 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -134,7 +134,7 @@ "enzyme-adapter-react-16": "^1.15.2", "enzyme-adapter-utils": "^1.13.0", "enzyme-to-json": "^3.4.4", - "execa": "^4.0.0", + "execa": "^4.0.2", "fancy-log": "^1.3.2", "fetch-mock": "^7.3.9", "graphql-code-generator": "^0.18.2", @@ -299,7 +299,7 @@ "oppsy": "^2.0.0", "p-retry": "^4.2.0", "papaparse": "^5.2.0", - "pdfmake": "^0.1.63", + "pdfmake": "^0.1.65", "pluralize": "3.1.0", "pngjs": "3.4.0", "polished": "^1.9.2", diff --git a/x-pack/plugins/actions/server/builtin_action_types/case/types.ts b/x-pack/plugins/actions/server/builtin_action_types/case/types.ts index 459e9d2b03f92..992b2cb16fb06 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/case/types.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/case/types.ts @@ -21,6 +21,7 @@ import { ExecutorSubActionGetIncidentParamsSchema, ExecutorSubActionHandshakeParamsSchema, } from './schema'; +import { LicenseType } from '../../../../../legacy/common/constants'; export interface AnyParams { [index: string]: string | number | object | undefined | null; @@ -51,6 +52,7 @@ export type Comment = TypeOf; export interface ExternalServiceConfiguration { id: string; name: string; + minimumLicenseRequired: LicenseType; } export interface ExternalServiceCredentials { diff --git a/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts b/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts index 315d13b5aa773..dd8d971b7df44 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts @@ -120,9 +120,7 @@ export const createConnector = ({ configurationUtilities, executor = createConnectorExecutor({ api, createExternalService }), }: CreateActionTypeArgs): ActionType => ({ - id: config.id, - name: config.name, - minimumLicenseRequired: 'platinum', + ...config, validate: { config: schema.object(validationSchema.config, { validate: curry(validate.config)(configurationUtilities), diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/config.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/config.ts index 7e415109f1bd9..54f28e447010a 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/config.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/config.ts @@ -10,4 +10,5 @@ import * as i18n from './translations'; export const config: ExternalServiceConfiguration = { id: '.jira', name: i18n.NAME, + minimumLicenseRequired: 'gold', }; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts index 4ad8108c3b137..70d53ab79f631 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts @@ -10,4 +10,5 @@ import * as i18n from './translations'; export const config: ExternalServiceConfiguration = { id: '.servicenow', name: i18n.NAME, + minimumLicenseRequired: 'platinum', }; diff --git a/x-pack/plugins/advanced_ui_actions/kibana.json b/x-pack/plugins/advanced_ui_actions/kibana.json deleted file mode 100644 index 45907e2d8b602..0000000000000 --- a/x-pack/plugins/advanced_ui_actions/kibana.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "id": "advancedUiActions", - "version": "kibana", - "configPath": ["xpack", "advanced_ui_actions"], - "requiredPlugins": [ - "embeddable", - "uiActions" - ], - "server": false, - "ui": true -} diff --git a/x-pack/plugins/advanced_ui_actions/public/index.ts b/x-pack/plugins/advanced_ui_actions/public/index.ts deleted file mode 100644 index 024cfe5530b97..0000000000000 --- a/x-pack/plugins/advanced_ui_actions/public/index.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { PluginInitializerContext } from '../../../../src/core/public'; -import { AdvancedUiActionsPublicPlugin } from './plugin'; - -export function plugin(initializerContext: PluginInitializerContext) { - return new AdvancedUiActionsPublicPlugin(initializerContext); -} - -export { AdvancedUiActionsPublicPlugin as Plugin }; -export { - SetupContract as AdvancedUiActionsSetup, - StartContract as AdvancedUiActionsStart, -} from './plugin'; - -export { ActionWizard } from './components'; -export { - ActionFactoryDefinition as AdvancedUiActionsActionFactoryDefinition, - ActionFactory as AdvancedUiActionsActionFactory, - SerializedAction as UiActionsEnhancedSerializedAction, - SerializedEvent as UiActionsEnhancedSerializedEvent, - AbstractActionStorage as UiActionsEnhancedAbstractActionStorage, - DynamicActionManager as UiActionsEnhancedDynamicActionManager, - DynamicActionManagerParams as UiActionsEnhancedDynamicActionManagerParams, - DynamicActionManagerState as UiActionsEnhancedDynamicActionManagerState, - MemoryActionStorage as UiActionsEnhancedMemoryActionStorage, -} from './dynamic_actions'; - -export { DrilldownDefinition as UiActionsEnhancedDrilldownDefinition } from './drilldowns'; diff --git a/x-pack/plugins/advanced_ui_actions/public/plugin.ts b/x-pack/plugins/advanced_ui_actions/public/plugin.ts deleted file mode 100644 index f042130158aec..0000000000000 --- a/x-pack/plugins/advanced_ui_actions/public/plugin.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { - PluginInitializerContext, - CoreSetup, - CoreStart, - Plugin, -} from '../../../../src/core/public'; -import { createReactOverlays } from '../../../../src/plugins/kibana_react/public'; -import { UiActionsSetup, UiActionsStart } from '../../../../src/plugins/ui_actions/public'; -import { - CONTEXT_MENU_TRIGGER, - PANEL_BADGE_TRIGGER, - EmbeddableSetup, - EmbeddableStart, -} from '../../../../src/plugins/embeddable/public'; -import { - CustomTimeRangeAction, - CUSTOM_TIME_RANGE, - TimeRangeActionContext, -} from './custom_time_range_action'; - -import { - CustomTimeRangeBadge, - CUSTOM_TIME_RANGE_BADGE, - TimeBadgeActionContext, -} from './custom_time_range_badge'; -import { CommonlyUsedRange } from './types'; -import { UiActionsServiceEnhancements } from './services'; - -interface SetupDependencies { - embeddable: EmbeddableSetup; // Embeddable are needed because they register basic triggers/actions. - uiActions: UiActionsSetup; -} - -interface StartDependencies { - embeddable: EmbeddableStart; - uiActions: UiActionsStart; -} - -export interface SetupContract - extends UiActionsSetup, - Pick {} - -export interface StartContract - extends UiActionsStart, - Pick {} - -declare module '../../../../src/plugins/ui_actions/public' { - export interface ActionContextMapping { - [CUSTOM_TIME_RANGE]: TimeRangeActionContext; - [CUSTOM_TIME_RANGE_BADGE]: TimeBadgeActionContext; - } -} - -export class AdvancedUiActionsPublicPlugin - implements Plugin { - private readonly enhancements = new UiActionsServiceEnhancements(); - - constructor(initializerContext: PluginInitializerContext) {} - - public setup(core: CoreSetup, { uiActions }: SetupDependencies): SetupContract { - return { - ...uiActions, - ...this.enhancements, - }; - } - - public start(core: CoreStart, { uiActions }: StartDependencies): StartContract { - const dateFormat = core.uiSettings.get('dateFormat') as string; - const commonlyUsedRanges = core.uiSettings.get('timepicker:quickRanges') as CommonlyUsedRange[]; - const { openModal } = createReactOverlays(core); - const timeRangeAction = new CustomTimeRangeAction({ - openModal, - dateFormat, - commonlyUsedRanges, - }); - uiActions.addTriggerAction(CONTEXT_MENU_TRIGGER, timeRangeAction); - - const timeRangeBadge = new CustomTimeRangeBadge({ - openModal, - dateFormat, - commonlyUsedRanges, - }); - uiActions.addTriggerAction(PANEL_BADGE_TRIGGER, timeRangeBadge); - - return { - ...uiActions, - ...this.enhancements, - }; - } - - public stop() {} -} diff --git a/x-pack/plugins/advanced_ui_actions/scripts/storybook.js b/x-pack/plugins/advanced_ui_actions/scripts/storybook.js deleted file mode 100644 index 3da0a3b37bfaf..0000000000000 --- a/x-pack/plugins/advanced_ui_actions/scripts/storybook.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { join } from 'path'; - -// eslint-disable-next-line -require('@kbn/storybook').runStorybookCli({ - name: 'advanced_ui_actions', - storyGlobs: [join(__dirname, '..', 'public', 'components', '**', '*.story.tsx')], -}); diff --git a/x-pack/plugins/apm/public/application/index.tsx b/x-pack/plugins/apm/public/application/index.tsx index cb8600ed2c214..56c427e67ad4c 100644 --- a/x-pack/plugins/apm/public/application/index.tsx +++ b/x-pack/plugins/apm/public/application/index.tsx @@ -9,6 +9,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { Route, Router, Switch } from 'react-router-dom'; import styled from 'styled-components'; +import { EuiThemeProvider } from '../../../observability/public'; import { CoreStart, AppMountParameters } from '../../../../../src/core/public'; import { ApmPluginSetupDeps } from '../plugin'; import { ApmPluginContext } from '../context/ApmPluginContext'; @@ -18,7 +19,10 @@ import { LocationProvider } from '../context/LocationContext'; import { MatchedRouteProvider } from '../context/MatchedRouteContext'; import { UrlParamsProvider } from '../context/UrlParamsContext'; import { AlertsContextProvider } from '../../../triggers_actions_ui/public'; -import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public'; +import { + KibanaContextProvider, + useUiSetting$, +} from '../../../../../src/plugins/kibana_react/public'; import { px, unit, units } from '../style/variables'; import { UpdateBreadcrumbs } from '../components/app/Main/UpdateBreadcrumbs'; import { APMIndicesPermission } from '../components/app/APMIndicesPermission'; @@ -35,18 +39,22 @@ const MainContainer = styled.div` `; const App = () => { + const [darkMode] = useUiSetting$('theme:darkMode'); + return ( - - - - - - {routes.map((route, i) => ( - - ))} - - - + + + + + + + {routes.map((route, i) => ( + + ))} + + + + ); }; diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/index.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/index.tsx index ed683b8ecd11d..1096c0c77db30 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/index.tsx @@ -103,7 +103,7 @@ const ErrorGroupList: React.FC = (props) => { }), field: 'type', sortable: false, - render: (type: string, item: ErrorGroupListAPIResponse[0]) => { + render: (type: string) => { return ( (obj: T): T { return Object.fromEntries( - Object.entries(obj).filter(([k, v]) => v != null && v !== '') + Object.entries(obj).filter(([_, v]) => v != null && v !== '') ); } diff --git a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/index.tsx index 5bb678d1c08af..50eb85715969a 100644 --- a/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Settings/AgentConfigurations/AgentConfigurationCreateEdit/index.tsx @@ -79,6 +79,7 @@ export function AgentConfigurationCreateEdit({ ..._newConfig, settings: existingConfig?.settings || {}, })); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [existingConfig]); // update newConfig when existingConfig has loaded diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx index d39ad530c1b4c..1244dd01a3b43 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx @@ -109,10 +109,12 @@ export const TransactionDistribution: FunctionComponent = ( bucketIndex, } = props; + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const formatYShort = useCallback(getFormatYShort(transactionType), [ transactionType, ]); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const formatYLong = useCallback(getFormatYLong(transactionType), [ transactionType, ]); diff --git a/x-pack/plugins/apm/public/components/shared/ErrorRateAlertTrigger/index.stories.tsx b/x-pack/plugins/apm/public/components/shared/ErrorRateAlertTrigger/index.stories.tsx index ddfca94e567d9..8f7ed54f91bd0 100644 --- a/x-pack/plugins/apm/public/components/shared/ErrorRateAlertTrigger/index.stories.tsx +++ b/x-pack/plugins/apm/public/components/shared/ErrorRateAlertTrigger/index.stories.tsx @@ -8,7 +8,7 @@ import { storiesOf } from '@storybook/react'; import React from 'react'; import { ErrorRateAlertTrigger } from '.'; -storiesOf('app/ErrorRateAlertTrigger', module).add('example', (props) => { +storiesOf('app/ErrorRateAlertTrigger', module).add('example', () => { const params = { threshold: 2, window: '5m', diff --git a/x-pack/plugins/apm/public/components/shared/StickyProperties/index.tsx b/x-pack/plugins/apm/public/components/shared/StickyProperties/index.tsx index 74c75e4585c3e..8bfea721c854d 100644 --- a/x-pack/plugins/apm/public/components/shared/StickyProperties/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/StickyProperties/index.tsx @@ -69,7 +69,6 @@ function getPropertyLabel({ fieldName, label }: Partial) { function getPropertyValue({ val, - fieldName, truncated = false, }: Partial) { if (truncated) { diff --git a/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/TransactionActionMenu.tsx b/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/TransactionActionMenu.tsx index 988edb197a230..2507eca9ff663 100644 --- a/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/TransactionActionMenu.tsx +++ b/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/TransactionActionMenu.tsx @@ -66,6 +66,7 @@ export const TransactionActionMenu: FunctionComponent = ({ { key: 'transaction.name', value: transaction?.transaction.name }, { key: 'transaction.type', value: transaction?.transaction.type }, ].filter((filter): filter is Filter => typeof filter.value === 'string'), + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [transaction] ); diff --git a/x-pack/plugins/apm/public/components/shared/TransactionDurationAlertTrigger/index.stories.tsx b/x-pack/plugins/apm/public/components/shared/TransactionDurationAlertTrigger/index.stories.tsx index 7b22218bf23df..e2429d1225442 100644 --- a/x-pack/plugins/apm/public/components/shared/TransactionDurationAlertTrigger/index.stories.tsx +++ b/x-pack/plugins/apm/public/components/shared/TransactionDurationAlertTrigger/index.stories.tsx @@ -14,37 +14,34 @@ import { import { MockUrlParamsContextProvider } from '../../../context/UrlParamsContext/MockUrlParamsContextProvider'; import { ApmPluginContextValue } from '../../../context/ApmPluginContext'; -storiesOf('app/TransactionDurationAlertTrigger', module).add( - 'example', - (context) => { - const params = { - threshold: 1500, - aggregationType: 'avg' as const, - window: '5m', - }; +storiesOf('app/TransactionDurationAlertTrigger', module).add('example', () => { + const params = { + threshold: 1500, + aggregationType: 'avg' as const, + window: '5m', + }; - const contextMock = (merge(cloneDeep(mockApmPluginContextValue), { - core: { - http: { - get: () => { - return Promise.resolve({ transactionTypes: ['request'] }); - }, + const contextMock = (merge(cloneDeep(mockApmPluginContextValue), { + core: { + http: { + get: () => { + return Promise.resolve({ transactionTypes: ['request'] }); }, }, - }) as unknown) as ApmPluginContextValue; + }, + }) as unknown) as ApmPluginContextValue; - return ( -
- - - undefined} - setAlertProperty={() => undefined} - /> - - -
- ); - } -); + return ( +
+ + + undefined} + setAlertProperty={() => undefined} + /> + + +
+ ); +}); diff --git a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/ChoroplethMap/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/ChoroplethMap/index.tsx index 937c18807f80f..ebd6061831f4e 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/ChoroplethMap/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/ChoroplethMap/index.tsx @@ -137,7 +137,7 @@ export const ChoroplethMap: React.FC = (props) => { }, [map, items, tooltipState]); const updateTooltipStateOnMousemoveRef = useRef( - (event: mapboxgl.MapMouseEvent & mapboxgl.EventData) => {} + (_event: mapboxgl.MapMouseEvent & mapboxgl.EventData) => {} ); // initialization side effect, only runs once diff --git a/x-pack/plugins/apm/public/context/LoadingIndicatorContext.tsx b/x-pack/plugins/apm/public/context/LoadingIndicatorContext.tsx index 32e52f8e396b5..a26653d3d5294 100644 --- a/x-pack/plugins/apm/public/context/LoadingIndicatorContext.tsx +++ b/x-pack/plugins/apm/public/context/LoadingIndicatorContext.tsx @@ -10,7 +10,7 @@ import { useDelayedVisibility } from '../components/shared/useDelayedVisibility' export const LoadingIndicatorContext = React.createContext({ statuses: {}, - dispatchStatus: (action: Action) => {}, + dispatchStatus: (_action: Action) => {}, }); interface State { diff --git a/x-pack/plugins/apm/public/context/UrlParamsContext/index.tsx b/x-pack/plugins/apm/public/context/UrlParamsContext/index.tsx index bc8cabb6f6641..6083a216bbf95 100644 --- a/x-pack/plugins/apm/public/context/UrlParamsContext/index.tsx +++ b/x-pack/plugins/apm/public/context/UrlParamsContext/index.tsx @@ -40,7 +40,7 @@ function useUiFilters(params: IUrlParams): UIFilters { return useDeepObjectIdentity({ kuery, environment, ...localUiFilters }); } -const defaultRefresh = (time: TimeRange) => {}; +const defaultRefresh = (_time: TimeRange) => {}; const UrlParamsContext = createContext({ urlParams: {} as IUrlParams, diff --git a/x-pack/plugins/apm/public/hooks/useFetcher.test.tsx b/x-pack/plugins/apm/public/hooks/useFetcher.test.tsx index 28b836cd2c650..2db4659c83603 100644 --- a/x-pack/plugins/apm/public/hooks/useFetcher.test.tsx +++ b/x-pack/plugins/apm/public/hooks/useFetcher.test.tsx @@ -106,6 +106,7 @@ describe('useFetcher', () => { jest.useFakeTimers(); const hook = renderHook( + /* eslint-disable-next-line react-hooks/exhaustive-deps */ ({ callback, args }) => useFetcher(callback, args), { initialProps: { @@ -165,6 +166,7 @@ describe('useFetcher', () => { it('should return the same object reference when data is unchanged between rerenders', async () => { const hook = renderHook( + /* eslint-disable-next-line react-hooks/exhaustive-deps */ ({ callback, args }) => useFetcher(callback, args), { initialProps: { diff --git a/x-pack/plugins/apm/public/plugin.ts b/x-pack/plugins/apm/public/plugin.ts index 76320efe617ea..0939c51b16605 100644 --- a/x-pack/plugins/apm/public/plugin.ts +++ b/x-pack/plugins/apm/public/plugin.ts @@ -75,7 +75,7 @@ export class ApmPlugin implements Plugin { core.application.register({ id: 'apm', title: 'APM', - order: 8100, + order: 8300, euiIconType: 'apmApp', appRoute: '/app/apm', icon: 'plugins/apm/public/icon.svg', diff --git a/x-pack/plugins/apm/public/services/rest/ml.ts b/x-pack/plugins/apm/public/services/rest/ml.ts index 7d1f386fa896c..99c162bde02da 100644 --- a/x-pack/plugins/apm/public/services/rest/ml.ts +++ b/x-pack/plugins/apm/public/services/rest/ml.ts @@ -36,7 +36,7 @@ interface StartedMLJobApiResponse { jobs: MlResponseItem[]; } -async function getTransactionIndices(http: HttpSetup) { +async function getTransactionIndices() { const indices = await callApmApi({ method: 'GET', pathname: `/api/apm/settings/apm-indices`, @@ -53,7 +53,7 @@ export async function startMLJob({ transactionType: string; http: HttpSetup; }) { - const transactionIndices = await getTransactionIndices(http); + const transactionIndices = await getTransactionIndices(); const groups = [ 'apm', encodeForMlApi(serviceName), diff --git a/x-pack/plugins/apm/public/services/rest/watcher.ts b/x-pack/plugins/apm/public/services/rest/watcher.ts index 3027164e2863e..246ed061eb20e 100644 --- a/x-pack/plugins/apm/public/services/rest/watcher.ts +++ b/x-pack/plugins/apm/public/services/rest/watcher.ts @@ -19,6 +19,6 @@ export async function createWatch({ return callApi(http, { method: 'PUT', pathname: `/api/watcher/watch/${id}`, - body: { type: 'json', id, watch }, + body: { type: 'json', id, watch, isNew: true, isActive: true }, }); } diff --git a/x-pack/plugins/apm/readme.md b/x-pack/plugins/apm/readme.md index ceed5e6c39716..cb694712d7c97 100644 --- a/x-pack/plugins/apm/readme.md +++ b/x-pack/plugins/apm/readme.md @@ -83,13 +83,13 @@ For debugging access Elasticsearch on http://localhost:9220` (elastic/changeme) **Start server** ``` -node scripts/functional_tests_server --config x-pack/test/api_integration/config.js +node scripts/functional_tests_server --config x-pack/test/api_integration/config.ts ``` **Run tests** ``` -node scripts/functional_test_runner --config x-pack/test/api_integration/config.js --grep='APM specs' +node scripts/functional_test_runner --config x-pack/test/api_integration/config.ts --grep='APM specs' ``` APM tests are located in `x-pack/test/api_integration/apis/apm`. diff --git a/x-pack/plugins/apm/scripts/optimize-tsconfig/tsconfig.json b/x-pack/plugins/apm/scripts/optimize-tsconfig/tsconfig.json index 34b67c834554d..5a810fa90259a 100644 --- a/x-pack/plugins/apm/scripts/optimize-tsconfig/tsconfig.json +++ b/x-pack/plugins/apm/scripts/optimize-tsconfig/tsconfig.json @@ -4,8 +4,8 @@ "./plugins/observability/**/*", "./typings/**/*" ], - "exclude": [ - "**/__fixtures__/**/*", - "./plugins/apm/e2e/cypress/**/*" - ] + "exclude": ["**/__fixtures__/**/*", "./plugins/apm/e2e/cypress/**/*"], + "compilerOptions": { + "noErrorTruncation": true + } } diff --git a/x-pack/plugins/apm/scripts/upload-telemetry-data/generate-sample-documents.ts b/x-pack/plugins/apm/scripts/upload-telemetry-data/generate-sample-documents.ts index e9f1e99f1fc39..50de0d5b234d4 100644 --- a/x-pack/plugins/apm/scripts/upload-telemetry-data/generate-sample-documents.ts +++ b/x-pack/plugins/apm/scripts/upload-telemetry-data/generate-sample-documents.ts @@ -78,7 +78,7 @@ export async function generateSampleDocuments( const dateOfScriptExecution = new Date(); return flatten( - range(0, opts.instances).map((instanceNo) => { + range(0, opts.instances).map(() => { const instanceId = uuid.v4(); const defaults = { cluster_uuid: instanceId, diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts index df82d44fb5041..632e653a2f6e9 100644 --- a/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts +++ b/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts @@ -120,7 +120,7 @@ export async function createApmTelemetry({ usageCollector.registerCollector(collector); - core.getStartServices().then(([coreStart, pluginsStart]) => { + core.getStartServices().then(([_coreStart, pluginsStart]) => { const { taskManager: taskManagerStart } = pluginsStart as { taskManager: TaskManagerStartContract; }; diff --git a/x-pack/plugins/apm/server/lib/helpers/es_client.ts b/x-pack/plugins/apm/server/lib/helpers/es_client.ts index c7a17197ca778..892f8f0ddd105 100644 --- a/x-pack/plugins/apm/server/lib/helpers/es_client.ts +++ b/x-pack/plugins/apm/server/lib/helpers/es_client.ts @@ -19,6 +19,7 @@ import { ESSearchRequest, ESSearchResponse, } from '../../../typings/elasticsearch'; +import { UI_SETTINGS } from '../../../../../../src/plugins/data/server'; import { OBSERVER_VERSION_MAJOR } from '../../../common/elasticsearch_fieldnames'; import { pickKeys } from '../../../common/utils/pick_keys'; import { APMRequestHandlerContext } from '../../routes/typings'; @@ -95,7 +96,7 @@ async function getParamsForSearchRequest( savedObjectsClient: context.core.savedObjects.client, config: context.config, }), - uiSettings.client.get('search:includeFrozen'), + uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN), ]); // Get indices for legacy data filter (only those which apply) diff --git a/x-pack/plugins/apm/server/lib/service_map/get_service_map_from_trace_ids.ts b/x-pack/plugins/apm/server/lib/service_map/get_service_map_from_trace_ids.ts index e34479e92a06c..01cbc1aa9b989 100644 --- a/x-pack/plugins/apm/server/lib/service_map/get_service_map_from_trace_ids.ts +++ b/x-pack/plugins/apm/server/lib/service_map/get_service_map_from_trace_ids.ts @@ -270,7 +270,7 @@ export async function getServiceMapFromTraceIds({ return conns; }, [] as Connection[]); }, [] as Connection[]), - (value, index, array) => { + (value, _index, array) => { return find(array, value); } ); diff --git a/x-pack/plugins/apm/server/lib/services/annotations/index.ts b/x-pack/plugins/apm/server/lib/services/annotations/index.ts index 4d3efc478a4fd..9365213a87f6e 100644 --- a/x-pack/plugins/apm/server/lib/services/annotations/index.ts +++ b/x-pack/plugins/apm/server/lib/services/annotations/index.ts @@ -41,7 +41,7 @@ export async function getServiceAnnotations({ : []; if (storedAnnotations.length) { - derivedAnnotationsPromise.catch((error) => { + derivedAnnotationsPromise.catch(() => { // handle error silently to prevent Kibana from crashing }); return { annotations: storedAnnotations }; diff --git a/x-pack/plugins/apm/server/lib/settings/apm_indices/save_apm_indices.ts b/x-pack/plugins/apm/server/lib/settings/apm_indices/save_apm_indices.ts index 9601bdd51824d..d4ef6e2f91051 100644 --- a/x-pack/plugins/apm/server/lib/settings/apm_indices/save_apm_indices.ts +++ b/x-pack/plugins/apm/server/lib/settings/apm_indices/save_apm_indices.ts @@ -28,6 +28,6 @@ export async function saveApmIndices( function removeEmpty(apmIndices: Partial) { return Object.entries(apmIndices) .map(([key, value]) => [key, value?.trim()]) - .filter(([key, value]) => !!value) + .filter(([_, value]) => !!value) .reduce((obj, [key, value]) => ({ ...obj, [key as string]: value }), {}); } diff --git a/x-pack/plugins/apm/server/routes/errors.ts b/x-pack/plugins/apm/server/routes/errors.ts index 7e45f412d4bdb..1615550027d3c 100644 --- a/x-pack/plugins/apm/server/routes/errors.ts +++ b/x-pack/plugins/apm/server/routes/errors.ts @@ -12,7 +12,7 @@ import { getErrorGroups } from '../lib/errors/get_error_groups'; import { setupRequest } from '../lib/helpers/setup_request'; import { uiFiltersRt, rangeRt } from './default_api_types'; -export const errorsRoute = createRoute((core) => ({ +export const errorsRoute = createRoute(() => ({ path: '/api/apm/services/{serviceName}/errors', params: { path: t.type({ diff --git a/x-pack/plugins/apm/server/routes/service_nodes.ts b/x-pack/plugins/apm/server/routes/service_nodes.ts index a6e9175fcb651..8721407671825 100644 --- a/x-pack/plugins/apm/server/routes/service_nodes.ts +++ b/x-pack/plugins/apm/server/routes/service_nodes.ts @@ -9,7 +9,7 @@ import { setupRequest } from '../lib/helpers/setup_request'; import { getServiceNodes } from '../lib/service_nodes'; import { rangeRt, uiFiltersRt } from './default_api_types'; -export const serviceNodesRoute = createRoute((core) => ({ +export const serviceNodesRoute = createRoute(() => ({ path: '/api/apm/services/{serviceName}/serviceNodes', params: { path: t.type({ diff --git a/x-pack/plugins/apm/server/routes/services.ts b/x-pack/plugins/apm/server/routes/services.ts index 996bfbd9184d1..8672c6c108c4c 100644 --- a/x-pack/plugins/apm/server/routes/services.ts +++ b/x-pack/plugins/apm/server/routes/services.ts @@ -17,7 +17,7 @@ import { uiFiltersRt, rangeRt } from './default_api_types'; import { getServiceAnnotations } from '../lib/services/annotations'; import { dateAsStringRt } from '../../common/runtime_types/date_as_string_rt'; -export const servicesRoute = createRoute((core) => ({ +export const servicesRoute = createRoute(() => ({ path: '/api/apm/services', params: { query: t.intersection([uiFiltersRt, rangeRt]), diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration.ts index 6fd864a337165..f5c9cc2adf238 100644 --- a/x-pack/plugins/apm/server/routes/settings/agent_configuration.ts +++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration.ts @@ -24,7 +24,7 @@ import { import { jsonRt } from '../../../common/runtime_types/json_rt'; // get list of configurations -export const agentConfigurationRoute = createRoute((core) => ({ +export const agentConfigurationRoute = createRoute(() => ({ path: '/api/apm/settings/agent-configuration', handler: async ({ context, request }) => { const setup = await setupRequest(context, request); @@ -137,7 +137,7 @@ export const createOrUpdateAgentConfigurationRoute = createRoute(() => ({ })); // Lookup single configuration (used by APM Server) -export const agentConfigurationSearchRoute = createRoute((core) => ({ +export const agentConfigurationSearchRoute = createRoute(() => ({ method: 'POST', path: '/api/apm/settings/agent-configuration/search', params: { diff --git a/x-pack/plugins/apm/server/routes/settings/apm_indices.ts b/x-pack/plugins/apm/server/routes/settings/apm_indices.ts index 2d5722744f93e..e52ce760e026a 100644 --- a/x-pack/plugins/apm/server/routes/settings/apm_indices.ts +++ b/x-pack/plugins/apm/server/routes/settings/apm_indices.ts @@ -34,7 +34,7 @@ export const apmIndicesRoute = createRoute(() => ({ })); // save ui indices -export const saveApmIndicesRoute = createRoute((core) => ({ +export const saveApmIndicesRoute = createRoute(() => ({ method: 'POST', path: '/api/apm/settings/apm-indices/save', options: { @@ -50,7 +50,7 @@ export const saveApmIndicesRoute = createRoute((core) => ({ 'apm_oss.metricsIndices': t.string, }), }, - handler: async ({ context, request }) => { + handler: async ({ context }) => { const { body } = context.params; const savedObjectsClient = context.core.savedObjects.client; return await saveApmIndices(savedObjectsClient, body); diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link.ts b/x-pack/plugins/apm/server/routes/settings/custom_link.ts index f32840fe08b9c..83c23a75e999d 100644 --- a/x-pack/plugins/apm/server/routes/settings/custom_link.ts +++ b/x-pack/plugins/apm/server/routes/settings/custom_link.ts @@ -17,7 +17,7 @@ import { getTransaction } from '../../lib/settings/custom_link/get_transaction'; import { listCustomLinks } from '../../lib/settings/custom_link/list_custom_links'; import { createRoute } from '../create_route'; -export const customLinkTransactionRoute = createRoute((core) => ({ +export const customLinkTransactionRoute = createRoute(() => ({ path: '/api/apm/settings/custom_links/transaction', params: { query: filterOptionsRt, @@ -31,7 +31,7 @@ export const customLinkTransactionRoute = createRoute((core) => ({ }, })); -export const listCustomLinksRoute = createRoute((core) => ({ +export const listCustomLinksRoute = createRoute(() => ({ path: '/api/apm/settings/custom_links', params: { query: filterOptionsRt, diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/metric/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/metric/index.ts index 7256657903aab..14409ae166a84 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/elements/metric/index.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/metric/index.ts @@ -7,6 +7,7 @@ import { openSans } from '../../../common/lib/fonts'; import { ElementFactory } from '../../../types'; import { SetupInitializer } from '../../plugin'; +import { UI_SETTINGS } from '../../../../../../src/plugins/data/public'; export const metricElementInitializer: SetupInitializer = (core, setup) => { return () => ({ @@ -23,7 +24,7 @@ export const metricElementInitializer: SetupInitializer = (core, | metric "Countries" metricFont={font size=48 family="${openSans.value}" color="#000000" align="center" lHeight=48} labelFont={font size=14 family="${openSans.value}" color="#000000" align="center"} - metricFormat="${core.uiSettings.get('format:number:defaultPattern')}" + metricFormat="${core.uiSettings.get(UI_SETTINGS.FORMAT_NUMBER_DEFAULT_PATTERN)}" | render`, }); }; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx index 2dd116d5ada08..ad368a912cd8c 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx @@ -11,12 +11,10 @@ import { StartDeps } from '../../plugin'; import { IEmbeddable, EmbeddableFactory, - EmbeddablePanel, EmbeddableFactoryNotFoundError, } from '../../../../../../src/plugins/embeddable/public'; import { EmbeddableExpression } from '../../expression_types/embeddable'; import { RendererStrings } from '../../../i18n'; -import { getSavedObjectFinder } from '../../../../../../src/plugins/saved_objects/public'; import { embeddableInputToExpression } from './embeddable_input_to_expression'; import { EmbeddableInput } from '../../expression_types'; import { RendererHandlers } from '../../../types'; @@ -38,17 +36,7 @@ const renderEmbeddableFactory = (core: CoreStart, plugins: StartDeps) => { style={{ width: domNode.offsetWidth, height: domNode.offsetHeight, cursor: 'auto' }} > - + ); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/time_filter/index.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/time_filter/index.tsx index ef5bfb70d4b3d..25278adcf4529 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/time_filter/index.tsx +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/time_filter/index.tsx @@ -7,6 +7,7 @@ import ReactDOM from 'react-dom'; import React from 'react'; import { toExpression } from '@kbn/interpreter/common'; +import { UI_SETTINGS } from '../../../../../../src/plugins/data/public'; import { syncFilterExpression } from '../../../public/lib/sync_filter_expression'; import { RendererStrings } from '../../../i18n'; import { TimeFilter } from './components'; @@ -20,7 +21,7 @@ const { timeFilter: strings } = RendererStrings; export const timeFilterFactory: StartInitializer> = (core, plugins) => { const { uiSettings } = core; - const customQuickRanges = (uiSettings.get('timepicker:quickRanges') || []).map( + const customQuickRanges = (uiSettings.get(UI_SETTINGS.TIMEPICKER_QUICK_RANGES) || []).map( ({ from, to, display }: { from: string; to: string; display: string }) => ({ start: from, end: to, diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/index.ts index 4025d4deaf997..5a3e3904f4f23 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/index.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/number_format/index.ts @@ -11,6 +11,7 @@ import { templateFromReactComponent } from '../../../../public/lib/template_from import { ArgumentFactory } from '../../../../types/arguments'; import { ArgumentStrings } from '../../../../i18n'; import { SetupInitializer } from '../../../plugin'; +import { UI_SETTINGS } from '../../../../../../../src/plugins/data/public'; const { NumberFormat: strings } = ArgumentStrings; @@ -19,11 +20,11 @@ export const numberFormatInitializer: SetupInitializer { const formatMap = { - NUMBER: core.uiSettings.get('format:number:defaultPattern'), - PERCENT: core.uiSettings.get('format:percent:defaultPattern'), - CURRENCY: core.uiSettings.get('format:currency:defaultPattern'), + NUMBER: core.uiSettings.get(UI_SETTINGS.FORMAT_NUMBER_DEFAULT_PATTERN), + PERCENT: core.uiSettings.get(UI_SETTINGS.FORMAT_PERCENT_DEFAULT_PATTERN), + CURRENCY: core.uiSettings.get(UI_SETTINGS.FORMAT_CURRENCY_DEFAULT_PATTERN), DURATION: '00:00:00', - BYTES: core.uiSettings.get('format:bytes:defaultPattern'), + BYTES: core.uiSettings.get(UI_SETTINGS.FORMAT_BYTES_DEFAULT_PATTERN), }; const numberFormats = [ diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/views/metric.ts b/x-pack/plugins/canvas/canvas_plugin_src/uis/views/metric.ts index 93912b7b0517f..11bee46088576 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/uis/views/metric.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/views/metric.ts @@ -7,6 +7,7 @@ import { openSans } from '../../../common/lib/fonts'; import { ViewStrings } from '../../../i18n'; import { SetupInitializer } from '../../plugin'; +import { UI_SETTINGS } from '../../../../../../src/plugins/data/public'; const { Metric: strings } = ViewStrings; @@ -22,7 +23,7 @@ export const metricInitializer: SetupInitializer = (core, plugin) => { displayName: strings.getMetricFormatDisplayName(), help: strings.getMetricFormatHelp(), argType: 'numberFormat', - default: `"${core.uiSettings.get('format:number:defaultPattern')}"`, + default: `"${core.uiSettings.get(UI_SETTINGS.FORMAT_NUMBER_DEFAULT_PATTERN)}"`, }, { name: '_', diff --git a/x-pack/plugins/canvas/public/application.tsx b/x-pack/plugins/canvas/public/application.tsx index 8751d8102ad37..c799f36a283c1 100644 --- a/x-pack/plugins/canvas/public/application.tsx +++ b/x-pack/plugins/canvas/public/application.tsx @@ -33,7 +33,7 @@ import { CapabilitiesStrings } from '../i18n'; import { startServices, services } from './services'; // @ts-ignore Untyped local -import { destroyHistory } from './lib/history_provider'; +import { createHistory, destroyHistory } from './lib/history_provider'; // @ts-ignore Untyped local import { stopRouter } from './lib/router_provider'; import { initFunctions } from './functions'; @@ -97,6 +97,9 @@ export const initializeCanvas = async ( services.expressions.getService().registerFunction(fn); } + // Re-initialize our history + createHistory(); + // Create Store const canvasStore = await createStore(coreSetup, setupPlugins); diff --git a/x-pack/plugins/canvas/public/components/expression_input/__examples__/expression_input.examples.tsx b/x-pack/plugins/canvas/public/components/expression_input/__examples__/expression_input.examples.tsx index 51caf1db196bc..d010f4a554b87 100644 --- a/x-pack/plugins/canvas/public/components/expression_input/__examples__/expression_input.examples.tsx +++ b/x-pack/plugins/canvas/public/components/expression_input/__examples__/expression_input.examples.tsx @@ -7,7 +7,7 @@ import { action } from '@storybook/addon-actions'; import { storiesOf } from '@storybook/react'; import React from 'react'; -import { monaco } from '@kbn/ui-shared-deps/monaco'; +import { monaco } from '@kbn/monaco'; import { ExpressionInput } from '../expression_input'; import { language, LANGUAGE_ID } from '../../../lib/monaco_language_def'; diff --git a/x-pack/plugins/canvas/public/components/expression_input/expression_input.tsx b/x-pack/plugins/canvas/public/components/expression_input/expression_input.tsx index 99e12b14104be..5ada495208fba 100644 --- a/x-pack/plugins/canvas/public/components/expression_input/expression_input.tsx +++ b/x-pack/plugins/canvas/public/components/expression_input/expression_input.tsx @@ -8,7 +8,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { EuiFormRow } from '@elastic/eui'; import { debounce } from 'lodash'; -import { monaco } from '@kbn/ui-shared-deps/monaco'; +import { monaco } from '@kbn/monaco'; import { ExpressionFunction } from '../../../types'; import { CodeEditor } from '../../../../../../src/plugins/kibana_react/public'; import { diff --git a/x-pack/plugins/canvas/public/lib/history_provider.js b/x-pack/plugins/canvas/public/lib/history_provider.js index 649f101126012..396372eeb85c1 100644 --- a/x-pack/plugins/canvas/public/lib/history_provider.js +++ b/x-pack/plugins/canvas/public/lib/history_provider.js @@ -134,7 +134,7 @@ function wrapHistoryInstance(history) { return wrappedHistory; } -let instances = new WeakMap(); +const instances = new WeakMap(); const getHistoryInstance = (win) => { // if no window object, use memory module @@ -144,6 +144,15 @@ const getHistoryInstance = (win) => { return createHashStateHistory(); }; +export const createHistory = (win = getWindow()) => { + // create and cache wrapped history instance + const historyInstance = getHistoryInstance(win); + const wrappedInstance = wrapHistoryInstance(historyInstance); + instances.set(win, wrappedInstance); + + return wrappedInstance; +}; + export const historyProvider = (win = getWindow()) => { // return cached instance if one exists const instance = instances.get(win); @@ -151,14 +160,13 @@ export const historyProvider = (win = getWindow()) => { return instance; } - // create and cache wrapped history instance - const historyInstance = getHistoryInstance(win); - const wrappedInstance = wrapHistoryInstance(historyInstance); - instances.set(win, wrappedInstance); - - return wrappedInstance; + return createHistory(win); }; -export const destroyHistory = () => { - instances = new WeakMap(); +export const destroyHistory = (win = getWindow()) => { + const instance = instances.get(win); + + if (instance) { + instance.resetOnChange(); + } }; diff --git a/x-pack/plugins/canvas/public/lib/monaco_language_def.ts b/x-pack/plugins/canvas/public/lib/monaco_language_def.ts index 7bd9ea7b6ef9a..5b88658ddcd63 100644 --- a/x-pack/plugins/canvas/public/lib/monaco_language_def.ts +++ b/x-pack/plugins/canvas/public/lib/monaco_language_def.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { monaco } from '@kbn/ui-shared-deps/monaco'; +import { monaco } from '@kbn/monaco'; import { ExpressionFunction } from '../../types'; export const LANGUAGE_ID = 'canvas-expression'; diff --git a/x-pack/plugins/dashboard_enhanced/kibana.json b/x-pack/plugins/dashboard_enhanced/kibana.json index f416ca97f7110..37211ea537179 100644 --- a/x-pack/plugins/dashboard_enhanced/kibana.json +++ b/x-pack/plugins/dashboard_enhanced/kibana.json @@ -3,6 +3,6 @@ "version": "kibana", "server": false, "ui": true, - "requiredPlugins": ["data", "advancedUiActions", "drilldowns", "embeddable", "dashboard", "share"], + "requiredPlugins": ["data", "uiActionsEnhanced", "drilldowns", "embeddable", "dashboard", "share"], "configPath": ["xpack", "dashboardEnhanced"] } diff --git a/x-pack/plugins/dashboard_enhanced/public/plugin.ts b/x-pack/plugins/dashboard_enhanced/public/plugin.ts index c258a4148f84a..413f5a7afe356 100644 --- a/x-pack/plugins/dashboard_enhanced/public/plugin.ts +++ b/x-pack/plugins/dashboard_enhanced/public/plugin.ts @@ -9,19 +9,19 @@ import { SharePluginStart, SharePluginSetup } from '../../../../src/plugins/shar import { EmbeddableSetup, EmbeddableStart } from '../../../../src/plugins/embeddable/public'; import { DashboardDrilldownsService } from './services'; import { DataPublicPluginStart } from '../../../../src/plugins/data/public'; -import { AdvancedUiActionsSetup, AdvancedUiActionsStart } from '../../advanced_ui_actions/public'; +import { AdvancedUiActionsSetup, AdvancedUiActionsStart } from '../../ui_actions_enhanced/public'; import { DrilldownsSetup, DrilldownsStart } from '../../drilldowns/public'; import { DashboardStart } from '../../../../src/plugins/dashboard/public'; export interface SetupDependencies { - advancedUiActions: AdvancedUiActionsSetup; + uiActionsEnhanced: AdvancedUiActionsSetup; drilldowns: DrilldownsSetup; embeddable: EmbeddableSetup; share: SharePluginSetup; } export interface StartDependencies { - advancedUiActions: AdvancedUiActionsStart; + uiActionsEnhanced: AdvancedUiActionsStart; data: DataPublicPluginStart; drilldowns: DrilldownsStart; embeddable: EmbeddableStart; diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.test.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.test.tsx index 555acf1fca5ff..309e6cbf53a3d 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.test.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.test.tsx @@ -8,7 +8,7 @@ import { FlyoutEditDrilldownAction, FlyoutEditDrilldownParams } from './flyout_e import { coreMock } from '../../../../../../../../src/core/public/mocks'; import { drilldownsPluginMock } from '../../../../../../drilldowns/public/mocks'; import { ViewMode } from '../../../../../../../../src/plugins/embeddable/public'; -import { uiActionsEnhancedPluginMock } from '../../../../../../advanced_ui_actions/public/mocks'; +import { uiActionsEnhancedPluginMock } from '../../../../../../ui_actions_enhanced/public/mocks'; import { EnhancedEmbeddable } from '../../../../../../embeddable_enhanced/public'; import { MockEmbeddable, enhanceEmbeddable } from '../test_helpers'; diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.test.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.test.tsx index ec3a78e97eae4..9a4ecb2d4bfb0 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.test.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { render, cleanup, act } from '@testing-library/react/pure'; import { MenuItem } from './menu_item'; import { createStateContainer } from '../../../../../../../../src/plugins/kibana_utils/public'; -import { UiActionsEnhancedDynamicActionManager as DynamicActionManager } from '../../../../../../advanced_ui_actions/public'; +import { UiActionsEnhancedDynamicActionManager as DynamicActionManager } from '../../../../../../ui_actions_enhanced/public'; import { EnhancedEmbeddable } from '../../../../../../embeddable_enhanced/public'; import '@testing-library/jest-dom'; diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/test_helpers.ts b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/test_helpers.ts index cccacf701a9ad..e831f87baa11c 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/test_helpers.ts +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/test_helpers.ts @@ -10,9 +10,9 @@ import { UiActionsEnhancedMemoryActionStorage as MemoryActionStorage, UiActionsEnhancedDynamicActionManager as DynamicActionManager, AdvancedUiActionsStart, -} from '../../../../../advanced_ui_actions/public'; +} from '../../../../../ui_actions_enhanced/public'; import { TriggerContextMapping } from '../../../../../../../src/plugins/ui_actions/public'; -import { uiActionsEnhancedPluginMock } from '../../../../../advanced_ui_actions/public/mocks'; +import { uiActionsEnhancedPluginMock } from '../../../../../ui_actions_enhanced/public/mocks'; export class MockEmbeddable extends Embeddable { public rootType = 'dashboard'; diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_drilldowns_services.ts b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_drilldowns_services.ts index f5926cd6961c2..4325e3309b898 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_drilldowns_services.ts +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_drilldowns_services.ts @@ -41,7 +41,7 @@ export class DashboardDrilldownsService { setupDrilldowns( core: CoreSetup, - { advancedUiActions: uiActions }: SetupDependencies + { uiActionsEnhanced: uiActions }: SetupDependencies ) { const start = createStartServicesGetter(core.getStartServices); const getDashboardUrlGenerator = () => { diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/drilldown.test.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/drilldown.test.tsx index c94d19d28e6da..6ce7dccd3a3ec 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/drilldown.test.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/drilldown.test.tsx @@ -101,13 +101,13 @@ describe('.execute() & getHref', () => { }, }, plugins: { - advancedUiActions: {}, + uiActionsEnhanced: {}, data: { actions: dataPluginActions, }, }, self: {}, - })) as unknown) as StartServicesGetter>, + })) as unknown) as StartServicesGetter>, getDashboardUrlGenerator: () => new UrlGeneratorsService().setup(coreMock.createSetup()).registerUrlGenerator( createDashboardUrlGenerator(() => diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/drilldown.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/drilldown.tsx index 7ff84a75dd52c..26a69132cffb1 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/drilldown.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/drilldown.tsx @@ -10,7 +10,7 @@ import { DashboardUrlGenerator } from '../../../../../../../src/plugins/dashboar import { ActionContext, Config } from './types'; import { CollectConfigContainer } from './components'; import { DASHBOARD_TO_DASHBOARD_DRILLDOWN } from './constants'; -import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '../../../../../advanced_ui_actions/public'; +import { UiActionsEnhancedDrilldownDefinition as Drilldown } from '../../../../../ui_actions_enhanced/public'; import { txtGoToDashboard } from './i18n'; import { esFilters } from '../../../../../../../src/plugins/data/public'; import { VisualizeEmbeddableContract } from '../../../../../../../src/plugins/visualizations/public'; @@ -22,7 +22,7 @@ import { StartServicesGetter } from '../../../../../../../src/plugins/kibana_uti import { StartDependencies } from '../../../plugin'; export interface Params { - start: StartServicesGetter>; + start: StartServicesGetter>; getDashboardUrlGenerator: () => DashboardUrlGenerator; } diff --git a/x-pack/plugins/data_enhanced/public/plugin.ts b/x-pack/plugins/data_enhanced/public/plugin.ts index 72e0817eea8df..879c73587ed96 100644 --- a/x-pack/plugins/data_enhanced/public/plugin.ts +++ b/x-pack/plugins/data_enhanced/public/plugin.ts @@ -29,19 +29,20 @@ export interface DataEnhancedStartDependencies { export type DataEnhancedSetup = ReturnType; export type DataEnhancedStart = ReturnType; -export class DataEnhancedPlugin implements Plugin { - constructor() {} - - public setup(core: CoreSetup, { data }: DataEnhancedSetupDependencies) { +export class DataEnhancedPlugin + implements Plugin { + public setup( + core: CoreSetup, + { data }: DataEnhancedSetupDependencies + ) { data.autocomplete.addQuerySuggestionProvider( KUERY_LANGUAGE_NAME, setupKqlQuerySuggestionProvider(core) ); - data.search.registerSearchStrategyProvider(ASYNC_SEARCH_STRATEGY, asyncSearchStrategyProvider); - data.search.registerSearchStrategyProvider( - ES_SEARCH_STRATEGY, - enhancedEsSearchStrategyProvider - ); + const asyncSearchStrategy = asyncSearchStrategyProvider(core); + const esSearchStrategy = enhancedEsSearchStrategyProvider(core, asyncSearchStrategy); + data.search.registerSearchStrategy(ASYNC_SEARCH_STRATEGY, asyncSearchStrategy); + data.search.registerSearchStrategy(ES_SEARCH_STRATEGY, esSearchStrategy); } public start(core: CoreStart, plugins: DataEnhancedStartDependencies) { diff --git a/x-pack/plugins/data_enhanced/public/search/async_search_strategy.test.ts b/x-pack/plugins/data_enhanced/public/search/async_search_strategy.test.ts index 6c635cc5b4489..3013f9966f068 100644 --- a/x-pack/plugins/data_enhanced/public/search/async_search_strategy.test.ts +++ b/x-pack/plugins/data_enhanced/public/search/async_search_strategy.test.ts @@ -6,35 +6,37 @@ import { of } from 'rxjs'; import { AbortController } from 'abort-controller'; +import { CoreSetup } from '../../../../../src/core/public'; import { coreMock } from '../../../../../src/core/public/mocks'; +import { DataPublicPluginStart } from '../../../../../src/plugins/data/public'; +import { dataPluginMock } from '../../../../../src/plugins/data/public/mocks'; import { asyncSearchStrategyProvider } from './async_search_strategy'; -import { IAsyncSearchOptions } from './types'; -import { CoreStart } from 'kibana/public'; +import { IAsyncSearchOptions } from '.'; +import { DataEnhancedStartDependencies } from '../plugin'; describe('Async search strategy', () => { - let mockCoreStart: MockedKeys; + let mockCoreSetup: jest.Mocked>; + let mockDataStart: jest.Mocked; const mockSearch = jest.fn(); const mockRequest = { params: {}, serverStrategy: 'foo' }; const mockOptions: IAsyncSearchOptions = { pollInterval: 0 }; beforeEach(() => { - mockCoreStart = coreMock.createStart(); + mockCoreSetup = coreMock.createSetup(); + mockDataStart = dataPluginMock.createStartContract(); + (mockDataStart.search.getSearchStrategy as jest.Mock).mockReturnValue({ search: mockSearch }); + mockCoreSetup.getStartServices.mockResolvedValue([ + undefined as any, + { data: mockDataStart }, + undefined, + ]); mockSearch.mockReset(); }); it('only sends one request if the first response is complete', async () => { mockSearch.mockReturnValueOnce(of({ id: 1, total: 1, loaded: 1 })); - const asyncSearch = asyncSearchStrategyProvider({ - core: mockCoreStart, - getSearchStrategy: jest.fn().mockImplementation(() => { - return () => { - return { - search: mockSearch, - }; - }; - }), - }); + const asyncSearch = asyncSearchStrategyProvider(mockCoreSetup); await asyncSearch.search(mockRequest, mockOptions).toPromise(); @@ -51,17 +53,7 @@ describe('Async search strategy', () => { of({ id: 1, total: 2, loaded: 2, is_running: false, is_partial: false }) ); - const asyncSearch = asyncSearchStrategyProvider({ - core: mockCoreStart, - getSearchStrategy: jest.fn().mockImplementation(() => { - return () => { - return { - search: mockSearch, - }; - }; - }), - }); - + const asyncSearch = asyncSearchStrategyProvider(mockCoreSetup); expect(mockSearch).toBeCalledTimes(0); await asyncSearch.search(mockRequest, mockOptions).toPromise(); @@ -75,17 +67,7 @@ describe('Async search strategy', () => { .mockReturnValueOnce(of({ id: 1, total: 2, loaded: 2, is_running: false, is_partial: true })) .mockReturnValueOnce(of({ id: 1, total: 2, loaded: 2, is_running: false, is_partial: true })); - const asyncSearch = asyncSearchStrategyProvider({ - core: mockCoreStart, - getSearchStrategy: jest.fn().mockImplementation(() => { - return () => { - return { - search: mockSearch, - }; - }; - }), - }); - + const asyncSearch = asyncSearchStrategyProvider(mockCoreSetup); expect(mockSearch).toBeCalledTimes(0); await asyncSearch @@ -104,16 +86,7 @@ describe('Async search strategy', () => { of({ id: 1, total: 2, loaded: 2, is_running: false, is_partial: false }) ); - const asyncSearch = asyncSearchStrategyProvider({ - core: mockCoreStart, - getSearchStrategy: jest.fn().mockImplementation(() => { - return () => { - return { - search: mockSearch, - }; - }; - }), - }); + const asyncSearch = asyncSearchStrategyProvider(mockCoreSetup); expect(mockSearch).toBeCalledTimes(0); @@ -131,16 +104,7 @@ describe('Async search strategy', () => { of({ id: 1, total: 2, loaded: 2, is_running: false, is_partial: false }) ); - const asyncSearch = asyncSearchStrategyProvider({ - core: mockCoreStart, - getSearchStrategy: jest.fn().mockImplementation(() => { - return () => { - return { - search: mockSearch, - }; - }; - }), - }); + const asyncSearch = asyncSearchStrategyProvider(mockCoreSetup); expect(mockSearch).toBeCalledTimes(0); @@ -157,16 +121,7 @@ describe('Async search strategy', () => { .mockReturnValueOnce(of({ id: 1, total: 2, loaded: 2 })) .mockReturnValueOnce(of({ id: 1, total: 2, loaded: 2 })); - const asyncSearch = asyncSearchStrategyProvider({ - core: mockCoreStart, - getSearchStrategy: jest.fn().mockImplementation(() => { - return () => { - return { - search: mockSearch, - }; - }; - }), - }); + const asyncSearch = asyncSearchStrategyProvider(mockCoreSetup); const abortController = new AbortController(); const options = { ...mockOptions, signal: abortController.signal }; @@ -178,7 +133,7 @@ describe('Async search strategy', () => { } catch (e) { expect(e.name).toBe('AbortError'); expect(mockSearch).toBeCalledTimes(1); - expect(mockCoreStart.http.delete).toBeCalled(); + expect(mockCoreSetup.http.delete).toBeCalled(); } }); }); diff --git a/x-pack/plugins/data_enhanced/public/search/async_search_strategy.ts b/x-pack/plugins/data_enhanced/public/search/async_search_strategy.ts index 18b5b976b3c1b..7de4dd28ad3d7 100644 --- a/x-pack/plugins/data_enhanced/public/search/async_search_strategy.ts +++ b/x-pack/plugins/data_enhanced/public/search/async_search_strategy.ts @@ -4,17 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EMPTY, fromEvent, NEVER, Observable, throwError, timer } from 'rxjs'; -import { mergeMap, expand, takeUntil } from 'rxjs/operators'; +import { EMPTY, fromEvent, NEVER, throwError, timer, Observable, from } from 'rxjs'; +import { mergeMap, expand, takeUntil, share, flatMap } from 'rxjs/operators'; +import { CoreSetup } from '../../../../../src/core/public'; import { AbortError } from '../../../../../src/plugins/data/common'; import { - IKibanaSearchResponse, - ISearchContext, + ISearch, ISearchStrategy, + ISyncSearchRequest, SYNC_SEARCH_STRATEGY, - TSearchStrategyProvider, } from '../../../../../src/plugins/data/public'; -import { IAsyncSearchRequest, IAsyncSearchOptions, IAsyncSearchResponse } from './types'; +import { IAsyncSearchOptions, IAsyncSearchResponse, IAsyncSearchRequest } from './types'; +import { DataEnhancedStartDependencies } from '../plugin'; export const ASYNC_SEARCH_STRATEGY = 'ASYNC_SEARCH_STRATEGY'; @@ -24,55 +25,59 @@ declare module '../../../../../src/plugins/data/public' { } } -export const asyncSearchStrategyProvider: TSearchStrategyProvider = ( - context: ISearchContext -): ISearchStrategy => { - const syncStrategyProvider = context.getSearchStrategy(SYNC_SEARCH_STRATEGY); - const { search } = syncStrategyProvider(context); - return { - search: ( - request: IAsyncSearchRequest, - { pollInterval = 1000, ...options }: IAsyncSearchOptions = {} - ): Observable => { - const { serverStrategy } = request; - let id: string | undefined = request.id; +export function asyncSearchStrategyProvider( + core: CoreSetup +): ISearchStrategy { + const startServices$ = from(core.getStartServices()).pipe(share()); - const aborted$ = options.signal - ? fromEvent(options.signal, 'abort').pipe( - mergeMap(() => { - // If we haven't received the response to the initial request, including the ID, then - // we don't need to send a follow-up request to delete this search. Otherwise, we - // send the follow-up request to delete this search, then throw an abort error. - if (id !== undefined) { - context.core.http.delete(`/internal/search/${request.serverStrategy}/${id}`); - } - return throwError(new AbortError()); - }) - ) - : NEVER; + const search: ISearch = ( + request: ISyncSearchRequest, + { pollInterval = 1000, ...options }: IAsyncSearchOptions = {} + ) => { + const { serverStrategy } = request; + let { id } = request; - return search(request, options).pipe( - expand((response: IAsyncSearchResponse) => { - // If the response indicates of an error, stop polling and complete the observable - if (!response || (response.is_partial && !response.is_running)) { + const aborted$ = options.signal + ? fromEvent(options.signal, 'abort').pipe( + mergeMap(() => { + // If we haven't received the response to the initial request, including the ID, then + // we don't need to send a follow-up request to delete this search. Otherwise, we + // send the follow-up request to delete this search, then throw an abort error. + if (id !== undefined) { + core.http.delete(`/internal/search/${request.serverStrategy}/${id}`); + } return throwError(new AbortError()); - } + }) + ) + : NEVER; + + return startServices$.pipe( + flatMap((startServices) => { + const syncSearch = startServices[1].data.search.getSearchStrategy(SYNC_SEARCH_STRATEGY); + return (syncSearch.search(request, options) as Observable).pipe( + expand((response) => { + // If the response indicates of an error, stop polling and complete the observable + if (!response || (response.is_partial && !response.is_running)) { + return throwError(new AbortError()); + } - // If the response indicates it is complete, stop polling and complete the observable - if (!response.is_running) return EMPTY; + // If the response indicates it is complete, stop polling and complete the observable + if (!response.is_running) return EMPTY; - id = response.id; + id = response.id; - // Delay by the given poll interval - return timer(pollInterval).pipe( - // Send future requests using just the ID from the response - mergeMap(() => { - return search({ id, serverStrategy }, options); - }) - ); - }), - takeUntil(aborted$) - ); - }, + // Delay by the given poll interval + return timer(pollInterval).pipe( + // Send future requests using just the ID from the response + mergeMap(() => { + return search({ id, serverStrategy }, options); + }) + ); + }), + takeUntil(aborted$) + ); + }) + ); }; -}; + return { search }; +} diff --git a/x-pack/plugins/data_enhanced/public/search/es_search_strategy.test.ts b/x-pack/plugins/data_enhanced/public/search/es_search_strategy.test.ts new file mode 100644 index 0000000000000..5d6bd53e2c945 --- /dev/null +++ b/x-pack/plugins/data_enhanced/public/search/es_search_strategy.test.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { CoreSetup } from '../../../../../src/core/public'; +import { coreMock } from '../../../../../src/core/public/mocks'; +import { ES_SEARCH_STRATEGY } from '../../../../../src/plugins/data/common'; +import { enhancedEsSearchStrategyProvider } from './es_search_strategy'; +import { IAsyncSearchOptions } from '.'; + +describe('Enhanced ES search strategy', () => { + let mockCoreSetup: jest.Mocked; + const mockSearch = { search: jest.fn() }; + + beforeEach(() => { + mockCoreSetup = coreMock.createSetup(); + mockSearch.search.mockClear(); + }); + + it('returns a strategy with `search` that calls the async search `search`', () => { + const request = { params: {} }; + const options: IAsyncSearchOptions = { pollInterval: 0 }; + + const esSearch = enhancedEsSearchStrategyProvider(mockCoreSetup, mockSearch); + esSearch.search(request, options); + + expect(mockSearch.search.mock.calls[0][0]).toEqual({ + ...request, + serverStrategy: ES_SEARCH_STRATEGY, + }); + expect(mockSearch.search.mock.calls[0][1]).toEqual(options); + }); +}); diff --git a/x-pack/plugins/data_enhanced/public/search/es_search_strategy.ts b/x-pack/plugins/data_enhanced/public/search/es_search_strategy.ts index c493e8ce86781..c4b293a52a104 100644 --- a/x-pack/plugins/data_enhanced/public/search/es_search_strategy.ts +++ b/x-pack/plugins/data_enhanced/public/search/es_search_strategy.ts @@ -5,41 +5,40 @@ */ import { Observable } from 'rxjs'; +import { CoreSetup } from '../../../../../src/core/public'; import { ES_SEARCH_STRATEGY, IEsSearchResponse } from '../../../../../src/plugins/data/common'; import { - TSearchStrategyProvider, - ISearchContext, ISearch, getEsPreference, + ISearchStrategy, + UI_SETTINGS, } from '../../../../../src/plugins/data/public'; import { IEnhancedEsSearchRequest, EnhancedSearchParams } from '../../common'; import { ASYNC_SEARCH_STRATEGY } from './async_search_strategy'; import { IAsyncSearchOptions } from './types'; -export const enhancedEsSearchStrategyProvider: TSearchStrategyProvider = ( - context: ISearchContext -) => { - const asyncStrategyProvider = context.getSearchStrategy(ASYNC_SEARCH_STRATEGY); - const { search: asyncSearch } = asyncStrategyProvider(context); - +export function enhancedEsSearchStrategyProvider( + core: CoreSetup, + asyncStrategy: ISearchStrategy +) { const search: ISearch = ( request: IEnhancedEsSearchRequest, options ) => { const params: EnhancedSearchParams = { - ignoreThrottled: !context.core.uiSettings.get('search:includeFrozen'), - preference: getEsPreference(context.core.uiSettings), + ignoreThrottled: !core.uiSettings.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN), + preference: getEsPreference(core.uiSettings), ...request.params, }; request.params = params; const asyncOptions: IAsyncSearchOptions = { pollInterval: 0, ...options }; - return asyncSearch( + return asyncStrategy.search( { ...request, serverStrategy: ES_SEARCH_STRATEGY }, asyncOptions ) as Observable; }; return { search }; -}; +} diff --git a/x-pack/plugins/drilldowns/kibana.json b/x-pack/plugins/drilldowns/kibana.json index 678c054aa322c..1614f94b488fd 100644 --- a/x-pack/plugins/drilldowns/kibana.json +++ b/x-pack/plugins/drilldowns/kibana.json @@ -3,6 +3,6 @@ "version": "kibana", "server": false, "ui": true, - "requiredPlugins": ["uiActions", "embeddable", "advancedUiActions"], + "requiredPlugins": ["uiActions", "embeddable", "uiActionsEnhanced"], "configPath": ["xpack", "drilldowns"] } diff --git a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.story.tsx b/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.story.tsx index a186feec33924..5fde4fc79e433 100644 --- a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.story.tsx +++ b/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.story.tsx @@ -12,13 +12,13 @@ import { dashboardFactory, urlFactory, // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../advanced_ui_actions/public/components/action_wizard/test_data'; +} from '../../../../ui_actions_enhanced/public/components/action_wizard/test_data'; import { Storage } from '../../../../../../src/plugins/kibana_utils/public'; import { StubBrowserStorage } from '../../../../../../src/test_utils/public/stub_browser_storage'; import { mockDynamicActionManager } from './test_data'; const FlyoutManageDrilldowns = createFlyoutManageDrilldowns({ - advancedUiActions: { + uiActionsEnhanced: { getActionFactories() { return [dashboardFactory, urlFactory]; }, diff --git a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx b/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx index 0f7f0cb22760b..32cbec795d092 100644 --- a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx +++ b/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx @@ -11,7 +11,7 @@ import { createFlyoutManageDrilldowns } from './connected_flyout_manage_drilldow import { dashboardFactory, urlFactory, -} from '../../../../advanced_ui_actions/public/components/action_wizard/test_data'; +} from '../../../../ui_actions_enhanced/public/components/action_wizard/test_data'; import { StubBrowserStorage } from '../../../../../../src/test_utils/public/stub_browser_storage'; import { Storage } from '../../../../../../src/plugins/kibana_utils/public'; import { mockDynamicActionManager } from './test_data'; @@ -24,7 +24,7 @@ import { toastDrilldownsCRUDError } from './i18n'; const storage = new Storage(new StubBrowserStorage()); const notifications = coreMock.createStart().notifications; const FlyoutManageDrilldowns = createFlyoutManageDrilldowns({ - advancedUiActions: { + uiActionsEnhanced: { getActionFactories() { return [dashboardFactory, urlFactory]; }, diff --git a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.tsx b/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.tsx index 3c9d2d2a86fb1..45cf7365ebd91 100644 --- a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.tsx +++ b/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.tsx @@ -7,12 +7,12 @@ import React, { useEffect, useState } from 'react'; import useMountedState from 'react-use/lib/useMountedState'; import { - AdvancedUiActionsActionFactory as ActionFactory, + UiActionsEnhancedActionFactory as ActionFactory, AdvancedUiActionsStart, UiActionsEnhancedDynamicActionManager as DynamicActionManager, UiActionsEnhancedSerializedAction, UiActionsEnhancedSerializedEvent, -} from '../../../../advanced_ui_actions/public'; +} from '../../../../ui_actions_enhanced/public'; import { NotificationsStart } from '../../../../../../src/core/public'; import { DrilldownWizardConfig, FlyoutDrilldownWizard } from '../flyout_drilldown_wizard'; import { FlyoutListManageDrilldowns } from '../flyout_list_manage_drilldowns'; @@ -48,17 +48,17 @@ enum Routes { } export function createFlyoutManageDrilldowns({ - advancedUiActions, + uiActionsEnhanced, storage, notifications, }: { - advancedUiActions: AdvancedUiActionsStart; + uiActionsEnhanced: AdvancedUiActionsStart; storage: IStorageWrapper; notifications: NotificationsStart; }) { // fine to assume this is static, // because all action factories should be registered in setup phase - const allActionFactories = advancedUiActions.getActionFactories(); + const allActionFactories = uiActionsEnhanced.getActionFactories(); const allActionFactoriesById = allActionFactories.reduce((acc, next) => { acc[next.id] = next; return acc; diff --git a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/test_data.ts b/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/test_data.ts index c9cb0b0eb1cb3..d585fa0692e8c 100644 --- a/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/test_data.ts +++ b/x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/test_data.ts @@ -9,7 +9,7 @@ import { UiActionsEnhancedDynamicActionManager as DynamicActionManager, UiActionsEnhancedDynamicActionManagerState as DynamicActionManagerState, UiActionsEnhancedSerializedAction, -} from '../../../../advanced_ui_actions/public'; +} from '../../../../ui_actions_enhanced/public'; import { TriggerContextMapping } from '../../../../../../src/plugins/ui_actions/public'; import { createStateContainer } from '../../../../../../src/plugins/kibana_utils/common'; diff --git a/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.story.tsx b/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.story.tsx index add8b748afee9..be048bf920602 100644 --- a/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.story.tsx +++ b/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.story.tsx @@ -14,8 +14,8 @@ import { dashboardFactory, urlFactory, // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../advanced_ui_actions/public/components/action_wizard/test_data'; -import { AdvancedUiActionsActionFactory as ActionFactory } from '../../../../advanced_ui_actions/public/'; +} from '../../../../ui_actions_enhanced/public/components/action_wizard/test_data'; +import { UiActionsEnhancedActionFactory as ActionFactory } from '../../../../ui_actions_enhanced/public/'; storiesOf('components/FlyoutDrilldownWizard', module) .add('default', () => { diff --git a/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx b/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx index 84c1a04a71d15..87f886817517f 100644 --- a/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx +++ b/x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx @@ -16,7 +16,7 @@ import { txtEditDrilldownTitle, } from './i18n'; import { DrilldownHelloBar } from '../drilldown_hello_bar'; -import { AdvancedUiActionsActionFactory as ActionFactory } from '../../../../advanced_ui_actions/public'; +import { UiActionsEnhancedActionFactory as ActionFactory } from '../../../../ui_actions_enhanced/public'; export interface DrilldownWizardConfig { name: string; diff --git a/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.tsx b/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.tsx index 38168377b02bd..1813851d728db 100644 --- a/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.tsx +++ b/x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.tsx @@ -8,9 +8,9 @@ import React from 'react'; import { EuiFieldText, EuiForm, EuiFormRow, EuiSpacer } from '@elastic/eui'; import { txtDrilldownAction, txtNameOfDrilldown, txtUntitledDrilldown } from './i18n'; import { - AdvancedUiActionsActionFactory as ActionFactory, + UiActionsEnhancedActionFactory as ActionFactory, ActionWizard, -} from '../../../../advanced_ui_actions/public'; +} from '../../../../ui_actions_enhanced/public'; const noopFn = () => {}; diff --git a/x-pack/plugins/drilldowns/public/plugin.ts b/x-pack/plugins/drilldowns/public/plugin.ts index 0108e04df9c99..32176241c102f 100644 --- a/x-pack/plugins/drilldowns/public/plugin.ts +++ b/x-pack/plugins/drilldowns/public/plugin.ts @@ -6,18 +6,18 @@ import { CoreStart, CoreSetup, Plugin } from 'src/core/public'; import { UiActionsSetup, UiActionsStart } from '../../../../src/plugins/ui_actions/public'; -import { AdvancedUiActionsSetup, AdvancedUiActionsStart } from '../../advanced_ui_actions/public'; +import { AdvancedUiActionsSetup, AdvancedUiActionsStart } from '../../ui_actions_enhanced/public'; import { createFlyoutManageDrilldowns } from './components/connected_flyout_manage_drilldowns'; import { Storage } from '../../../../src/plugins/kibana_utils/public'; export interface SetupDependencies { uiActions: UiActionsSetup; - advancedUiActions: AdvancedUiActionsSetup; + uiActionsEnhanced: AdvancedUiActionsSetup; } export interface StartDependencies { uiActions: UiActionsStart; - advancedUiActions: AdvancedUiActionsStart; + uiActionsEnhanced: AdvancedUiActionsStart; } // eslint-disable-next-line @@ -36,7 +36,7 @@ export class DrilldownsPlugin public start(core: CoreStart, plugins: StartDependencies): StartContract { return { FlyoutManageDrilldowns: createFlyoutManageDrilldowns({ - advancedUiActions: plugins.advancedUiActions, + uiActionsEnhanced: plugins.uiActionsEnhanced, storage: new Storage(localStorage), notifications: core.notifications, }), diff --git a/x-pack/plugins/embeddable_enhanced/kibana.json b/x-pack/plugins/embeddable_enhanced/kibana.json index 780a1d5d89870..5663671de7bd9 100644 --- a/x-pack/plugins/embeddable_enhanced/kibana.json +++ b/x-pack/plugins/embeddable_enhanced/kibana.json @@ -3,5 +3,5 @@ "version": "kibana", "server": false, "ui": true, - "requiredPlugins": ["embeddable", "advancedUiActions"] + "requiredPlugins": ["embeddable", "uiActionsEnhanced"] } diff --git a/x-pack/plugins/embeddable_enhanced/public/embeddables/embeddable_action_storage.test.ts b/x-pack/plugins/embeddable_enhanced/public/embeddables/embeddable_action_storage.test.ts index f8b3a9dfb92d0..5c5d98d75295d 100644 --- a/x-pack/plugins/embeddable_enhanced/public/embeddables/embeddable_action_storage.test.ts +++ b/x-pack/plugins/embeddable_enhanced/public/embeddables/embeddable_action_storage.test.ts @@ -9,7 +9,7 @@ import { EmbeddableActionStorage, EmbeddableWithDynamicActionsInput, } from './embeddable_action_storage'; -import { UiActionsEnhancedSerializedEvent } from '../../../advanced_ui_actions/public'; +import { UiActionsEnhancedSerializedEvent } from '../../../ui_actions_enhanced/public'; import { of } from '../../../../../src/plugins/kibana_utils/public'; class TestEmbeddable extends Embeddable { diff --git a/x-pack/plugins/embeddable_enhanced/public/embeddables/embeddable_action_storage.ts b/x-pack/plugins/embeddable_enhanced/public/embeddables/embeddable_action_storage.ts index e93674ba650a7..fdc42585a80ce 100644 --- a/x-pack/plugins/embeddable_enhanced/public/embeddables/embeddable_action_storage.ts +++ b/x-pack/plugins/embeddable_enhanced/public/embeddables/embeddable_action_storage.ts @@ -7,7 +7,7 @@ import { UiActionsEnhancedAbstractActionStorage as AbstractActionStorage, UiActionsEnhancedSerializedEvent as SerializedEvent, -} from '../../../advanced_ui_actions/public'; +} from '../../../ui_actions_enhanced/public'; import { EmbeddableInput, EmbeddableOutput, diff --git a/x-pack/plugins/embeddable_enhanced/public/plugin.ts b/x-pack/plugins/embeddable_enhanced/public/plugin.ts index d26acb4459a71..e6413ac03aeae 100644 --- a/x-pack/plugins/embeddable_enhanced/public/plugin.ts +++ b/x-pack/plugins/embeddable_enhanced/public/plugin.ts @@ -27,7 +27,7 @@ import { UiActionsEnhancedDynamicActionManager as DynamicActionManager, AdvancedUiActionsSetup, AdvancedUiActionsStart, -} from '../../advanced_ui_actions/public'; +} from '../../ui_actions_enhanced/public'; import { PanelNotificationsAction, ACTION_PANEL_NOTIFICATIONS } from './actions'; declare module '../../../../src/plugins/ui_actions/public' { @@ -38,12 +38,12 @@ declare module '../../../../src/plugins/ui_actions/public' { export interface SetupDependencies { embeddable: EmbeddableSetup; - advancedUiActions: AdvancedUiActionsSetup; + uiActionsEnhanced: AdvancedUiActionsSetup; } export interface StartDependencies { embeddable: EmbeddableStart; - advancedUiActions: AdvancedUiActionsStart; + uiActionsEnhanced: AdvancedUiActionsStart; } // eslint-disable-next-line @@ -56,20 +56,20 @@ export class EmbeddableEnhancedPlugin implements Plugin { constructor(protected readonly context: PluginInitializerContext) {} - private uiActions?: StartDependencies['advancedUiActions']; + private uiActions?: StartDependencies['uiActionsEnhanced']; public setup(core: CoreSetup, plugins: SetupDependencies): SetupContract { this.setCustomEmbeddableFactoryProvider(plugins); const panelNotificationAction = new PanelNotificationsAction(); - plugins.advancedUiActions.registerAction(panelNotificationAction); - plugins.advancedUiActions.attachAction(PANEL_NOTIFICATION_TRIGGER, panelNotificationAction.id); + plugins.uiActionsEnhanced.registerAction(panelNotificationAction); + plugins.uiActionsEnhanced.attachAction(PANEL_NOTIFICATION_TRIGGER, panelNotificationAction.id); return {}; } public start(core: CoreStart, plugins: StartDependencies): StartContract { - this.uiActions = plugins.advancedUiActions; + this.uiActions = plugins.uiActionsEnhanced; return {}; } diff --git a/x-pack/plugins/embeddable_enhanced/public/types.ts b/x-pack/plugins/embeddable_enhanced/public/types.ts index 924605be332b2..4f5c316f2fc17 100644 --- a/x-pack/plugins/embeddable_enhanced/public/types.ts +++ b/x-pack/plugins/embeddable_enhanced/public/types.ts @@ -5,7 +5,7 @@ */ import { IEmbeddable } from '../../../../src/plugins/embeddable/public'; -import { UiActionsEnhancedDynamicActionManager as DynamicActionManager } from '../../advanced_ui_actions/public'; +import { UiActionsEnhancedDynamicActionManager as DynamicActionManager } from '../../ui_actions_enhanced/public'; export type EnhancedEmbeddable = E & { enhancements: { diff --git a/x-pack/plugins/event_log/server/es/cluster_client_adapter.test.ts b/x-pack/plugins/event_log/server/es/cluster_client_adapter.test.ts index 0144e573fc146..ada86adf84cfd 100644 --- a/x-pack/plugins/event_log/server/es/cluster_client_adapter.test.ts +++ b/x-pack/plugins/event_log/server/es/cluster_client_adapter.test.ts @@ -51,7 +51,7 @@ describe('doesIlmPolicyExist', () => { await clusterClientAdapter.doesIlmPolicyExist('foo'); expect(clusterClient.callAsInternalUser).toHaveBeenCalledWith('transport.request', { method: 'GET', - path: '_ilm/policy/foo', + path: '/_ilm/policy/foo', }); }); @@ -78,7 +78,7 @@ describe('createIlmPolicy', () => { await clusterClientAdapter.createIlmPolicy('foo', { args: true }); expect(clusterClient.callAsInternalUser).toHaveBeenCalledWith('transport.request', { method: 'PUT', - path: '_ilm/policy/foo', + path: '/_ilm/policy/foo', body: { args: true }, }); }); diff --git a/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts b/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts index 7fd239ca49369..a036bfb74e408 100644 --- a/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts +++ b/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts @@ -41,7 +41,7 @@ export class ClusterClientAdapter { public async doesIlmPolicyExist(policyName: string): Promise { const request = { method: 'GET', - path: `_ilm/policy/${policyName}`, + path: `/_ilm/policy/${policyName}`, }; try { await this.callEs('transport.request', request); @@ -55,7 +55,7 @@ export class ClusterClientAdapter { public async createIlmPolicy(policyName: string, policy: unknown): Promise { const request = { method: 'PUT', - path: `_ilm/policy/${policyName}`, + path: `/_ilm/policy/${policyName}`, body: policy, }; try { diff --git a/x-pack/plugins/global_search/README.md b/x-pack/plugins/global_search/README.md new file mode 100644 index 0000000000000..d47e0bd696fd8 --- /dev/null +++ b/x-pack/plugins/global_search/README.md @@ -0,0 +1,49 @@ +# Kibana GlobalSearch plugin + +The GlobalSearch plugin provides an easy way to search for various objects, such as applications +or dashboards from the Kibana instance, from both server and client-side plugins + +## Consuming the globalSearch API + +```ts +startDeps.globalSearch.find('some term').subscribe({ + next: ({ results }) => { + addNewResultsToList(results); + }, + error: () => {}, + complete: () => { + showAsyncSearchIndicator(false); + } +}); +``` + +## Registering custom result providers + +The GlobalSearch API allows to extend provided results by registering your own provider. + +```ts +setupDeps.globalSearch.registerResultProvider({ + id: 'my_provider', + find: (term, options, context) => { + const resultPromise = myService.search(term, context.core.savedObjects.client); + return from(resultPromise).pipe(takeUntil(options.aborted$); + }, +}); +``` + +## Known limitations + +### Client-side registered providers + +Results from providers registered from the client-side `registerResultProvider` API will +not be available when performing a search from the server-side. For this reason, prefer +registering providers using the server-side API when possible. + +Refer to the [RFC](rfcs/text/0011_global_search.md#result_provider_registration) for more details + +### Search completion cause + +There is currently no way to identify `globalSearch.find` observable completion cause: +searches completing because all providers returned all their results and searches +completing because the consumer aborted the search using the `aborted$` option or because +the internal timout period has been reaches will both complete the same way. diff --git a/x-pack/plugins/global_search/common/errors.test.ts b/x-pack/plugins/global_search/common/errors.test.ts new file mode 100644 index 0000000000000..949795abd701a --- /dev/null +++ b/x-pack/plugins/global_search/common/errors.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { GlobalSearchFindError } from './errors'; + +describe('GlobalSearchFindError', () => { + describe('#invalidLicense', () => { + it('create an error with the correct `type`', () => { + const error = GlobalSearchFindError.invalidLicense('foobar'); + expect(error.message).toBe('foobar'); + expect(error.type).toBe('invalid-license'); + }); + + it('can be identified via instanceof', () => { + const error = GlobalSearchFindError.invalidLicense('foo'); + expect(error instanceof GlobalSearchFindError).toBe(true); + }); + }); +}); diff --git a/x-pack/plugins/global_search/common/errors.ts b/x-pack/plugins/global_search/common/errors.ts new file mode 100644 index 0000000000000..15bc0958cb8aa --- /dev/null +++ b/x-pack/plugins/global_search/common/errors.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +// only one type for now, but already present for future-proof reasons +export type GlobalSearchFindErrorType = 'invalid-license'; + +/** + * Error thrown from the {@link GlobalSearchPluginStart.find | GlobalSearch find API}'s result observable + * + * @public + */ +export class GlobalSearchFindError extends Error { + public static invalidLicense(message: string) { + return new GlobalSearchFindError('invalid-license', message); + } + + private constructor(public readonly type: GlobalSearchFindErrorType, message: string) { + super(message); + + // Set the prototype explicitly, see: + // https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work + Object.setPrototypeOf(this, GlobalSearchFindError.prototype); + } +} diff --git a/x-pack/plugins/global_search/common/license_checker.mock.ts b/x-pack/plugins/global_search/common/license_checker.mock.ts new file mode 100644 index 0000000000000..e19a2562e53d8 --- /dev/null +++ b/x-pack/plugins/global_search/common/license_checker.mock.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ILicenseChecker } from './license_checker'; + +const createLicenseCheckerMock = (): jest.Mocked => { + const mock = { + getState: jest.fn(), + getLicense: jest.fn(), + clean: jest.fn(), + }; + + mock.getLicense.mockReturnValue(undefined); + mock.getState.mockReturnValue({ valid: true }); + + return mock; +}; + +export const licenseCheckerMock = { + create: createLicenseCheckerMock, +}; diff --git a/x-pack/plugins/global_search/common/license_checker.test.ts b/x-pack/plugins/global_search/common/license_checker.test.ts new file mode 100644 index 0000000000000..47a0d41016d71 --- /dev/null +++ b/x-pack/plugins/global_search/common/license_checker.test.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Observable, of, BehaviorSubject } from 'rxjs'; +import { licenseMock } from '../../licensing/common/licensing.mock'; +import { ILicense, LicenseCheck } from '../../licensing/common/types'; +import { LicenseChecker } from './license_checker'; + +describe('LicenseChecker', () => { + const createLicense = (check: LicenseCheck): ILicense => { + const license = licenseMock.createLicenseMock(); + license.check.mockReturnValue(check); + return license; + }; + + const createLicense$ = (check: LicenseCheck): Observable => of(createLicense(check)); + + it('returns the correct state of the license', () => { + let checker = new LicenseChecker(createLicense$({ state: 'valid' })); + expect(checker.getState()).toEqual({ valid: true }); + + checker = new LicenseChecker(createLicense$({ state: 'expired' })); + expect(checker.getState()).toEqual({ valid: false, message: 'expired' }); + + checker = new LicenseChecker(createLicense$({ state: 'invalid' })); + expect(checker.getState()).toEqual({ valid: false, message: 'invalid' }); + + checker = new LicenseChecker(createLicense$({ state: 'unavailable' })); + expect(checker.getState()).toEqual({ valid: false, message: 'unavailable' }); + }); + + it('updates the state when the license changes', () => { + const license$ = new BehaviorSubject(createLicense({ state: 'valid' })); + + const checker = new LicenseChecker(license$); + expect(checker.getState()).toEqual({ valid: true }); + + license$.next(createLicense({ state: 'expired' })); + expect(checker.getState()).toEqual({ valid: false, message: 'expired' }); + + license$.next(createLicense({ state: 'valid' })); + expect(checker.getState()).toEqual({ valid: true }); + }); + + it('removes the subscription when calling `clean`', () => { + const mockUnsubscribe = jest.fn(); + const mockObs = { + subscribe: jest.fn().mockReturnValue({ unsubscribe: mockUnsubscribe }), + }; + + const checker = new LicenseChecker(mockObs as any); + + expect(mockObs.subscribe).toHaveBeenCalledTimes(1); + expect(mockUnsubscribe).not.toHaveBeenCalled(); + + checker.clean(); + + expect(mockUnsubscribe).toHaveBeenCalledTimes(1); + }); +}); diff --git a/x-pack/plugins/global_search/common/license_checker.ts b/x-pack/plugins/global_search/common/license_checker.ts new file mode 100644 index 0000000000000..d201b31802b32 --- /dev/null +++ b/x-pack/plugins/global_search/common/license_checker.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Observable, Subscription } from 'rxjs'; +import { ILicense } from '../../licensing/common/types'; + +export type LicenseState = { valid: false; message: string } | { valid: true }; + +export type CheckLicense = (license: ILicense) => LicenseState; + +const checkLicense: CheckLicense = (license) => { + const check = license.check('globalSearch', 'basic'); + switch (check.state) { + case 'expired': + return { valid: false, message: 'expired' }; + case 'invalid': + return { valid: false, message: 'invalid' }; + case 'unavailable': + return { valid: false, message: 'unavailable' }; + case 'valid': + return { valid: true }; + default: + throw new Error(`Invalid license state: ${check.state}`); + } +}; + +export type ILicenseChecker = PublicMethodsOf; + +export class LicenseChecker { + private subscription: Subscription; + private state: LicenseState = { valid: false, message: 'unknown' }; + + constructor(license$: Observable) { + this.subscription = license$.subscribe((license) => { + this.state = checkLicense(license); + }); + } + + public getState() { + return this.state; + } + + public clean() { + this.subscription.unsubscribe(); + } +} diff --git a/x-pack/plugins/global_search/common/operators/index.ts b/x-pack/plugins/global_search/common/operators/index.ts new file mode 100644 index 0000000000000..2a0cf066a04aa --- /dev/null +++ b/x-pack/plugins/global_search/common/operators/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { takeInArray } from './take_in_array'; diff --git a/x-pack/plugins/global_search/common/operators/take_in_array.test.ts b/x-pack/plugins/global_search/common/operators/take_in_array.test.ts new file mode 100644 index 0000000000000..b73ee20c9889a --- /dev/null +++ b/x-pack/plugins/global_search/common/operators/take_in_array.test.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { TestScheduler } from 'rxjs/testing'; +import { takeInArray } from './take_in_array'; + +const getTestScheduler = () => + new TestScheduler((actual, expected) => { + expect(actual).toEqual(expected); + }); + +describe('takeInArray', () => { + it('only emits a given `count` of items from an array observable', () => { + getTestScheduler().run(({ expectObservable, hot }) => { + const source = hot('a-b-c', { a: [1], b: [2], c: [3] }); + const expected = 'a-(b|)'; + + expectObservable(source.pipe(takeInArray(2))).toBe(expected, { + a: [1], + b: [2], + }); + }); + }); + + it('completes if the source completes before reaching the given `count`', () => { + getTestScheduler().run(({ expectObservable, hot }) => { + const source = hot('a-b-c-|', { a: [1, 2], b: [3, 4], c: [5] }); + const expected = 'a-b-c-|'; + + expectObservable(source.pipe(takeInArray(10))).toBe(expected, { + a: [1, 2], + b: [3, 4], + c: [5], + }); + }); + }); + + it('split the emission if `count` is reached in a given emission', () => { + getTestScheduler().run(({ expectObservable, hot }) => { + const source = hot('a-b-c', { a: [1, 2, 3], b: [4, 5, 6], c: [7, 8] }); + const expected = 'a-(b|)'; + + expectObservable(source.pipe(takeInArray(5))).toBe(expected, { + a: [1, 2, 3], + b: [4, 5], + }); + }); + }); + + it('throws when trying to take a negative number of items', () => { + getTestScheduler().run(({ expectObservable, hot }) => { + const source = hot('a-b-c', { a: [1, 2, 3], b: [4, 5, 6], c: [7, 8] }); + + expect(() => { + source.pipe(takeInArray(-4)).subscribe(() => undefined); + }).toThrowErrorMatchingInlineSnapshot(`"Cannot take a negative number of items"`); + }); + }); +}); diff --git a/x-pack/plugins/global_search/common/operators/take_in_array.ts b/x-pack/plugins/global_search/common/operators/take_in_array.ts new file mode 100644 index 0000000000000..7d041d3c2bab0 --- /dev/null +++ b/x-pack/plugins/global_search/common/operators/take_in_array.ts @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +// eslint-disable-next-line max-classes-per-file +import { + EMPTY, + MonoTypeOperatorFunction, + Observable, + Operator, + Subscriber, + TeardownLogic, +} from 'rxjs'; + +/** + * Emits only the first `count` items from the arrays emitted by the source Observable. The limit + * is global to all emitted values, and not per emission. + * + * @example + * ```ts + * const source = of([1, 2], [3, 4], [5, 6]); + * const takeThreeInArray = source.pipe(takeInArray(3)); + * takeThreeInArray.subscribe(x => console.log(x)); + * + * // Logs: + * // [1,2] + * // [3] + * ``` + * + * @param count The total maximum number of value to keep from the emitted arrays + */ +export function takeInArray(count: number): MonoTypeOperatorFunction { + return function takeLastOperatorFunction(source: Observable): Observable { + if (count === 0) { + return EMPTY; + } else { + return source.lift(new TakeInArray(count)); + } + }; +} + +class TakeInArray implements Operator { + constructor(private total: number) { + if (this.total < 0) { + throw new Error('Cannot take a negative number of items'); + } + } + + call(subscriber: Subscriber, source: any): TeardownLogic { + return source.subscribe(new TakeInArraySubscriber(subscriber, this.total)); + } +} + +class TakeInArraySubscriber extends Subscriber { + private current: number = 0; + + constructor(destination: Subscriber, private total: number) { + super(destination); + } + + protected _next(value: T[]): void { + const remaining = this.total - this.current; + if (remaining > value.length) { + this.destination.next!(value); + this.current += value.length; + } else { + this.destination.next!(value.slice(0, remaining)); + this.destination.complete!(); + this.unsubscribe(); + } + } +} diff --git a/x-pack/plugins/global_search/common/process_result.test.mocks.ts b/x-pack/plugins/global_search/common/process_result.test.mocks.ts new file mode 100644 index 0000000000000..718ac7a1a6a52 --- /dev/null +++ b/x-pack/plugins/global_search/common/process_result.test.mocks.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const convertResultUrlMock = jest.fn().mockReturnValue('converted-url'); +jest.doMock('./utils', () => ({ + convertResultUrl: convertResultUrlMock, +})); diff --git a/x-pack/plugins/global_search/common/process_result.test.ts b/x-pack/plugins/global_search/common/process_result.test.ts new file mode 100644 index 0000000000000..723f21a24f552 --- /dev/null +++ b/x-pack/plugins/global_search/common/process_result.test.ts @@ -0,0 +1,73 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { convertResultUrlMock } from './process_result.test.mocks'; + +import { IBasePath } from './utils'; +import { GlobalSearchProviderResult } from './types'; +import { processProviderResult } from './process_result'; + +const createResult = (parts: Partial): GlobalSearchProviderResult => ({ + id: 'id', + title: 'title', + type: 'type', + icon: 'icon', + url: '/foo/bar', + score: 42, + meta: { foo: 'bar' }, + ...parts, +}); + +describe('processProviderResult', () => { + let basePath: jest.Mocked; + + beforeEach(() => { + basePath = { + prepend: jest.fn(), + }; + + convertResultUrlMock.mockClear(); + }); + + it('returns all properties unchanged except `url`', () => { + const r1 = createResult({ + id: '1', + type: 'test', + url: '/url-1', + title: 'title 1', + icon: 'foo', + score: 69, + meta: { hello: 'dolly' }, + }); + + expect(processProviderResult(r1, basePath)).toEqual({ + ...r1, + url: expect.any(String), + }); + }); + + it('converts the url using `convertResultUrl`', () => { + const r1 = createResult({ id: '1', url: '/url-1' }); + const r2 = createResult({ id: '2', url: '/url-2' }); + + convertResultUrlMock.mockReturnValueOnce('/url-A'); + convertResultUrlMock.mockReturnValueOnce('/url-B'); + + expect(convertResultUrlMock).not.toHaveBeenCalled(); + + const g1 = processProviderResult(r1, basePath); + + expect(g1.url).toEqual('/url-A'); + expect(convertResultUrlMock).toHaveBeenCalledTimes(1); + expect(convertResultUrlMock).toHaveBeenCalledWith(r1.url, basePath); + + const g2 = processProviderResult(r2, basePath); + + expect(g2.url).toEqual('/url-B'); + expect(convertResultUrlMock).toHaveBeenCalledTimes(2); + expect(convertResultUrlMock).toHaveBeenCalledWith(r2.url, basePath); + }); +}); diff --git a/x-pack/plugins/global_search/common/process_result.ts b/x-pack/plugins/global_search/common/process_result.ts new file mode 100644 index 0000000000000..fed6dc14f066b --- /dev/null +++ b/x-pack/plugins/global_search/common/process_result.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { GlobalSearchProviderResult, GlobalSearchResult } from './types'; +import { convertResultUrl, IBasePath } from './utils'; + +/** + * Convert a {@link GlobalSearchProviderResult | provider result} + * to a {@link GlobalSearchResult | service result} + */ +export const processProviderResult = ( + result: GlobalSearchProviderResult, + basePath: IBasePath +): GlobalSearchResult => { + return { + ...result, + url: convertResultUrl(result.url, basePath), + }; +}; diff --git a/x-pack/plugins/global_search/common/types.ts b/x-pack/plugins/global_search/common/types.ts new file mode 100644 index 0000000000000..26940806a4ecd --- /dev/null +++ b/x-pack/plugins/global_search/common/types.ts @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Observable } from 'rxjs'; +import { Serializable } from 'src/core/types'; + +/** + * Options provided to {@link GlobalSearchResultProvider | a result provider}'s `find` method. + */ +export interface GlobalSearchProviderFindOptions { + /** + * A custom preference token associated with a search 'session' that should be used to get consistent scoring + * when performing calls to ES. Can also be used as a 'session' token for providers returning data from elsewhere + * than an elasticsearch cluster. + */ + preference: string; + /** + * Observable that emits once if and when the `find` call has been aborted, either manually by the consumer, + * or when the internal timeout period as been reached. + * + * When a `find` request is effectively aborted, the service will stop emitting any new result to the consumer anyway, but + * this can (and should) be used to cancel any pending asynchronous task and complete the result observable from within the provider. + */ + aborted$: Observable; + /** + * The total maximum number of results (including all batches, not per emission) that should be returned by the provider for a given `find` request. + * Any result emitted exceeding this quota will be ignored by the service and not emitted to the consumer. + */ + maxResults: number; +} + +/** + * Structured type for the {@link GlobalSearchProviderResult.url | provider result's url property} + */ +export type GlobalSearchProviderResultUrl = string | { path: string; prependBasePath: boolean }; + +/** + * Representation of a result returned by a {@link GlobalSearchResultProvider | result provider} + */ +export interface GlobalSearchProviderResult { + /** an id that should be unique for an individual provider's results */ + id: string; + /** the title/label of the result */ + title: string; + /** the type of result */ + type: string; + /** an optional EUI icon name to associate with the search result */ + icon?: string; + /** + * The url associated with this result. + * This can be either an absolute url, a path relative to the basePath, or a structure specifying if the basePath should be prepended. + * + * @example + * `result.url = 'https://kibana-instance:8080/base-path/app/my-app/my-result-type/id';` + * `result.url = '/app/my-app/my-result-type/id';` + * `result.url = { path: '/base-path/app/my-app/my-result-type/id', prependBasePath: false };` + */ + url: GlobalSearchProviderResultUrl; + /** the score of the result, from 1 (lowest) to 100 (highest) */ + score: number; + /** an optional record of metadata for this result */ + meta?: Record; +} + +/** + * Representation of a result returned by the {@link GlobalSearchPluginStart.find | `find` API} + */ +export type GlobalSearchResult = Omit & { + /** + * The url associated with this result. + * This can be either an absolute url, or a relative path including the basePath + */ + url: string; +}; + +/** + * Response returned from the {@link GlobalSearchPluginStart | global search service}'s `find` API + * + * @public + */ +export interface GlobalSearchBatchedResults { + /** + * Results for this batch + */ + results: GlobalSearchResult[]; +} diff --git a/x-pack/plugins/global_search/common/utils.test.ts b/x-pack/plugins/global_search/common/utils.test.ts new file mode 100644 index 0000000000000..27f1ce99a58cc --- /dev/null +++ b/x-pack/plugins/global_search/common/utils.test.ts @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { convertResultUrl } from './utils'; + +const createBasePath = () => ({ + prepend: jest.fn(), +}); + +describe('convertResultUrl', () => { + let basePath: ReturnType; + + beforeEach(() => { + basePath = createBasePath(); + basePath.prepend.mockImplementation((path) => `/base-path${path}`); + }); + + describe('when the url is a string', () => { + it('does not convert absolute urls', () => { + expect(convertResultUrl('http://kibana:8080/foo/bar', basePath)).toEqual( + 'http://kibana:8080/foo/bar' + ); + expect(convertResultUrl('https://localhost/path/to/thing', basePath)).toEqual( + 'https://localhost/path/to/thing' + ); + expect(basePath.prepend).toHaveBeenCalledTimes(0); + }); + + it('prepends the base path to relative urls', () => { + expect(convertResultUrl('/app/my-app/foo', basePath)).toEqual('/base-path/app/my-app/foo'); + expect(basePath.prepend).toHaveBeenCalledTimes(1); + expect(basePath.prepend).toHaveBeenCalledWith('/app/my-app/foo'); + + expect(convertResultUrl('/some-path', basePath)).toEqual('/base-path/some-path'); + expect(basePath.prepend).toHaveBeenCalledTimes(2); + expect(basePath.prepend).toHaveBeenCalledWith('/some-path'); + }); + }); + + describe('when the url is an object', () => { + it('converts the path if `prependBasePath` is true', () => { + expect(convertResultUrl({ path: '/app/my-app', prependBasePath: true }, basePath)).toEqual( + '/base-path/app/my-app' + ); + expect(basePath.prepend).toHaveBeenCalledTimes(1); + expect(basePath.prepend).toHaveBeenCalledWith('/app/my-app'); + + expect(convertResultUrl({ path: '/some-path', prependBasePath: true }, basePath)).toEqual( + '/base-path/some-path' + ); + expect(basePath.prepend).toHaveBeenCalledTimes(2); + expect(basePath.prepend).toHaveBeenCalledWith('/some-path'); + }); + it('does not convert the path if `prependBasePath` is false', () => { + expect(convertResultUrl({ path: '/app/my-app', prependBasePath: false }, basePath)).toEqual( + '/app/my-app' + ); + expect(convertResultUrl({ path: '/some-path', prependBasePath: false }, basePath)).toEqual( + '/some-path' + ); + expect(basePath.prepend).toHaveBeenCalledTimes(0); + }); + }); +}); diff --git a/x-pack/plugins/global_search/common/utils.ts b/x-pack/plugins/global_search/common/utils.ts new file mode 100644 index 0000000000000..46648319458de --- /dev/null +++ b/x-pack/plugins/global_search/common/utils.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { GlobalSearchProviderResultUrl } from './types'; + +// interface matching both the server and client-side implementation of IBasePath for our needs +// used to avoid duplicating `convertResultUrl` in server and client code due to different signatures. +export interface IBasePath { + prepend(path: string): string; +} + +/** + * Convert a {@link GlobalSearchProviderResultUrl | provider result's url} to an absolute or relative url + * usable in {@link GlobalSearchResult | service results} + */ +export const convertResultUrl = ( + url: GlobalSearchProviderResultUrl, + basePath: IBasePath +): string => { + if (typeof url === 'string') { + // relative path + if (url.startsWith('/')) { + return basePath.prepend(url); + } + // absolute url + return url; + } + if (url.prependBasePath) { + return basePath.prepend(url.path); + } + return url.path; +}; diff --git a/x-pack/plugins/global_search/kibana.json b/x-pack/plugins/global_search/kibana.json new file mode 100644 index 0000000000000..c94e080a8c589 --- /dev/null +++ b/x-pack/plugins/global_search/kibana.json @@ -0,0 +1,10 @@ +{ + "id": "globalSearch", + "version": "8.0.0", + "kibanaVersion": "kibana", + "server": true, + "ui": true, + "requiredPlugins": ["licensing"], + "optionalPlugins": [], + "configPath": ["xpack", "global_search"] +} diff --git a/x-pack/plugins/global_search/public/config.ts b/x-pack/plugins/global_search/public/config.ts new file mode 100644 index 0000000000000..a3969bef287b2 --- /dev/null +++ b/x-pack/plugins/global_search/public/config.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export interface GlobalSearchClientConfigType { + // is a string because the server-side counterpart is a duration + // which is serialized to string when sent to the client + // should be parsed using moment.duration(config.search_timeout) + search_timeout: string; +} diff --git a/x-pack/plugins/global_search/public/index.ts b/x-pack/plugins/global_search/public/index.ts new file mode 100644 index 0000000000000..18483cea72540 --- /dev/null +++ b/x-pack/plugins/global_search/public/index.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { PluginInitializer } from 'src/core/public'; +import { + GlobalSearchPlugin, + GlobalSearchPluginSetupDeps, + GlobalSearchPluginStartDeps, +} from './plugin'; +import { GlobalSearchPluginSetup, GlobalSearchPluginStart } from './types'; + +export const plugin: PluginInitializer< + GlobalSearchPluginSetup, + GlobalSearchPluginStart, + GlobalSearchPluginSetupDeps, + GlobalSearchPluginStartDeps +> = (context) => new GlobalSearchPlugin(context); + +export { + GlobalSearchBatchedResults, + GlobalSearchProviderFindOptions, + GlobalSearchProviderResult, + GlobalSearchProviderResultUrl, + GlobalSearchResult, +} from '../common/types'; +export { + GlobalSearchPluginSetup, + GlobalSearchPluginStart, + GlobalSearchResultProvider, +} from './types'; +export { GlobalSearchFindOptions } from './services/types'; diff --git a/x-pack/plugins/global_search/public/mocks.ts b/x-pack/plugins/global_search/public/mocks.ts new file mode 100644 index 0000000000000..97dc01e92dbfe --- /dev/null +++ b/x-pack/plugins/global_search/public/mocks.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { GlobalSearchPluginSetup, GlobalSearchPluginStart } from './types'; +import { searchServiceMock } from './services/search_service.mock'; + +const createSetupMock = (): jest.Mocked => { + const searchMock = searchServiceMock.createSetupContract(); + + return { + registerResultProvider: searchMock.registerResultProvider, + }; +}; + +const createStartMock = (): jest.Mocked => { + const searchMock = searchServiceMock.createStartContract(); + + return { + find: searchMock.find, + }; +}; + +export const globalSearchPluginMock = { + createSetupContract: createSetupMock, + createStartContract: createStartMock, +}; diff --git a/x-pack/plugins/global_search/public/plugin.ts b/x-pack/plugins/global_search/public/plugin.ts new file mode 100644 index 0000000000000..6af8ec32a581d --- /dev/null +++ b/x-pack/plugins/global_search/public/plugin.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'src/core/public'; +import { LicensingPluginStart } from '../../licensing/public'; +import { LicenseChecker, ILicenseChecker } from '../common/license_checker'; +import { GlobalSearchPluginSetup, GlobalSearchPluginStart } from './types'; +import { GlobalSearchClientConfigType } from './config'; +import { SearchService } from './services'; + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface GlobalSearchPluginSetupDeps {} +export interface GlobalSearchPluginStartDeps { + licensing: LicensingPluginStart; +} + +export class GlobalSearchPlugin + implements + Plugin< + GlobalSearchPluginSetup, + GlobalSearchPluginStart, + GlobalSearchPluginSetupDeps, + GlobalSearchPluginStartDeps + > { + private readonly config: GlobalSearchClientConfigType; + private licenseChecker?: ILicenseChecker; + private readonly searchService = new SearchService(); + + constructor(context: PluginInitializerContext) { + this.config = context.config.get(); + } + + setup(core: CoreSetup<{}, GlobalSearchPluginStart>) { + const { registerResultProvider } = this.searchService.setup({ + config: this.config, + }); + + return { + registerResultProvider, + }; + } + + start({ http }: CoreStart, { licensing }: GlobalSearchPluginStartDeps) { + this.licenseChecker = new LicenseChecker(licensing.license$); + const { find } = this.searchService.start({ + http, + licenseChecker: this.licenseChecker, + }); + + return { + find, + }; + } + + public stop() { + if (this.licenseChecker) { + this.licenseChecker.clean(); + } + } +} diff --git a/x-pack/plugins/global_search/public/services/fetch_server_results.test.ts b/x-pack/plugins/global_search/public/services/fetch_server_results.test.ts new file mode 100644 index 0000000000000..f62acd08633ff --- /dev/null +++ b/x-pack/plugins/global_search/public/services/fetch_server_results.test.ts @@ -0,0 +1,88 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { TestScheduler } from 'rxjs/testing'; +import { httpServiceMock } from '../../../../../src/core/public/mocks'; +import { GlobalSearchResult } from '../../common/types'; +import { fetchServerResults } from './fetch_server_results'; + +const getTestScheduler = () => + new TestScheduler((actual, expected) => { + expect(actual).toEqual(expected); + }); + +const createResult = (id: string, parts: Partial = {}): GlobalSearchResult => ({ + id, + title: id, + type: 'type', + url: `/path/to/${id}`, + score: 100, + ...parts, +}); + +describe('fetchServerResults', () => { + let http: ReturnType; + + beforeEach(() => { + http = httpServiceMock.createStartContract(); + }); + + it('perform a POST request to the endpoint with valid options', () => { + http.post.mockResolvedValue({ results: [] }); + + fetchServerResults(http, 'some term', { preference: 'pref' }); + + expect(http.post).toHaveBeenCalledTimes(1); + expect(http.post).toHaveBeenCalledWith('/internal/global_search/find', { + body: JSON.stringify({ term: 'some term', options: { preference: 'pref' } }), + }); + }); + + it('returns the results from the server', async () => { + const resultA = createResult('A'); + const resultB = createResult('B'); + + http.post.mockResolvedValue({ results: [resultA, resultB] }); + + const results = await fetchServerResults(http, 'some term', { preference: 'pref' }).toPromise(); + + expect(http.post).toHaveBeenCalledTimes(1); + expect(results).toHaveLength(2); + expect(results[0]).toEqual(resultA); + expect(results[1]).toEqual(resultB); + }); + + describe('returns an observable that', () => { + // NOTE: test scheduler do not properly work with promises because of their asynchronous nature. + // we are cheating here by having `http.post` return an observable instead of a promise. + // this still allows more finely grained testing about timing, and asserting that the method + // works properly when `post` returns a real promise is handled in other tests of this suite + + it('emits when the response is received', () => { + getTestScheduler().run(({ expectObservable, hot }) => { + http.post.mockReturnValue(hot('---(a|)', { a: { results: [] } }) as any); + + const results = fetchServerResults(http, 'term', {}); + + expectObservable(results).toBe('---(a|)', { + a: [], + }); + }); + }); + + it('completes without returning results if aborted$ emits before the response', () => { + getTestScheduler().run(({ expectObservable, hot }) => { + http.post.mockReturnValue(hot('---(a|)', { a: { results: [] } }) as any); + const aborted$ = hot('-(a|)', { a: undefined }); + const results = fetchServerResults(http, 'term', { aborted$ }); + + expectObservable(results).toBe('-|', { + a: [], + }); + }); + }); + }); +}); diff --git a/x-pack/plugins/global_search/public/services/fetch_server_results.ts b/x-pack/plugins/global_search/public/services/fetch_server_results.ts new file mode 100644 index 0000000000000..3c06dfab9f50e --- /dev/null +++ b/x-pack/plugins/global_search/public/services/fetch_server_results.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Observable, from, EMPTY } from 'rxjs'; +import { map, takeUntil } from 'rxjs/operators'; +import { HttpStart } from 'src/core/public'; +import { GlobalSearchResult } from '../../common/types'; +import { GlobalSearchFindOptions } from './types'; + +interface ServerFetchResponse { + results: GlobalSearchResult[]; +} + +/** + * Fetch the server-side results from the GS internal HTTP API. + * + * @remarks + * Though this function returns an Observable, the current implementation is not streaming + * results from the server. All results will be returned in a single batch when + * all server-side providers are completed. + */ +export const fetchServerResults = ( + http: HttpStart, + term: string, + { preference, aborted$ }: GlobalSearchFindOptions +): Observable => { + let controller: AbortController | undefined; + if (aborted$) { + controller = new AbortController(); + aborted$.subscribe(() => { + controller!.abort(); + }); + } + return from( + http.post('/internal/global_search/find', { + body: JSON.stringify({ term, options: { preference } }), + signal: controller?.signal, + }) + ).pipe( + takeUntil(aborted$ ?? EMPTY), + map((response) => response.results) + ); +}; diff --git a/x-pack/plugins/global_search/public/services/index.ts b/x-pack/plugins/global_search/public/services/index.ts new file mode 100644 index 0000000000000..8d3cb86043432 --- /dev/null +++ b/x-pack/plugins/global_search/public/services/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { SearchService, SearchServiceSetup, SearchServiceStart } from './search_service'; +export { GlobalSearchFindOptions } from './types'; diff --git a/x-pack/plugins/global_search/public/services/search_service.mock.ts b/x-pack/plugins/global_search/public/services/search_service.mock.ts new file mode 100644 index 0000000000000..eca69148288b9 --- /dev/null +++ b/x-pack/plugins/global_search/public/services/search_service.mock.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SearchServiceSetup, SearchServiceStart } from './search_service'; +import { of } from 'rxjs'; + +const createSetupMock = (): jest.Mocked => { + return { + registerResultProvider: jest.fn(), + }; +}; + +const createStartMock = (): jest.Mocked => { + const mock = { + find: jest.fn(), + }; + mock.find.mockReturnValue(of({ results: [] })); + + return mock; +}; + +export const searchServiceMock = { + createSetupContract: createSetupMock, + createStartContract: createStartMock, +}; diff --git a/x-pack/plugins/global_search/public/services/search_service.test.mocks.ts b/x-pack/plugins/global_search/public/services/search_service.test.mocks.ts new file mode 100644 index 0000000000000..ce406e27c4a72 --- /dev/null +++ b/x-pack/plugins/global_search/public/services/search_service.test.mocks.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const fetchServerResultsMock = jest.fn(); +jest.doMock('./fetch_server_results', () => ({ + fetchServerResults: fetchServerResultsMock, +})); + +export const getDefaultPreferenceMock = jest.fn(); +jest.doMock('./utils', () => ({ + ...jest.requireActual('./utils'), + getDefaultPreference: getDefaultPreferenceMock, +})); diff --git a/x-pack/plugins/global_search/public/services/search_service.test.ts b/x-pack/plugins/global_search/public/services/search_service.test.ts new file mode 100644 index 0000000000000..350547a928fe4 --- /dev/null +++ b/x-pack/plugins/global_search/public/services/search_service.test.ts @@ -0,0 +1,436 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { fetchServerResultsMock, getDefaultPreferenceMock } from './search_service.test.mocks'; + +import { Observable, of } from 'rxjs'; +import { take } from 'rxjs/operators'; +import { TestScheduler } from 'rxjs/testing'; +import { duration } from 'moment'; +import { httpServiceMock } from '../../../../../src/core/public/mocks'; +import { licenseCheckerMock } from '../../common/license_checker.mock'; +import { GlobalSearchProviderResult, GlobalSearchResult } from '../../common/types'; +import { GlobalSearchFindError } from '../../common/errors'; +import { GlobalSearchClientConfigType } from '../config'; +import { GlobalSearchResultProvider } from '../types'; +import { SearchService } from './search_service'; + +const getTestScheduler = () => + new TestScheduler((actual, expected) => { + expect(actual).toEqual(expected); + }); + +describe('SearchService', () => { + let service: SearchService; + let httpStart: ReturnType; + let licenseChecker: ReturnType; + + const createConfig = (timeoutMs: number = 30000): GlobalSearchClientConfigType => { + return { + search_timeout: duration(timeoutMs).toString(), + }; + }; + + const startDeps = () => ({ + http: httpStart, + licenseChecker, + }); + + const createProvider = ( + id: string, + source: Observable = of([]) + ): jest.Mocked => ({ + id, + find: jest.fn().mockImplementation((term, options, context) => source), + }); + + const expectedResult = (id: string) => expect.objectContaining({ id }); + + const expectedBatch = (...ids: string[]) => ({ + results: ids.map((id) => expectedResult(id)), + }); + + const providerResult = ( + id: string, + parts: Partial = {} + ): GlobalSearchProviderResult => ({ + title: id, + type: 'test', + url: '/foo/bar', + score: 100, + ...parts, + id, + }); + + const serverResult = ( + id: string, + parts: Partial = {} + ): GlobalSearchResult => ({ + title: id, + type: 'test', + url: '/foo/bar', + score: 100, + ...parts, + id, + }); + + beforeEach(() => { + service = new SearchService(); + httpStart = httpServiceMock.createStartContract({ basePath: '/base-path' }); + licenseChecker = licenseCheckerMock.create(); + + fetchServerResultsMock.mockClear(); + fetchServerResultsMock.mockReturnValue(of()); + + getDefaultPreferenceMock.mockClear(); + getDefaultPreferenceMock.mockReturnValue('default_pref'); + }); + + describe('#setup()', () => { + describe('#registerResultProvider()', () => { + it('throws when trying to register the same provider twice', () => { + const { registerResultProvider } = service.setup({ + config: createConfig(), + }); + + const provider = createProvider('A'); + registerResultProvider(provider); + expect(() => { + registerResultProvider(provider); + }).toThrowErrorMatchingInlineSnapshot(`"trying to register duplicate provider: A"`); + }); + }); + }); + + describe('#start()', () => { + describe('#find()', () => { + it('calls the provider with the correct parameters', () => { + const { registerResultProvider } = service.setup({ + config: createConfig(), + }); + + const provider = createProvider('A'); + registerResultProvider(provider); + + const { find } = service.start(startDeps()); + find('foobar', { preference: 'pref' }); + + expect(provider.find).toHaveBeenCalledTimes(1); + expect(provider.find).toHaveBeenCalledWith( + 'foobar', + expect.objectContaining({ preference: 'pref' }) + ); + }); + + it('calls `fetchServerResults` with the correct parameters', () => { + service.setup({ config: createConfig() }); + + const { find } = service.start(startDeps()); + find('foobar', { preference: 'pref' }); + + expect(fetchServerResultsMock).toHaveBeenCalledTimes(1); + expect(fetchServerResultsMock).toHaveBeenCalledWith( + httpStart, + 'foobar', + expect.objectContaining({ preference: 'pref', aborted$: expect.any(Object) }) + ); + }); + + it('calls `getDefaultPreference` when `preference` is not specified', () => { + const { registerResultProvider } = service.setup({ + config: createConfig(), + }); + + const provider = createProvider('A'); + registerResultProvider(provider); + + const { find } = service.start(startDeps()); + find('foobar', { preference: 'pref' }); + + expect(getDefaultPreferenceMock).not.toHaveBeenCalled(); + + expect(provider.find).toHaveBeenNthCalledWith( + 1, + 'foobar', + expect.objectContaining({ + preference: 'pref', + }) + ); + + find('foobar', {}); + + expect(getDefaultPreferenceMock).toHaveBeenCalledTimes(1); + + expect(provider.find).toHaveBeenNthCalledWith( + 2, + 'foobar', + expect.objectContaining({ + preference: 'default_pref', + }) + ); + }); + + it('return the results from the provider', async () => { + const { registerResultProvider } = service.setup({ + config: createConfig(), + }); + + getTestScheduler().run(({ expectObservable, hot }) => { + const providerResults = hot('a-b-|', { + a: [providerResult('1')], + b: [providerResult('2')], + }); + registerResultProvider(createProvider('A', providerResults)); + + const { find } = service.start(startDeps()); + const results = find('foo', {}); + + expectObservable(results).toBe('a-b-|', { + a: expectedBatch('1'), + b: expectedBatch('2'), + }); + }); + }); + + it('return the results from the server', async () => { + service.setup({ config: createConfig() }); + + getTestScheduler().run(({ expectObservable, hot }) => { + const serverResults = hot('a-b-|', { + a: [serverResult('1')], + b: [serverResult('2')], + }); + + fetchServerResultsMock.mockReturnValue(serverResults); + + const { find } = service.start(startDeps()); + const results = find('foo', {}); + + expectObservable(results).toBe('a-b-|', { + a: expectedBatch('1'), + b: expectedBatch('2'), + }); + }); + }); + + it('handles multiple providers', async () => { + const { registerResultProvider } = service.setup({ + config: createConfig(), + }); + + getTestScheduler().run(({ expectObservable, hot }) => { + registerResultProvider( + createProvider( + 'A', + hot('a---d-|', { + a: [providerResult('A1'), providerResult('A2')], + d: [providerResult('A3')], + }) + ) + ); + registerResultProvider( + createProvider( + 'B', + hot('-b-c| ', { + b: [providerResult('B1')], + c: [providerResult('B2'), providerResult('B3')], + }) + ) + ); + + const { find } = service.start(startDeps()); + const results = find('foo', {}); + + expectObservable(results).toBe('ab-cd-|', { + a: expectedBatch('A1', 'A2'), + b: expectedBatch('B1'), + c: expectedBatch('B2', 'B3'), + d: expectedBatch('A3'), + }); + }); + }); + + it('return mixed server/client providers results', async () => { + const { registerResultProvider } = service.setup({ + config: createConfig(), + }); + + getTestScheduler().run(({ expectObservable, hot }) => { + fetchServerResultsMock.mockReturnValue( + hot('-----(c|)', { + c: [serverResult('S1'), serverResult('S2')], + }) + ); + + registerResultProvider( + createProvider( + 'A', + hot('a-b-|', { + a: [providerResult('P1')], + b: [providerResult('P2')], + }) + ) + ); + + const { find } = service.start(startDeps()); + const results = find('foo', {}); + + expectObservable(results).toBe('a-b--(c|)', { + a: expectedBatch('P1'), + b: expectedBatch('P2'), + c: expectedBatch('S1', 'S2'), + }); + }); + }); + + it('handles the `aborted$` option', async () => { + const { registerResultProvider } = service.setup({ + config: createConfig(), + }); + + getTestScheduler().run(({ expectObservable, hot }) => { + const providerResults = hot('--a---(b|)', { + a: [providerResult('1')], + b: [providerResult('2')], + }); + registerResultProvider(createProvider('A', providerResults)); + + const aborted$ = hot('----a--|', { a: undefined }); + + const { find } = service.start(startDeps()); + const results = find('foo', { aborted$ }); + + expectObservable(results).toBe('--a-|', { + a: expectedBatch('1'), + }); + }); + }); + + it('respects the timeout duration', async () => { + const { registerResultProvider } = service.setup({ + config: createConfig(100), + }); + + getTestScheduler().run(({ expectObservable, hot }) => { + const providerResults = hot('a 24ms b 100ms (c|)', { + a: [providerResult('1')], + b: [providerResult('2')], + c: [providerResult('3')], + }); + registerResultProvider(createProvider('A', providerResults)); + + const { find } = service.start(startDeps()); + const results = find('foo', {}); + + expectObservable(results).toBe('a 24ms b 74ms |', { + a: expectedBatch('1'), + b: expectedBatch('2'), + }); + }); + }); + + it('only returns a given maximum number of results per provider', async () => { + const { registerResultProvider } = service.setup({ + config: createConfig(100), + maxProviderResults: 2, + }); + + getTestScheduler().run(({ expectObservable, hot }) => { + registerResultProvider( + createProvider( + 'A', + hot('a---d-|', { + a: [providerResult('A1'), providerResult('A2')], + d: [providerResult('A3')], + }) + ) + ); + registerResultProvider( + createProvider( + 'B', + hot('-b-c| ', { + b: [providerResult('B1')], + c: [providerResult('B2'), providerResult('B3')], + }) + ) + ); + + const { find } = service.start(startDeps()); + const results = find('foo', {}); + + expectObservable(results).toBe('ab-(c|)', { + a: expectedBatch('A1', 'A2'), + b: expectedBatch('B1'), + c: expectedBatch('B2'), + }); + }); + }); + + it('process the results before returning them', async () => { + const { registerResultProvider } = service.setup({ + config: createConfig(), + }); + + const resultA = providerResult('A', { + type: 'application', + icon: 'appIcon', + score: 42, + title: 'foo', + url: '/foo/bar', + }); + const resultB = providerResult('B', { + type: 'dashboard', + score: 69, + title: 'bar', + url: { path: '/foo', prependBasePath: false }, + }); + + const provider = createProvider('A', of([resultA, resultB])); + registerResultProvider(provider); + + const { find } = service.start(startDeps()); + const batch = await find('foo', {}).pipe(take(1)).toPromise(); + + expect(batch.results).toHaveLength(2); + expect(batch.results[0]).toEqual({ + ...resultA, + url: '/base-path/foo/bar', + }); + expect(batch.results[1]).toEqual({ + ...resultB, + url: '/foo', + }); + }); + + it('emits an error when the license is invalid', async () => { + licenseChecker.getState.mockReturnValue({ valid: false, message: 'expired' }); + + const { registerResultProvider } = service.setup({ + config: createConfig(), + }); + + getTestScheduler().run(({ expectObservable, hot }) => { + const providerResults = hot('a-b-|', { + a: [providerResult('1')], + b: [providerResult('2')], + }); + registerResultProvider(createProvider('A', providerResults)); + + const { find } = service.start(startDeps()); + const results = find('foo', {}); + + expectObservable(results).toBe( + '#', + {}, + GlobalSearchFindError.invalidLicense( + 'GlobalSearch API is disabled because of invalid license state: expired' + ) + ); + }); + }); + }); + }); +}); diff --git a/x-pack/plugins/global_search/public/services/search_service.ts b/x-pack/plugins/global_search/public/services/search_service.ts new file mode 100644 index 0000000000000..68970b75ad975 --- /dev/null +++ b/x-pack/plugins/global_search/public/services/search_service.ts @@ -0,0 +1,164 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { merge, Observable, timer, throwError } from 'rxjs'; +import { map, takeUntil } from 'rxjs/operators'; +import { duration } from 'moment'; +import { i18n } from '@kbn/i18n'; +import { HttpStart } from 'src/core/public'; +import { GlobalSearchProviderResult, GlobalSearchBatchedResults } from '../../common/types'; +import { GlobalSearchFindError } from '../../common/errors'; +import { takeInArray } from '../../common/operators'; +import { processProviderResult } from '../../common/process_result'; +import { ILicenseChecker } from '../../common/license_checker'; +import { GlobalSearchResultProvider } from '../types'; +import { GlobalSearchClientConfigType } from '../config'; +import { GlobalSearchFindOptions } from './types'; +import { getDefaultPreference } from './utils'; +import { fetchServerResults } from './fetch_server_results'; + +/** @public */ +export interface SearchServiceSetup { + /** + * Register a result provider to be used by the search service. + * + * @example + * ```ts + * setupDeps.globalSearch.registerResultProvider({ + * id: 'my_provider', + * find: (term, options) => { + * const resultPromise = myService.search(term, options); + * return from(resultPromise).pipe(takeUntil(options.aborted$); + * }, + * }); + * ``` + * + * @remarks + * As results from providers registered from the client-side API will not be available from the server's `find` API, + * registering result providers from the client should only be done when returning results that would not be retrievable + * from the server-side. In any other situation, prefer registering your provider from the server-side instead. + */ + registerResultProvider(provider: GlobalSearchResultProvider): void; +} + +/** @public */ +export interface SearchServiceStart { + /** + * Perform a search for given `term` and {@link GlobalSearchFindOptions | options}. + * + * @example + * ```ts + * startDeps.globalSearch.find('some term').subscribe({ + * next: ({ results }) => { + * addNewResultsToList(results); + * }, + * error: () => {}, + * complete: () => { + * showAsyncSearchIndicator(false); + * } + * }); + * ``` + * + * @remarks + * Emissions from the resulting observable will only contains **new** results. It is the consumer's + * responsibility to aggregate the emission and sort the results if required. + */ + find(term: string, options: GlobalSearchFindOptions): Observable; +} + +interface SetupDeps { + config: GlobalSearchClientConfigType; + maxProviderResults?: number; +} + +interface StartDeps { + http: HttpStart; + licenseChecker: ILicenseChecker; +} + +const defaultMaxProviderResults = 20; +const mapToUndefined = () => undefined; + +/** @internal */ +export class SearchService { + private readonly providers = new Map(); + private config?: GlobalSearchClientConfigType; + private http?: HttpStart; + private maxProviderResults = defaultMaxProviderResults; + private licenseChecker?: ILicenseChecker; + + setup({ config, maxProviderResults = defaultMaxProviderResults }: SetupDeps): SearchServiceSetup { + this.config = config; + + this.maxProviderResults = maxProviderResults; + + return { + registerResultProvider: (provider) => { + if (this.providers.has(provider.id)) { + throw new Error(`trying to register duplicate provider: ${provider.id}`); + } + this.providers.set(provider.id, provider); + }, + }; + } + + start({ http, licenseChecker }: StartDeps): SearchServiceStart { + this.http = http; + this.licenseChecker = licenseChecker; + + return { + find: (term, options) => this.performFind(term, options), + }; + } + + private performFind(term: string, options: GlobalSearchFindOptions) { + const licenseState = this.licenseChecker!.getState(); + if (!licenseState.valid) { + return throwError( + GlobalSearchFindError.invalidLicense( + i18n.translate('xpack.globalSearch.find.invalidLicenseError', { + defaultMessage: `GlobalSearch API is disabled because of invalid license state: {errorMessage}`, + values: { errorMessage: licenseState.message }, + }) + ) + ); + } + + const timeout = duration(this.config!.search_timeout).asMilliseconds(); + const timeout$ = timer(timeout).pipe(map(mapToUndefined)); + const aborted$ = options.aborted$ ? merge(options.aborted$, timeout$) : timeout$; + const preference = options.preference ?? getDefaultPreference(); + + const providerOptions = { + ...options, + preference, + maxResults: this.maxProviderResults, + aborted$, + }; + + const processResult = (result: GlobalSearchProviderResult) => + processProviderResult(result, this.http!.basePath); + + const serverResults$ = fetchServerResults(this.http!, term, { + preference, + aborted$, + }); + + const providersResults$ = [...this.providers.values()].map((provider) => + provider.find(term, providerOptions).pipe( + takeInArray(this.maxProviderResults), + takeUntil(aborted$), + map((results) => results.map((r) => processResult(r))) + ) + ); + + return merge(...providersResults$, serverResults$).pipe( + map((results) => ({ + results, + })) + ); + } +} diff --git a/x-pack/plugins/global_search/public/services/types.ts b/x-pack/plugins/global_search/public/services/types.ts new file mode 100644 index 0000000000000..fcaa8f0545a6e --- /dev/null +++ b/x-pack/plugins/global_search/public/services/types.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Observable } from 'rxjs'; + +/** + * Options for the server-side {@link GlobalSearchPluginStart.find | find API} + */ +export interface GlobalSearchFindOptions { + /** + * A custom preference token associated with a search 'session' that should be used to get consistent scoring + * when performing calls to ES. Can also be used as a 'session' token for providers returning data from elsewhere + * than an elasticsearch cluster. + * + * If not specified, a random token will be generated and used. The token is stored in the sessionStorage and is guaranteed + * to be consistent during a given http 'session' + */ + preference?: string; + /** + * Optional observable to notify that the associated `find` call should be canceled. + * If/when provided and emitting, the result observable will be completed and no further result emission will be performed. + */ + aborted$?: Observable; +} diff --git a/x-pack/plugins/global_search/public/services/utils.test.ts b/x-pack/plugins/global_search/public/services/utils.test.ts new file mode 100644 index 0000000000000..f69fb1d2fd825 --- /dev/null +++ b/x-pack/plugins/global_search/public/services/utils.test.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { StubBrowserStorage } from '../../../../../src/test_utils/public/stub_browser_storage'; +import { getDefaultPreference } from './utils'; + +describe('getDefaultPreference', () => { + let storage: Storage; + let getItemSpy: jest.SpyInstance; + let setItemSpy: jest.SpyInstance; + + beforeEach(() => { + storage = new StubBrowserStorage(); + getItemSpy = jest.spyOn(storage, 'getItem'); + setItemSpy = jest.spyOn(storage, 'setItem'); + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('returns the value in storage when available', () => { + getItemSpy.mockReturnValue('foo_pref'); + + const pref = getDefaultPreference(storage); + + expect(pref).toEqual('foo_pref'); + expect(getItemSpy).toHaveBeenCalledTimes(1); + expect(setItemSpy).not.toHaveBeenCalled(); + }); + + it('sets the value to the storage and return it when not already present', () => { + getItemSpy.mockReturnValue(null); + + const returnedPref = getDefaultPreference(storage); + + expect(getItemSpy).toHaveBeenCalledTimes(1); + expect(setItemSpy).toHaveBeenCalledTimes(1); + + const storedPref = setItemSpy.mock.calls[0][1]; + + expect(storage.length).toBe(1); + expect(storage.key(0)).toBe('globalSearch:defaultPref'); + expect(storedPref).toEqual(returnedPref); + }); +}); diff --git a/x-pack/plugins/global_search/public/services/utils.ts b/x-pack/plugins/global_search/public/services/utils.ts new file mode 100644 index 0000000000000..45d2ba7d7c210 --- /dev/null +++ b/x-pack/plugins/global_search/public/services/utils.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import uuid from 'uuid'; + +const defaultPrefStorageKey = 'globalSearch:defaultPref'; + +/** + * Returns the default {@link GlobalSearchFindOptions.preference | preference} value. + * + * The implementation is based on the sessionStorage, which ensure the default value for a session/tab will remain the same. + */ +export const getDefaultPreference = (storage: Storage = window.sessionStorage): string => { + let pref = storage.getItem(defaultPrefStorageKey); + if (pref) { + return pref; + } + pref = uuid.v4(); + storage.setItem(defaultPrefStorageKey, pref); + return pref; +}; diff --git a/x-pack/plugins/global_search/public/types.ts b/x-pack/plugins/global_search/public/types.ts new file mode 100644 index 0000000000000..42ef234504d12 --- /dev/null +++ b/x-pack/plugins/global_search/public/types.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Observable } from 'rxjs'; +import { GlobalSearchProviderFindOptions, GlobalSearchProviderResult } from '../common/types'; +import { SearchServiceSetup, SearchServiceStart } from './services'; + +export type GlobalSearchPluginSetup = Pick; +export type GlobalSearchPluginStart = Pick; + +/** + * GlobalSearch result provider, to be registered using the {@link GlobalSearchPluginSetup | global search API} + */ +export interface GlobalSearchResultProvider { + /** + * id of the provider + */ + id: string; + /** + * Method that should return an observable used to emit new results from the provider. + * + * See {@GlobalSearchProviderResult | the result type} for the expected result structure. + * + * @example + * ```ts + * // returning all results in a single batch + * setupDeps.globalSearch.registerResultProvider({ + * id: 'my_provider', + * find: (term, { aborted$, preference, maxResults }, context) => { + * const resultPromise = myService.search(term, { preference, maxResults }, context.core.savedObjects.client); + * return from(resultPromise).pipe(takeUntil(aborted$)); + * }, + * }); + * ``` + */ + find( + term: string, + options: GlobalSearchProviderFindOptions + ): Observable; +} diff --git a/x-pack/plugins/global_search/server/config.ts b/x-pack/plugins/global_search/server/config.ts new file mode 100644 index 0000000000000..33ff45595b912 --- /dev/null +++ b/x-pack/plugins/global_search/server/config.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { PluginConfigDescriptor } from 'kibana/server'; + +const configSchema = schema.object({ + search_timeout: schema.duration({ defaultValue: '30s' }), +}); + +export type GlobalSearchConfigType = TypeOf; + +export const config: PluginConfigDescriptor = { + schema: configSchema, + exposeToBrowser: { + search_timeout: true, + }, +}; diff --git a/x-pack/plugins/global_search/server/index.ts b/x-pack/plugins/global_search/server/index.ts new file mode 100644 index 0000000000000..82f7c80dca552 --- /dev/null +++ b/x-pack/plugins/global_search/server/index.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { PluginInitializer } from 'src/core/server'; +import { + GlobalSearchPlugin, + GlobalSearchPluginSetupDeps, + GlobalSearchPluginStartDeps, +} from './plugin'; +import { GlobalSearchPluginSetup, GlobalSearchPluginStart } from './types'; + +export const plugin: PluginInitializer< + GlobalSearchPluginSetup, + GlobalSearchPluginStart, + GlobalSearchPluginSetupDeps, + GlobalSearchPluginStartDeps +> = (context) => new GlobalSearchPlugin(context); + +export { config } from './config'; + +export { + GlobalSearchBatchedResults, + GlobalSearchProviderFindOptions, + GlobalSearchProviderResult, + GlobalSearchProviderResultUrl, + GlobalSearchResult, +} from '../common/types'; +export { + GlobalSearchFindOptions, + GlobalSearchProviderContext, + GlobalSearchPluginStart, + GlobalSearchPluginSetup, + GlobalSearchResultProvider, + RouteHandlerGlobalSearchContext, +} from './types'; diff --git a/x-pack/plugins/global_search/server/mocks.ts b/x-pack/plugins/global_search/server/mocks.ts new file mode 100644 index 0000000000000..8a189a5701708 --- /dev/null +++ b/x-pack/plugins/global_search/server/mocks.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { of } from 'rxjs'; +import { + GlobalSearchPluginSetup, + GlobalSearchPluginStart, + RouteHandlerGlobalSearchContext, +} from './types'; +import { searchServiceMock } from './services/search_service.mock'; + +const createSetupMock = (): jest.Mocked => { + const searchMock = searchServiceMock.createSetupContract(); + + return { + registerResultProvider: searchMock.registerResultProvider, + }; +}; + +const createStartMock = (): jest.Mocked => { + const searchMock = searchServiceMock.createStartContract(); + + return { + find: searchMock.find, + }; +}; + +const createRouteHandlerContextMock = (): jest.Mocked => { + const contextMock = { + find: jest.fn(), + }; + + contextMock.find.mockReturnValue(of([])); + + return contextMock; +}; + +export const globalSearchPluginMock = { + createSetupContract: createSetupMock, + createStartContract: createStartMock, + createRouteHandlerContext: createRouteHandlerContextMock, +}; diff --git a/x-pack/plugins/global_search/server/plugin.test.mocks.ts b/x-pack/plugins/global_search/server/plugin.test.mocks.ts new file mode 100644 index 0000000000000..1223b1ec20389 --- /dev/null +++ b/x-pack/plugins/global_search/server/plugin.test.mocks.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const registerRoutesMock = jest.fn(); +jest.doMock('./routes', () => ({ + registerRoutes: registerRoutesMock, +})); diff --git a/x-pack/plugins/global_search/server/plugin.test.ts b/x-pack/plugins/global_search/server/plugin.test.ts new file mode 100644 index 0000000000000..e654dbfdc158a --- /dev/null +++ b/x-pack/plugins/global_search/server/plugin.test.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { registerRoutesMock } from './plugin.test.mocks'; + +import { coreMock } from '../../../../src/core/server/mocks'; +import { GlobalSearchPlugin } from './plugin'; + +describe('GlobalSearchPlugin', () => { + let plugin: GlobalSearchPlugin; + + beforeEach(() => { + plugin = new GlobalSearchPlugin(coreMock.createPluginInitializerContext()); + }); + + it('registers routes during `setup`', async () => { + await plugin.setup(coreMock.createSetup()); + expect(registerRoutesMock).toHaveBeenCalledTimes(1); + }); + + it('registers the globalSearch route handler context', async () => { + const coreSetup = coreMock.createSetup(); + await plugin.setup(coreSetup); + expect(coreSetup.http.registerRouteHandlerContext).toHaveBeenCalledTimes(1); + expect(coreSetup.http.registerRouteHandlerContext).toHaveBeenCalledWith( + 'globalSearch', + expect.any(Function) + ); + }); +}); diff --git a/x-pack/plugins/global_search/server/plugin.ts b/x-pack/plugins/global_search/server/plugin.ts new file mode 100644 index 0000000000000..87e7f96b34c0c --- /dev/null +++ b/x-pack/plugins/global_search/server/plugin.ts @@ -0,0 +1,86 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Observable } from 'rxjs'; +import { take } from 'rxjs/operators'; +import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'src/core/server'; +import { LicensingPluginStart } from '../../licensing/server'; +import { LicenseChecker, ILicenseChecker } from '../common/license_checker'; +import { SearchService, SearchServiceStart } from './services'; +import { registerRoutes } from './routes'; +import { + GlobalSearchPluginSetup, + GlobalSearchPluginStart, + RouteHandlerGlobalSearchContext, +} from './types'; +import { GlobalSearchConfigType } from './config'; + +declare module 'src/core/server' { + interface RequestHandlerContext { + globalSearch?: RouteHandlerGlobalSearchContext; + } +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface GlobalSearchPluginSetupDeps {} +export interface GlobalSearchPluginStartDeps { + licensing: LicensingPluginStart; +} + +export class GlobalSearchPlugin + implements + Plugin< + GlobalSearchPluginSetup, + GlobalSearchPluginStart, + GlobalSearchPluginSetupDeps, + GlobalSearchPluginStartDeps + > { + private readonly config$: Observable; + private readonly searchService = new SearchService(); + private searchServiceStart?: SearchServiceStart; + private licenseChecker?: ILicenseChecker; + + constructor(context: PluginInitializerContext) { + this.config$ = context.config.create(); + } + + public async setup(core: CoreSetup<{}, GlobalSearchPluginStart>) { + const config = await this.config$.pipe(take(1)).toPromise(); + const { registerResultProvider } = this.searchService.setup({ + basePath: core.http.basePath, + config, + }); + + registerRoutes(core.http.createRouter()); + + core.http.registerRouteHandlerContext('globalSearch', (_, req) => { + return { + find: (term, options) => this.searchServiceStart!.find(term, options, req), + }; + }); + + return { + registerResultProvider, + }; + } + + public start(core: CoreStart, { licensing }: GlobalSearchPluginStartDeps) { + this.licenseChecker = new LicenseChecker(licensing.license$); + this.searchServiceStart = this.searchService.start({ + core, + licenseChecker: this.licenseChecker, + }); + return { + find: this.searchServiceStart.find, + }; + } + + public stop() { + if (this.licenseChecker) { + this.licenseChecker.clean(); + } + } +} diff --git a/x-pack/plugins/global_search/server/routes/find.ts b/x-pack/plugins/global_search/server/routes/find.ts new file mode 100644 index 0000000000000..a9063abda0e3e --- /dev/null +++ b/x-pack/plugins/global_search/server/routes/find.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { reduce, map } from 'rxjs/operators'; +import { schema } from '@kbn/config-schema'; +import { IRouter } from 'src/core/server'; +import { GlobalSearchFindError } from '../../common/errors'; + +export const registerInternalFindRoute = (router: IRouter) => { + router.post( + { + path: '/internal/global_search/find', + validate: { + body: schema.object({ + term: schema.string(), + options: schema.maybe( + schema.object({ + preference: schema.maybe(schema.string()), + }) + ), + }), + }, + }, + async (ctx, req, res) => { + const { term, options } = req.body; + try { + const allResults = await ctx + .globalSearch!.find(term, { ...options, aborted$: req.events.aborted$ }) + .pipe( + map((batch) => batch.results), + reduce((acc, results) => [...acc, ...results]) + ) + .toPromise(); + return res.ok({ + body: { + results: allResults, + }, + }); + } catch (e) { + if (e instanceof GlobalSearchFindError && e.type === 'invalid-license') { + return res.forbidden({ body: e.message }); + } + throw e; + } + } + ); +}; diff --git a/x-pack/plugins/global_search/server/routes/index.test.ts b/x-pack/plugins/global_search/server/routes/index.test.ts new file mode 100644 index 0000000000000..64675bc13cb1c --- /dev/null +++ b/x-pack/plugins/global_search/server/routes/index.test.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { httpServiceMock } from '../../../../../src/core/server/mocks'; +import { registerRoutes } from './index'; + +describe('registerRoutes', () => { + it('foo', () => { + const router = httpServiceMock.createRouter(); + + registerRoutes(router); + + expect(router.post).toHaveBeenCalledTimes(1); + + expect(router.post).toHaveBeenCalledWith( + expect.objectContaining({ + path: '/internal/global_search/find', + }), + expect.any(Function) + ); + + expect(router.get).toHaveBeenCalledTimes(0); + expect(router.delete).toHaveBeenCalledTimes(0); + expect(router.put).toHaveBeenCalledTimes(0); + }); +}); diff --git a/x-pack/plugins/global_search/server/routes/index.ts b/x-pack/plugins/global_search/server/routes/index.ts new file mode 100644 index 0000000000000..7840b95614993 --- /dev/null +++ b/x-pack/plugins/global_search/server/routes/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IRouter } from 'src/core/server'; +import { registerInternalFindRoute } from './find'; + +export const registerRoutes = (router: IRouter) => { + registerInternalFindRoute(router); +}; diff --git a/x-pack/plugins/global_search/server/routes/integration_tests/find.test.ts b/x-pack/plugins/global_search/server/routes/integration_tests/find.test.ts new file mode 100644 index 0000000000000..878e4ac896b96 --- /dev/null +++ b/x-pack/plugins/global_search/server/routes/integration_tests/find.test.ts @@ -0,0 +1,131 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { of, throwError } from 'rxjs'; +import supertest from 'supertest'; +import { UnwrapPromise } from '@kbn/utility-types'; +import { setupServer } from '../../../../../../src/core/server/test_utils'; +import { GlobalSearchResult, GlobalSearchBatchedResults } from '../../../common/types'; +import { GlobalSearchFindError } from '../../../common/errors'; +import { globalSearchPluginMock } from '../../mocks'; +import { registerInternalFindRoute } from '../find'; + +type setupServerReturn = UnwrapPromise>; +const pluginId = Symbol('globalSearch'); + +const createResult = (id: string): GlobalSearchResult => ({ + id, + title: id, + type: 'test', + url: `/app/test/${id}`, + score: 42, +}); + +const createBatch = (...ids: string[]): GlobalSearchBatchedResults => ({ + results: ids.map(createResult), +}); + +const expectedResults = (...ids: string[]) => ids.map((id) => expect.objectContaining({ id })); + +describe('POST /internal/global_search/find', () => { + let server: setupServerReturn['server']; + let httpSetup: setupServerReturn['httpSetup']; + let globalSearchHandlerContext: ReturnType; + + beforeEach(async () => { + ({ server, httpSetup } = await setupServer(pluginId)); + + globalSearchHandlerContext = globalSearchPluginMock.createRouteHandlerContext(); + httpSetup.registerRouteHandlerContext( + pluginId, + 'globalSearch', + () => globalSearchHandlerContext + ); + + const router = httpSetup.createRouter('/'); + + registerInternalFindRoute(router); + + await server.start(); + }); + + afterEach(async () => { + await server.stop(); + }); + + it('calls the handler context with correct parameters', async () => { + await supertest(httpSetup.server.listener) + .post('/internal/global_search/find') + .send({ + term: 'search', + options: { + preference: 'custom-pref', + }, + }) + .expect(200); + + expect(globalSearchHandlerContext.find).toHaveBeenCalledTimes(1); + expect(globalSearchHandlerContext.find).toHaveBeenCalledWith('search', { + preference: 'custom-pref', + aborted$: expect.any(Object), + }); + }); + + it('returns all the results returned from the service', async () => { + globalSearchHandlerContext.find.mockReturnValue( + of(createBatch('1', '2'), createBatch('3', '4')) + ); + + const response = await supertest(httpSetup.server.listener) + .post('/internal/global_search/find') + .send({ + term: 'search', + }) + .expect(200); + + expect(response.body).toEqual({ + results: expectedResults('1', '2', '3', '4'), + }); + }); + + it('returns a 403 when the observable throws an invalid-license error', async () => { + globalSearchHandlerContext.find.mockReturnValue( + throwError(GlobalSearchFindError.invalidLicense('invalid-license-message')) + ); + + const response = await supertest(httpSetup.server.listener) + .post('/internal/global_search/find') + .send({ + term: 'search', + }) + .expect(403); + + expect(response.body).toEqual( + expect.objectContaining({ + message: 'invalid-license-message', + statusCode: 403, + }) + ); + }); + + it('returns the default error when the observable throws any other error', async () => { + globalSearchHandlerContext.find.mockReturnValue(throwError('any-error')); + + const response = await supertest(httpSetup.server.listener) + .post('/internal/global_search/find') + .send({ + term: 'search', + }) + .expect(500); + + expect(response.body).toEqual( + expect.objectContaining({ + message: 'An internal server error occurred.', + statusCode: 500, + }) + ); + }); +}); diff --git a/x-pack/plugins/global_search/server/services/context.test.ts b/x-pack/plugins/global_search/server/services/context.test.ts new file mode 100644 index 0000000000000..397a1ea170349 --- /dev/null +++ b/x-pack/plugins/global_search/server/services/context.test.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { httpServerMock, coreMock } from '../../../../../src/core/server/mocks'; +import { getContextFactory } from './context'; + +describe('getContextFactory', () => { + it('returns a GlobalSearchProviderContext bound to the request', () => { + const coreStart = coreMock.createStart(); + const request = httpServerMock.createKibanaRequest(); + + const factory = getContextFactory(coreStart); + const context = factory(request); + + expect(coreStart.savedObjects.getScopedClient).toHaveBeenCalledTimes(1); + expect(coreStart.savedObjects.getScopedClient).toHaveBeenCalledWith(request); + + expect(coreStart.savedObjects.getTypeRegistry).toHaveBeenCalledTimes(1); + + expect(coreStart.elasticsearch.legacy.client.asScoped).toHaveBeenCalledTimes(1); + expect(coreStart.elasticsearch.legacy.client.asScoped).toHaveBeenCalledWith(request); + + const soClient = coreStart.savedObjects.getScopedClient.mock.results[0].value; + expect(coreStart.uiSettings.asScopedToClient).toHaveBeenCalledTimes(1); + expect(coreStart.uiSettings.asScopedToClient).toHaveBeenCalledWith(soClient); + + expect(context).toEqual({ + core: { + savedObjects: expect.any(Object), + elasticsearch: expect.any(Object), + uiSettings: expect.any(Object), + }, + }); + }); +}); diff --git a/x-pack/plugins/global_search/server/services/context.ts b/x-pack/plugins/global_search/server/services/context.ts new file mode 100644 index 0000000000000..b15deccaae018 --- /dev/null +++ b/x-pack/plugins/global_search/server/services/context.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { CoreStart, KibanaRequest } from 'src/core/server'; +import { GlobalSearchProviderContext } from '../types'; + +export type GlobalSearchContextFactory = (request: KibanaRequest) => GlobalSearchProviderContext; + +/** + * {@link GlobalSearchProviderContext | context} factory + */ +export const getContextFactory = (coreStart: CoreStart) => ( + request: KibanaRequest +): GlobalSearchProviderContext => { + const soClient = coreStart.savedObjects.getScopedClient(request); + return { + core: { + savedObjects: { + client: soClient, + typeRegistry: coreStart.savedObjects.getTypeRegistry(), + }, + elasticsearch: { + legacy: { + client: coreStart.elasticsearch.legacy.client.asScoped(request), + }, + }, + uiSettings: { + client: coreStart.uiSettings.asScopedToClient(soClient), + }, + }, + }; +}; diff --git a/x-pack/plugins/global_search/server/services/index.ts b/x-pack/plugins/global_search/server/services/index.ts new file mode 100644 index 0000000000000..cee5b24d2f588 --- /dev/null +++ b/x-pack/plugins/global_search/server/services/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { SearchService, SearchServiceSetup, SearchServiceStart } from './search_service'; diff --git a/x-pack/plugins/global_search/server/services/search_service.mock.ts b/x-pack/plugins/global_search/server/services/search_service.mock.ts new file mode 100644 index 0000000000000..eca69148288b9 --- /dev/null +++ b/x-pack/plugins/global_search/server/services/search_service.mock.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SearchServiceSetup, SearchServiceStart } from './search_service'; +import { of } from 'rxjs'; + +const createSetupMock = (): jest.Mocked => { + return { + registerResultProvider: jest.fn(), + }; +}; + +const createStartMock = (): jest.Mocked => { + const mock = { + find: jest.fn(), + }; + mock.find.mockReturnValue(of({ results: [] })); + + return mock; +}; + +export const searchServiceMock = { + createSetupContract: createSetupMock, + createStartContract: createStartMock, +}; diff --git a/x-pack/plugins/global_search/server/services/search_service.test.ts b/x-pack/plugins/global_search/server/services/search_service.test.ts new file mode 100644 index 0000000000000..fd705b4286680 --- /dev/null +++ b/x-pack/plugins/global_search/server/services/search_service.test.ts @@ -0,0 +1,323 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Observable, of } from 'rxjs'; +import { take } from 'rxjs/operators'; +import { TestScheduler } from 'rxjs/testing'; +import { duration } from 'moment'; +import { httpServiceMock, httpServerMock, coreMock } from '../../../../../src/core/server/mocks'; +import { licenseCheckerMock } from '../../common/license_checker.mock'; +import { GlobalSearchProviderResult } from '../../common/types'; +import { GlobalSearchFindError } from '../../common/errors'; +import { GlobalSearchConfigType } from '../config'; +import { GlobalSearchResultProvider } from '../types'; +import { SearchService } from './search_service'; + +const getTestScheduler = () => + new TestScheduler((actual, expected) => { + expect(actual).toEqual(expected); + }); + +describe('SearchService', () => { + let service: SearchService; + let basePath: ReturnType; + let coreStart: ReturnType; + let licenseChecker: ReturnType; + let request: ReturnType; + + const createConfig = (timeoutMs: number = 30000): GlobalSearchConfigType => { + return { + search_timeout: duration(timeoutMs), + }; + }; + + const createProvider = ( + id: string, + source: Observable = of([]) + ): jest.Mocked => ({ + id, + find: jest.fn().mockImplementation((term, options, context) => source), + }); + + const expectedResult = (id: string) => expect.objectContaining({ id }); + + const expectedBatch = (...ids: string[]) => ({ + results: ids.map((id) => expectedResult(id)), + }); + + const result = ( + id: string, + parts: Partial = {} + ): GlobalSearchProviderResult => ({ + title: id, + type: 'test', + url: '/foo/bar', + score: 100, + ...parts, + id, + }); + + beforeEach(() => { + service = new SearchService(); + basePath = httpServiceMock.createBasePath(); + basePath.prepend.mockImplementation((path) => `/base-path${path}`); + coreStart = coreMock.createStart(); + licenseChecker = licenseCheckerMock.create(); + }); + + describe('#setup()', () => { + describe('#registerResultProvider()', () => { + it('throws when trying to register the same provider twice', () => { + const { registerResultProvider } = service.setup({ + config: createConfig(), + basePath, + }); + + const provider = createProvider('A'); + registerResultProvider(provider); + expect(() => { + registerResultProvider(provider); + }).toThrowErrorMatchingInlineSnapshot(`"trying to register duplicate provider: A"`); + }); + }); + }); + + describe('#start()', () => { + describe('#find()', () => { + it('calls the provider with the correct parameters', () => { + const { registerResultProvider } = service.setup({ + config: createConfig(), + basePath, + }); + + const provider = createProvider('A'); + registerResultProvider(provider); + + const { find } = service.start({ core: coreStart, licenseChecker }); + find('foobar', { preference: 'pref' }, request); + + expect(provider.find).toHaveBeenCalledTimes(1); + expect(provider.find).toHaveBeenCalledWith( + 'foobar', + expect.objectContaining({ preference: 'pref' }), + expect.objectContaining({ core: expect.any(Object) }) + ); + }); + + it('return the results from the provider', async () => { + const { registerResultProvider } = service.setup({ + config: createConfig(), + basePath, + }); + + getTestScheduler().run(({ expectObservable, hot }) => { + const providerResults = hot('a-b-|', { + a: [result('1')], + b: [result('2')], + }); + registerResultProvider(createProvider('A', providerResults)); + + const { find } = service.start({ core: coreStart, licenseChecker }); + const results = find('foo', {}, request); + + expectObservable(results).toBe('a-b-|', { + a: expectedBatch('1'), + b: expectedBatch('2'), + }); + }); + }); + + it('handles multiple providers', async () => { + const { registerResultProvider } = service.setup({ + config: createConfig(), + basePath, + }); + + getTestScheduler().run(({ expectObservable, hot }) => { + registerResultProvider( + createProvider( + 'A', + hot('a---d-|', { + a: [result('A1'), result('A2')], + d: [result('A3')], + }) + ) + ); + registerResultProvider( + createProvider( + 'B', + hot('-b-c| ', { + b: [result('B1')], + c: [result('B2'), result('B3')], + }) + ) + ); + + const { find } = service.start({ core: coreStart, licenseChecker }); + const results = find('foo', {}, request); + + expectObservable(results).toBe('ab-cd-|', { + a: expectedBatch('A1', 'A2'), + b: expectedBatch('B1'), + c: expectedBatch('B2', 'B3'), + d: expectedBatch('A3'), + }); + }); + }); + + it('handles the `aborted$` option', async () => { + const { registerResultProvider } = service.setup({ + config: createConfig(), + basePath, + }); + + getTestScheduler().run(({ expectObservable, hot }) => { + const providerResults = hot('--a---(b|)', { + a: [result('1')], + b: [result('2')], + }); + registerResultProvider(createProvider('A', providerResults)); + + const aborted$ = hot('----a--|', { a: undefined }); + + const { find } = service.start({ core: coreStart, licenseChecker }); + const results = find('foo', { aborted$ }, request); + + expectObservable(results).toBe('--a-|', { + a: expectedBatch('1'), + }); + }); + }); + + it('respects the timeout duration', async () => { + const { registerResultProvider } = service.setup({ + config: createConfig(100), + basePath, + }); + + getTestScheduler().run(({ expectObservable, hot }) => { + const providerResults = hot('a 24ms b 100ms (c|)', { + a: [result('1')], + b: [result('2')], + c: [result('3')], + }); + registerResultProvider(createProvider('A', providerResults)); + + const { find } = service.start({ core: coreStart, licenseChecker }); + const results = find('foo', {}, request); + + expectObservable(results).toBe('a 24ms b 74ms |', { + a: expectedBatch('1'), + b: expectedBatch('2'), + }); + }); + }); + + it('only returns a given maximum number of results per provider', async () => { + const { registerResultProvider } = service.setup({ + config: createConfig(100), + basePath, + maxProviderResults: 2, + }); + + getTestScheduler().run(({ expectObservable, hot }) => { + registerResultProvider( + createProvider( + 'A', + hot('a---d-|', { + a: [result('A1'), result('A2')], + d: [result('A3')], + }) + ) + ); + registerResultProvider( + createProvider( + 'B', + hot('-b-c| ', { + b: [result('B1')], + c: [result('B2'), result('B3')], + }) + ) + ); + + const { find } = service.start({ core: coreStart, licenseChecker }); + const results = find('foo', {}, request); + + expectObservable(results).toBe('ab-(c|)', { + a: expectedBatch('A1', 'A2'), + b: expectedBatch('B1'), + c: expectedBatch('B2'), + }); + }); + }); + + it('process the results before returning them', async () => { + const { registerResultProvider } = service.setup({ + config: createConfig(), + basePath, + }); + + const resultA = result('A', { + type: 'application', + icon: 'appIcon', + score: 42, + title: 'foo', + url: '/foo/bar', + }); + const resultB = result('B', { + type: 'dashboard', + score: 69, + title: 'bar', + url: { path: '/foo', prependBasePath: false }, + }); + + const provider = createProvider('A', of([resultA, resultB])); + registerResultProvider(provider); + + const { find } = service.start({ core: coreStart, licenseChecker }); + const batch = await find('foo', {}, request).pipe(take(1)).toPromise(); + + expect(batch.results).toHaveLength(2); + expect(batch.results[0]).toEqual({ + ...resultA, + url: '/base-path/foo/bar', + }); + expect(batch.results[1]).toEqual({ + ...resultB, + url: '/foo', + }); + }); + + it('emits an error when the license is invalid', async () => { + licenseChecker.getState.mockReturnValue({ valid: false, message: 'expired' }); + + const { registerResultProvider } = service.setup({ + config: createConfig(), + basePath, + }); + + getTestScheduler().run(({ expectObservable, hot }) => { + const providerResults = hot('a-b-|', { + a: [result('1')], + b: [result('2')], + }); + registerResultProvider(createProvider('A', providerResults)); + + const { find } = service.start({ core: coreStart, licenseChecker }); + const results = find('foo', {}, request); + + expectObservable(results).toBe( + '#', + {}, + GlobalSearchFindError.invalidLicense( + 'GlobalSearch API is disabled because of invalid license state: expired' + ) + ); + }); + }); + }); + }); +}); diff --git a/x-pack/plugins/global_search/server/services/search_service.ts b/x-pack/plugins/global_search/server/services/search_service.ts new file mode 100644 index 0000000000000..12eada2a1385e --- /dev/null +++ b/x-pack/plugins/global_search/server/services/search_service.ts @@ -0,0 +1,162 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Observable, timer, merge, throwError } from 'rxjs'; +import { map, takeUntil } from 'rxjs/operators'; +import { i18n } from '@kbn/i18n'; +import { KibanaRequest, CoreStart, IBasePath } from 'src/core/server'; +import { GlobalSearchProviderResult, GlobalSearchBatchedResults } from '../../common/types'; +import { GlobalSearchFindError } from '../../common/errors'; +import { takeInArray } from '../../common/operators'; +import { ILicenseChecker } from '../../common/license_checker'; + +import { processProviderResult } from '../../common/process_result'; +import { GlobalSearchConfigType } from '../config'; +import { getContextFactory, GlobalSearchContextFactory } from './context'; +import { GlobalSearchResultProvider, GlobalSearchFindOptions } from '../types'; + +/** @public */ +export interface SearchServiceSetup { + /** + * Register a result provider to be used by the search service. + * + * @example + * ```ts + * setupDeps.globalSearch.registerResultProvider({ + * id: 'my_provider', + * find: (term, options, context) => { + * const resultPromise = myService.search(term, options, context.core.savedObjects.client); + * return from(resultPromise).pipe(takeUntil(options.aborted$); + * }, + * }); + * ``` + */ + registerResultProvider(provider: GlobalSearchResultProvider): void; +} + +/** @public */ +export interface SearchServiceStart { + /** + * Perform a search for given `term` and {@link GlobalSearchFindOptions | options}. + * + * @example + * ```ts + * startDeps.globalSearch.find('some term').subscribe({ + * next: ({ results }) => { + * addNewResultsToList(results); + * }, + * error: () => {}, + * complete: () => { + * showAsyncSearchIndicator(false); + * } + * }); + * ``` + * + * @remarks + * - Emissions from the resulting observable will only contains **new** results. It is the consumer + * responsibility to aggregate the emission and sort the results if required. + * - Results from the client-side registered providers will not available when performing a search + * from the server-side `find` API. + */ + find( + term: string, + options: GlobalSearchFindOptions, + request: KibanaRequest + ): Observable; +} + +interface SetupDeps { + basePath: IBasePath; + config: GlobalSearchConfigType; + maxProviderResults?: number; +} + +interface StartDeps { + core: CoreStart; + licenseChecker: ILicenseChecker; +} + +const defaultMaxProviderResults = 20; +const mapToUndefined = () => undefined; + +/** @internal */ +export class SearchService { + private readonly providers = new Map(); + private basePath?: IBasePath; + private config?: GlobalSearchConfigType; + private contextFactory?: GlobalSearchContextFactory; + private licenseChecker?: ILicenseChecker; + private maxProviderResults = defaultMaxProviderResults; + + setup({ + basePath, + config, + maxProviderResults = defaultMaxProviderResults, + }: SetupDeps): SearchServiceSetup { + this.basePath = basePath; + this.config = config; + this.maxProviderResults = maxProviderResults; + + return { + registerResultProvider: (provider) => { + if (this.providers.has(provider.id)) { + throw new Error(`trying to register duplicate provider: ${provider.id}`); + } + this.providers.set(provider.id, provider); + }, + }; + } + + start({ core, licenseChecker }: StartDeps): SearchServiceStart { + this.licenseChecker = licenseChecker; + this.contextFactory = getContextFactory(core); + return { + find: (term, options, request) => this.performFind(term, options, request), + }; + } + + private performFind(term: string, options: GlobalSearchFindOptions, request: KibanaRequest) { + const licenseState = this.licenseChecker!.getState(); + if (!licenseState.valid) { + return throwError( + GlobalSearchFindError.invalidLicense( + i18n.translate('xpack.globalSearch.find.invalidLicenseError', { + defaultMessage: `GlobalSearch API is disabled because of invalid license state: {errorMessage}`, + values: { errorMessage: licenseState.message }, + }) + ) + ); + } + + const context = this.contextFactory!(request); + + const timeout$ = timer(this.config!.search_timeout.asMilliseconds()).pipe(map(mapToUndefined)); + const aborted$ = options.aborted$ ? merge(options.aborted$, timeout$) : timeout$; + const providerOptions = { + ...options, + preference: options.preference ?? 'default', + maxResults: this.maxProviderResults, + aborted$, + }; + + const processResult = (result: GlobalSearchProviderResult) => + processProviderResult(result, this.basePath!); + + const providersResults$ = [...this.providers.values()].map((provider) => + provider.find(term, providerOptions, context).pipe( + takeInArray(this.maxProviderResults), + takeUntil(aborted$), + map((results) => results.map((r) => processResult(r))) + ) + ); + + return merge(...providersResults$).pipe( + map((results) => ({ + results, + })) + ); + } +} diff --git a/x-pack/plugins/global_search/server/types.ts b/x-pack/plugins/global_search/server/types.ts new file mode 100644 index 0000000000000..eca4aff366883 --- /dev/null +++ b/x-pack/plugins/global_search/server/types.ts @@ -0,0 +1,110 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Observable } from 'rxjs'; +import { + ISavedObjectTypeRegistry, + IScopedClusterClient, + IUiSettingsClient, + SavedObjectsClientContract, +} from 'src/core/server'; +import { + GlobalSearchBatchedResults, + GlobalSearchProviderFindOptions, + GlobalSearchProviderResult, +} from '../common/types'; +import { SearchServiceSetup, SearchServiceStart } from './services'; + +export type GlobalSearchPluginSetup = Pick; +export type GlobalSearchPluginStart = Pick; + +/** + * globalSearch route handler context. + * + * @public + */ +export interface RouteHandlerGlobalSearchContext { + /** + * See {@link SearchServiceStart.find | the find API} + */ + find(term: string, options: GlobalSearchFindOptions): Observable; +} + +/** + * Context passed to server-side {@GlobalSearchResultProvider | result provider}'s `find` method. + * + * @public + */ +export interface GlobalSearchProviderContext { + core: { + savedObjects: { + client: SavedObjectsClientContract; + typeRegistry: ISavedObjectTypeRegistry; + }; + elasticsearch: { + legacy: { + client: IScopedClusterClient; + }; + }; + uiSettings: { + client: IUiSettingsClient; + }; + }; +} + +/** + * Options for the server-side {@link GlobalSearchPluginStart.find | find API} + * + * @public + */ +export interface GlobalSearchFindOptions { + /** + * A custom preference token associated with a search 'session' that should be used to get consistent scoring + * when performing calls to ES. Can also be used as a 'session' token for providers returning data from elsewhere + * than an elasticsearch cluster. + * If not specified, a random token will be generated and used. + */ + preference?: string; + /** + * Optional observable to notify that the associated `find` call should be canceled. + * If/when provided and emitting, no further result emission will be performed and the result observable will be completed. + */ + aborted$?: Observable; +} + +/** + * GlobalSearch result provider, to be registered using the {@link GlobalSearchPluginSetup | global search API} + * + * @public + */ +export interface GlobalSearchResultProvider { + /** + * id of the provider + */ + id: string; + /** + * Method that should return an observable used to emit new results from the provider. + * + * See {@GlobalSearchProviderResult | the result type} for the expected result structure. + * + * @example + * ```ts + * // returning all results in a single batch + * setupDeps.globalSearch.registerResultProvider({ + * id: 'my_provider', + * find: (term, { aborted$, preference, maxResults }, context) => { + * const resultPromise = myService.search(term, { preference, maxResults }, context.core.savedObjects.client); + * return from(resultPromise).pipe(takeUntil(aborted$)); + * }, + * }); + * ``` + */ + find( + term: string, + options: GlobalSearchProviderFindOptions, + context: GlobalSearchProviderContext + ): Observable; +} diff --git a/x-pack/plugins/graph/server/routes/search.ts b/x-pack/plugins/graph/server/routes/search.ts index ffca273d66c71..645e6b520013f 100644 --- a/x-pack/plugins/graph/server/routes/search.ts +++ b/x-pack/plugins/graph/server/routes/search.ts @@ -7,6 +7,7 @@ import { IRouter } from 'kibana/server'; import { schema } from '@kbn/config-schema'; import { LicenseState, verifyApiAccess } from '../lib/license_state'; +import { UI_SETTINGS } from '../../../../../src/plugins/data/server'; export function registerSearchRoute({ router, @@ -41,7 +42,7 @@ export function registerSearchRoute({ response ) => { verifyApiAccess(licenseState); - const includeFrozen = await uiSettings.get('search:includeFrozen'); + const includeFrozen = await uiSettings.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); try { return response.ok({ body: { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/min_age_input.js b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/min_age_input.js index bfe1bbb04338c..28bc8671f29e2 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/min_age_input.js +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/min_age_input.js @@ -140,6 +140,41 @@ export const MinAgeInput = (props) => { defaultMessage: 'hours from index creation', } ); + + minutesOptionLabel = i18n.translate( + 'xpack.indexLifecycleMgmt.editPolicy.creationMinutesOptionLabel', + { + defaultMessage: 'minutes from index creation', + } + ); + + secondsOptionLabel = i18n.translate( + 'xpack.indexLifecycleMgmt.editPolicy.creationSecondsOptionLabel', + { + defaultMessage: 'seconds from index creation', + } + ); + + millisecondsOptionLabel = i18n.translate( + 'xpack.indexLifecycleMgmt.editPolicy.creationMilliSecondsOptionLabel', + { + defaultMessage: 'milliseconds from index creation', + } + ); + + microsecondsOptionLabel = i18n.translate( + 'xpack.indexLifecycleMgmt.editPolicy.creationMicroSecondsOptionLabel', + { + defaultMessage: 'microseconds from index creation', + } + ); + + nanosecondsOptionLabel = i18n.translate( + 'xpack.indexLifecycleMgmt.editPolicy.creationNanoSecondsOptionLabel', + { + defaultMessage: 'nanoseconds from index creation', + } + ); } return ( diff --git a/x-pack/plugins/index_lifecycle_management/public/application/store/selectors/lifecycle.js b/x-pack/plugins/index_lifecycle_management/public/application/store/selectors/lifecycle.js index 789de0f528b1b..03538fad9aa83 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/store/selectors/lifecycle.js +++ b/x-pack/plugins/index_lifecycle_management/public/application/store/selectors/lifecycle.js @@ -270,7 +270,9 @@ export const getLifecycle = (state) => { if (phaseName === PHASE_DELETE) { accum[phaseName].actions = { ...accum[phaseName].actions, - delete: {}, + delete: { + ...accum[phaseName].actions.delete, + }, }; } } diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts index 2eb635e19be48..7bf3f96e2b2ef 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts @@ -67,7 +67,7 @@ const warmPhaseSchema = schema.maybe( actions: schema.object({ set_priority: setPrioritySchema, unfollow: unfollowSchema, - read_only: schema.maybe(schema.object({})), // Readonly has no options + readonly: schema.maybe(schema.object({})), // Readonly has no options allocate: allocateSchema, shrink: schema.maybe( schema.object({ @@ -91,6 +91,11 @@ const coldPhaseSchema = schema.maybe( unfollow: unfollowSchema, allocate: allocateSchema, freeze: schema.maybe(schema.object({})), // Freeze has no options + searchable_snapshot: schema.maybe( + schema.object({ + snapshot_repository: schema.string(), + }) + ), }), }) ); @@ -104,7 +109,11 @@ const deletePhaseSchema = schema.maybe( policy: schema.string(), }) ), - delete: schema.maybe(schema.object({})), // Delete has no options + delete: schema.maybe( + schema.object({ + delete_searchable_snapshot: schema.maybe(schema.boolean()), + }) + ), }), }) ); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts b/x-pack/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts index e5bce31ee6de1..da461609f0b83 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts @@ -12,7 +12,7 @@ type HttpResponse = Record | any[]; // Register helpers to mock HTTP Requests const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { const setLoadTemplatesResponse = (response: HttpResponse = []) => { - server.respondWith('GET', `${API_BASE_PATH}/templates`, [ + server.respondWith('GET', `${API_BASE_PATH}/index-templates`, [ 200, { 'Content-Type': 'application/json' }, JSON.stringify(response), @@ -28,7 +28,7 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { }; const setDeleteTemplateResponse = (response: HttpResponse = []) => { - server.respondWith('DELETE', `${API_BASE_PATH}/templates`, [ + server.respondWith('POST', `${API_BASE_PATH}/delete-index-templates`, [ 200, { 'Content-Type': 'application/json' }, JSON.stringify(response), @@ -39,7 +39,7 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { const status = error ? error.status || 400 : 200; const body = error ? error.body : response; - server.respondWith('GET', `${API_BASE_PATH}/templates/:id`, [ + server.respondWith('GET', `${API_BASE_PATH}/index-templates/:id`, [ status, { 'Content-Type': 'application/json' }, JSON.stringify(body), @@ -50,7 +50,7 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { const status = error ? error.body.status || 400 : 200; const body = error ? JSON.stringify(error.body) : JSON.stringify(response); - server.respondWith('PUT', `${API_BASE_PATH}/templates`, [ + server.respondWith('POST', `${API_BASE_PATH}/index-templates`, [ status, { 'Content-Type': 'application/json' }, body, @@ -61,7 +61,7 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => { const status = error ? error.status || 400 : 200; const body = error ? JSON.stringify(error.body) : JSON.stringify(response); - server.respondWith('PUT', `${API_BASE_PATH}/templates/:name`, [ + server.respondWith('PUT', `${API_BASE_PATH}/index-templates/:name`, [ status, { 'Content-Type': 'application/json' }, body, diff --git a/x-pack/plugins/index_management/__jest__/client_integration/helpers/index.ts b/x-pack/plugins/index_management/__jest__/client_integration/helpers/index.ts index ab42a035a3d90..8e7755a65af3c 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/helpers/index.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/index.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import './mocks'; + export { nextTick, getRandomString, findTestSubject, TestBed } from '../../../../../test_utils'; export { setupEnvironment, WithAppDependencies, services } from './setup_environment'; @@ -14,6 +16,7 @@ export type TestSubjects = | 'cell' | 'closeDetailsButton' | 'createTemplateButton' + | 'createLegacyTemplateButton' | 'deleteSystemTemplateCallOut' | 'deleteTemplateButton' | 'deleteTemplatesConfirmation' @@ -44,4 +47,7 @@ export type TestSubjects = | 'templateDetails.title' | 'templateList' | 'templateTable' - | 'templatesTab'; + | 'templatesTab' + | 'legacyTemplateTable' + | 'viewButton' + | 'filterList.filterItem'; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/helpers/mocks.ts b/x-pack/plugins/index_management/__jest__/client_integration/helpers/mocks.ts new file mode 100644 index 0000000000000..6260a987e270a --- /dev/null +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/mocks.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +(window as any).Worker = class Worker { + onmessage() {} + postMessage() {} +}; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/home.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/home.test.ts index d195ce46c2f54..a7ac2ebf9bb02 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/home.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/home.test.ts @@ -7,9 +7,17 @@ import { act } from 'react-dom/test-utils'; import { setupEnvironment, nextTick } from '../helpers'; - import { HomeTestBed, setup } from './home.helpers'; +/** + * The below import is required to avoid a console error warn from the "brace" package + * console.warn ../node_modules/brace/index.js:3999 + Could not load worker ReferenceError: Worker is not defined + at createWorker (//node_modules/brace/index.js:17992:5) + */ +import { stubWebWorker } from '../../../../../test_utils/stub_web_worker'; +stubWebWorker(); + describe('', () => { const { server, httpRequestsMockHelpers } = setupEnvironment(); let testBed: HomeTestBed; @@ -62,7 +70,7 @@ describe('', () => { expect(exists('indicesList')).toBe(true); expect(exists('templateList')).toBe(false); - httpRequestsMockHelpers.setLoadTemplatesResponse([]); + httpRequestsMockHelpers.setLoadTemplatesResponse({ templates: [], legacyTemplates: [] }); actions.selectHomeTab('templatesTab'); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts index 0c4cca4dbcc7e..98bd3077670a7 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.helpers.ts @@ -12,7 +12,6 @@ import { TestBed, TestBedConfig, findTestSubject, - nextTick, } from '../../../../../test_utils'; // NOTE: We have to use the Home component instead of the TemplateList component because we depend // upon react router to provide the name of the template to load in the detail panel. @@ -24,7 +23,7 @@ import { WithAppDependencies, services, TestSubjects } from '../helpers'; const testBedConfig: TestBedConfig = { store: () => indexManagementStore(services as any), memoryRouter: { - initialEntries: [`/indices?includeHidden=true`], + initialEntries: [`/indices`], componentRoutePath: `/:section(indices|templates)`, }, doMountAsync: true, @@ -45,6 +44,7 @@ export interface IndexTemplatesTabTestBed extends TestBed { clickTemplateAt: (index: number) => void; clickCloseDetailsButton: () => void; clickActionMenu: (name: TemplateDeserialized['name']) => void; + toggleViewItem: (view: 'composable' | 'system') => void; }; } @@ -102,15 +102,14 @@ export const setup = async (): Promise => { const clickTemplateAt = async (index: number) => { const { component, table, router } = testBed; - const { rows } = table.getMetaData('templateTable'); + const { rows } = table.getMetaData('legacyTemplateTable'); const templateLink = findTestSubject(rows[index].reactWrapper, 'templateDetailsLink'); + const { href } = templateLink.props(); await act(async () => { - const { href } = templateLink.props(); router.navigateTo(href!); - await nextTick(); - component.update(); }); + component.update(); }; const clickCloseDetailsButton = () => { @@ -119,6 +118,23 @@ export const setup = async (): Promise => { find('closeDetailsButton').simulate('click'); }; + const toggleViewItem = (view: 'composable' | 'system') => { + const { find, component } = testBed; + const views = ['composable', 'system']; + + // First open the pop over + act(() => { + find('viewButton').simulate('click'); + }); + component.update(); + + // Then click on a filter item + act(() => { + find('filterList.filterItem').at(views.indexOf(view)).simulate('click'); + }); + component.update(); + }; + return { ...testBed, findAction, @@ -130,6 +146,7 @@ export const setup = async (): Promise => { clickTemplateAt, clickCloseDetailsButton, clickActionMenu, + toggleViewItem, }, }; }; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts index c9a279e90d0e0..8f6a8dddeb195 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/index_templates_tab.test.ts @@ -8,16 +8,18 @@ import { act } from 'react-dom/test-utils'; import * as fixtures from '../../../test/fixtures'; import { API_BASE_PATH } from '../../../common/constants'; -import { setupEnvironment, nextTick, getRandomString } from '../helpers'; +import { setupEnvironment, getRandomString } from '../helpers'; import { IndexTemplatesTabTestBed, setup } from './index_templates_tab.helpers'; const removeWhiteSpaceOnArrayValues = (array: any[]) => array.map((value) => { - if (!value.trim) { + if (typeof value !== 'string') { return value; } - return value.trim(); + + // Convert non breaking spaces ( ) to ordinary space + return value.trim().replace(/\s/g, ' '); }); describe('Index Templates tab', () => { @@ -31,13 +33,8 @@ describe('Index Templates tab', () => { beforeEach(async () => { httpRequestsMockHelpers.setLoadIndicesResponse([]); - testBed = await setup(); - await act(async () => { - const { component } = testBed; - - await nextTick(); - component.update(); + testBed = await setup(); }); }); @@ -45,14 +42,12 @@ describe('Index Templates tab', () => { beforeEach(async () => { const { actions, component } = testBed; - httpRequestsMockHelpers.setLoadTemplatesResponse([]); - - actions.goToTemplatesList(); + httpRequestsMockHelpers.setLoadTemplatesResponse({ templates: [], legacyTemplates: [] }); await act(async () => { - await nextTick(); - component.update(); + actions.goToTemplatesList(); }); + component.update(); }); test('should display an empty prompt', async () => { @@ -64,6 +59,9 @@ describe('Index Templates tab', () => { }); describe('when there are index templates', () => { + // Add a default loadIndexTemplate response + httpRequestsMockHelpers.setLoadTemplateResponse(fixtures.getTemplate()); + const template1 = fixtures.getTemplate({ name: `a${getRandomString()}`, indexPatterns: ['template1Pattern1*', 'template1Pattern2'], @@ -78,37 +76,87 @@ describe('Index Templates tab', () => { }, }, }); + const template2 = fixtures.getTemplate({ name: `b${getRandomString()}`, indexPatterns: ['template2Pattern1*'], }); + const template3 = fixtures.getTemplate({ name: `.c${getRandomString()}`, // mock system template indexPatterns: ['template3Pattern1*', 'template3Pattern2', 'template3Pattern3'], }); + const template4 = fixtures.getTemplate({ + name: `a${getRandomString()}`, + indexPatterns: ['template4Pattern1*', 'template4Pattern2'], + template: { + settings: { + index: { + number_of_shards: '1', + lifecycle: { + name: 'my_ilm_policy', + }, + }, + }, + }, + isLegacy: true, + }); + + const template5 = fixtures.getTemplate({ + name: `b${getRandomString()}`, + indexPatterns: ['template5Pattern1*'], + isLegacy: true, + }); + + const template6 = fixtures.getTemplate({ + name: `.c${getRandomString()}`, // mock system template + indexPatterns: ['template6Pattern1*', 'template6Pattern2', 'template6Pattern3'], + isLegacy: true, + }); + const templates = [template1, template2, template3]; + const legacyTemplates = [template4, template5, template6]; beforeEach(async () => { const { actions, component } = testBed; - httpRequestsMockHelpers.setLoadTemplatesResponse(templates); - - actions.goToTemplatesList(); + httpRequestsMockHelpers.setLoadTemplatesResponse({ templates, legacyTemplates }); await act(async () => { - await nextTick(); - component.update(); + actions.goToTemplatesList(); }); + component.update(); }); test('should list them in the table', async () => { const { table } = testBed; const { tableCellsValues } = table.getMetaData('templateTable'); + const { tableCellsValues: legacyTableCellsValues } = table.getMetaData('legacyTemplateTable'); + // Test composable table content tableCellsValues.forEach((row, i) => { const template = templates[i]; + const { name, indexPatterns, priority, ilmPolicy, composedOf } = template; + + const ilmPolicyName = ilmPolicy && ilmPolicy.name ? ilmPolicy.name : ''; + const composedOfString = composedOf ? composedOf.join(',') : ''; + const priorityFormatted = priority ? priority.toString() : ''; + + expect(removeWhiteSpaceOnArrayValues(row)).toEqual([ + name, + indexPatterns.join(', '), + ilmPolicyName, + composedOfString, + priorityFormatted, + 'M S A', // Mappings Settings Aliases badges + ]); + }); + + // Test legacy table content + legacyTableCellsValues.forEach((row, i) => { + const template = legacyTemplates[i]; const { name, indexPatterns, order, ilmPolicy } = template; const ilmPolicyName = ilmPolicy && ilmPolicy.name ? ilmPolicy.name : ''; @@ -129,44 +177,40 @@ describe('Index Templates tab', () => { }); test('should have a button to reload the index templates', async () => { - const { component, exists, actions } = testBed; + const { exists, actions } = testBed; const totalRequests = server.requests.length; expect(exists('reloadButton')).toBe(true); await act(async () => { actions.clickReloadButton(); - await nextTick(); - component.update(); }); expect(server.requests.length).toBe(totalRequests + 1); - expect(server.requests[server.requests.length - 1].url).toBe(`${API_BASE_PATH}/templates`); + expect(server.requests[server.requests.length - 1].url).toBe( + `${API_BASE_PATH}/index-templates` + ); }); test('should have a button to create a new template', () => { const { exists } = testBed; - expect(exists('createTemplateButton')).toBe(true); + expect(exists('createLegacyTemplateButton')).toBe(true); }); test('should have a switch to view system templates', async () => { - const { table, exists, component, form } = testBed; - const { rows } = table.getMetaData('templateTable'); + const { table, exists, actions } = testBed; + const { rows } = table.getMetaData('legacyTemplateTable'); expect(rows.length).toEqual( - templates.filter((template) => !template.name.startsWith('.')).length + legacyTemplates.filter((template) => !template.name.startsWith('.')).length ); - expect(exists('systemTemplatesSwitch')).toBe(true); + expect(exists('viewButton')).toBe(true); - await act(async () => { - form.toggleEuiSwitch('systemTemplatesSwitch'); - await nextTick(); - component.update(); - }); + actions.toggleViewItem('system'); - const { rows: updatedRows } = table.getMetaData('templateTable'); - expect(updatedRows.length).toEqual(templates.length); + const { rows: updatedRows } = table.getMetaData('legacyTemplateTable'); + expect(updatedRows.length).toEqual(legacyTemplates.length); }); test('each row should have a link to the template details panel', async () => { @@ -176,12 +220,12 @@ describe('Index Templates tab', () => { expect(exists('templateList')).toBe(true); expect(exists('templateDetails')).toBe(true); - expect(find('templateDetails.title').text()).toBe(template1.name); + expect(find('templateDetails.title').text()).toBe(legacyTemplates[0].name); }); test('template actions column should have an option to delete', () => { const { actions, findAction } = testBed; - const { name: templateName } = template1; + const [{ name: templateName }] = legacyTemplates; actions.clickActionMenu(templateName); @@ -192,7 +236,7 @@ describe('Index Templates tab', () => { test('template actions column should have an option to clone', () => { const { actions, findAction } = testBed; - const { name: templateName } = template1; + const [{ name: templateName }] = legacyTemplates; actions.clickActionMenu(templateName); @@ -203,7 +247,7 @@ describe('Index Templates tab', () => { test('template actions column should have an option to edit', () => { const { actions, findAction } = testBed; - const { name: templateName } = template1; + const [{ name: templateName }] = legacyTemplates; actions.clickActionMenu(templateName); @@ -215,7 +259,7 @@ describe('Index Templates tab', () => { describe('delete index template', () => { test('should show a confirmation when clicking the delete template button', async () => { const { actions } = testBed; - const { name: templateName } = template1; + const [{ name: templateName }] = legacyTemplates; await actions.clickTemplateAction(templateName, 'delete'); @@ -231,32 +275,28 @@ describe('Index Templates tab', () => { }); test('should show a warning message when attempting to delete a system template', async () => { - const { component, form, actions } = testBed; + const { exists, actions } = testBed; - await act(async () => { - form.toggleEuiSwitch('systemTemplatesSwitch'); - await nextTick(); - component.update(); - }); + actions.toggleViewItem('system'); - const { name: systemTemplateName } = template3; + const { name: systemTemplateName } = legacyTemplates[2]; await actions.clickTemplateAction(systemTemplateName, 'delete'); - expect( - document.body.querySelector('[data-test-subj="deleteSystemTemplateCallOut"]') - ).not.toBe(null); + expect(exists('deleteSystemTemplateCallOut')).toBe(true); }); test('should send the correct HTTP request to delete an index template', async () => { - const { component, actions, table } = testBed; - const { rows } = table.getMetaData('templateTable'); + const { actions, table } = testBed; + const { rows } = table.getMetaData('legacyTemplateTable'); const templateId = rows[0].columns[2].value; - const { - name: templateName, - _kbnMeta: { formatVersion }, - } = template1; + const [ + { + name: templateName, + _kbnMeta: { isLegacy }, + }, + ] = legacyTemplates; await actions.clickTemplateAction(templateName, 'delete'); const modal = document.body.querySelector('[data-test-subj="deleteTemplatesConfirmation"]'); @@ -273,16 +313,14 @@ describe('Index Templates tab', () => { await act(async () => { confirmButton!.click(); - await nextTick(); - component.update(); }); const latestRequest = server.requests[server.requests.length - 1]; expect(latestRequest.method).toBe('POST'); - expect(latestRequest.url).toBe(`${API_BASE_PATH}/delete-templates`); + expect(latestRequest.url).toBe(`${API_BASE_PATH}/delete-index-templates`); expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual({ - templates: [{ name: template1.name, formatVersion }], + templates: [{ name: legacyTemplates[0].name, isLegacy }], }); }); }); @@ -292,6 +330,7 @@ describe('Index Templates tab', () => { const template = fixtures.getTemplate({ name: `a${getRandomString()}`, indexPatterns: ['template1Pattern1*', 'template1Pattern2'], + isLegacy: true, }); httpRequestsMockHelpers.setLoadTemplateResponse(template); @@ -316,7 +355,7 @@ describe('Index Templates tab', () => { test('should set the correct title', async () => { const { find } = testBed; - const { name } = template1; + const [{ name }] = legacyTemplates; expect(find('templateDetails.title').text()).toEqual(name); }); @@ -327,12 +366,10 @@ describe('Index Templates tab', () => { expect(exists('closeDetailsButton')).toBe(true); expect(exists('summaryTab')).toBe(true); - actions.clickCloseDetailsButton(); - await act(async () => { - await nextTick(); - component.update(); + actions.clickCloseDetailsButton(); }); + component.update(); expect(exists('summaryTab')).toBe(false); }); @@ -372,6 +409,7 @@ describe('Index Templates tab', () => { alias1: {}, }, }, + isLegacy: true, }); const { find, actions, exists } = testBed; @@ -412,19 +450,15 @@ describe('Index Templates tab', () => { const templateWithNoOptionalFields = fixtures.getTemplate({ name: `a${getRandomString()}`, indexPatterns: ['template1Pattern1*', 'template1Pattern2'], + isLegacy: true, }); - const { actions, find, exists, component } = testBed; + const { actions, find, exists } = testBed; httpRequestsMockHelpers.setLoadTemplateResponse(templateWithNoOptionalFields); await actions.clickTemplateAt(0); - await act(async () => { - await nextTick(); - component.update(); - }); - expect(find('templateDetails.tab').length).toBe(4); expect(exists('summaryTab')).toBe(true); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.helpers.ts index 07f3391782a54..e995932dfa00d 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.helpers.ts @@ -14,7 +14,7 @@ import { WithAppDependencies, services, TestSubjects } from '../helpers'; const testBedConfig: TestBedConfig = { store: () => indexManagementStore(services as any), memoryRouter: { - initialEntries: [`/indices?includeHidden=true`], + initialEntries: [`/indices?includeHiddenIndices=true`], componentRoutePath: `/:section(indices|templates)`, }, doMountAsync: true, diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts index e5db5d547f1ab..11c25ffbb590f 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts @@ -8,9 +8,17 @@ import { act } from 'react-dom/test-utils'; import { API_BASE_PATH } from '../../../common/constants'; import { setupEnvironment, nextTick } from '../helpers'; - import { IndicesTestBed, setup } from './indices_tab.helpers'; +/** + * The below import is required to avoid a console error warn from the "brace" package + * console.warn ../node_modules/brace/index.js:3999 + Could not load worker ReferenceError: Worker is not defined + at createWorker (//node_modules/brace/index.js:17992:5) + */ +import { stubWebWorker } from '../../../../../test_utils/stub_web_worker'; +stubWebWorker(); + describe('', () => { const { server, httpRequestsMockHelpers } = setupEnvironment(); let testBed: IndicesTestBed; @@ -33,16 +41,14 @@ describe('', () => { }); }); - test('sets the hash query param base on include hidden indices toggle', () => { + test('toggles the include hidden button through URL hash correctly', () => { const { actions } = testBed; expect(actions.getIncludeHiddenIndicesToggleStatus()).toBe(true); - expect(window.location.hash.includes('includeHidden=true')).toBe(true); actions.clickIncludeHiddenIndicesToggle(); - expect(window.location.hash.includes('includeHidden=true')).toBe(false); + expect(actions.getIncludeHiddenIndicesToggleStatus()).toBe(false); // Note: this test modifies the shared location.hash state, we put it back the way it was actions.clickIncludeHiddenIndicesToggle(); expect(actions.getIncludeHiddenIndicesToggleStatus()).toBe(true); - expect(window.location.hash.includes('includeHidden=true')).toBe(true); }); }); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx index e0db9cd58ee23..6250ef0dc247d 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_clone.test.tsx @@ -53,6 +53,7 @@ describe.skip('', () => { template: { mappings: MAPPINGS, }, + isLegacy: true, }); beforeEach(async () => { diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx index 95545b6c66f54..50b35fc76721a 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_create.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; -import { DEFAULT_INDEX_TEMPLATE_VERSION_FORMAT } from '../../../common'; +import { CREATE_LEGACY_TEMPLATE_BY_DEFAULT } from '../../../common'; import { setupEnvironment, nextTick } from '../helpers'; import { @@ -344,7 +344,6 @@ describe.skip('', () => { const latestRequest = server.requests[server.requests.length - 1]; const expected = { - isManaged: false, name: TEMPLATE_NAME, indexPatterns: DEFAULT_INDEX_PATTERNS, template: { @@ -366,7 +365,8 @@ describe.skip('', () => { aliases: ALIASES, }, _kbnMeta: { - formatVersion: DEFAULT_INDEX_TEMPLATE_VERSION_FORMAT, + isLegacy: CREATE_LEGACY_TEMPLATE_BY_DEFAULT, + isManaged: false, }, }; diff --git a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.test.tsx index 6e935a5263301..88067d479f7e7 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/index_template_wizard/template_edit.test.tsx @@ -62,6 +62,7 @@ describe.skip('', () => { const templateToEdit = fixtures.getTemplate({ name: 'index_template_without_mappings', indexPatterns: ['indexPattern1'], + isLegacy: true, }); beforeEach(async () => { @@ -102,6 +103,7 @@ describe.skip('', () => { template: { mappings: MAPPING, }, + isLegacy: true, }); beforeEach(async () => { @@ -206,9 +208,9 @@ describe.skip('', () => { settings: SETTINGS, aliases: ALIASES, }, - isManaged: false, _kbnMeta: { - formatVersion: templateToEdit._kbnMeta.formatVersion, + isManaged: false, + isLegacy: templateToEdit._kbnMeta.isLegacy, }, }; diff --git a/x-pack/plugins/index_management/common/constants/index.ts b/x-pack/plugins/index_management/common/constants/index.ts index 966e2e8e64838..526b9fede2a67 100644 --- a/x-pack/plugins/index_management/common/constants/index.ts +++ b/x-pack/plugins/index_management/common/constants/index.ts @@ -9,7 +9,7 @@ export { BASE_PATH } from './base_path'; export { API_BASE_PATH } from './api_base_path'; export { INVALID_INDEX_PATTERN_CHARS, INVALID_TEMPLATE_NAME_CHARS } from './invalid_characters'; export * from './index_statuses'; -export { DEFAULT_INDEX_TEMPLATE_VERSION_FORMAT } from './index_templates'; +export { CREATE_LEGACY_TEMPLATE_BY_DEFAULT } from './index_templates'; export { UIM_APP_NAME, diff --git a/x-pack/plugins/index_management/common/constants/index_templates.ts b/x-pack/plugins/index_management/common/constants/index_templates.ts index 788e96ee895ed..7696b3832c51e 100644 --- a/x-pack/plugins/index_management/common/constants/index_templates.ts +++ b/x-pack/plugins/index_management/common/constants/index_templates.ts @@ -6,7 +6,7 @@ /** * Up until the end of the 8.x release cycle we need to support both - * V1 and V2 index template formats. This constant keeps track of whether - * we create V1 or V2 index template format in the UI. + * legacy and composable index template formats. This constant keeps track of whether + * we create legacy index template format by default in the UI. */ -export const DEFAULT_INDEX_TEMPLATE_VERSION_FORMAT = 1; +export const CREATE_LEGACY_TEMPLATE_BY_DEFAULT = true; diff --git a/x-pack/plugins/index_management/common/index.ts b/x-pack/plugins/index_management/common/index.ts index 459eda7552c85..3792e322ae40b 100644 --- a/x-pack/plugins/index_management/common/index.ts +++ b/x-pack/plugins/index_management/common/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -export { PLUGIN, API_BASE_PATH, DEFAULT_INDEX_TEMPLATE_VERSION_FORMAT } from './constants'; +export { PLUGIN, API_BASE_PATH, CREATE_LEGACY_TEMPLATE_BY_DEFAULT } from './constants'; export { getTemplateParameter } from './lib'; diff --git a/x-pack/plugins/index_management/common/lib/index.ts b/x-pack/plugins/index_management/common/lib/index.ts index 33f7fbe45182e..16eb544c56a08 100644 --- a/x-pack/plugins/index_management/common/lib/index.ts +++ b/x-pack/plugins/index_management/common/lib/index.ts @@ -4,9 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ export { + deserializeLegacyTemplateList, deserializeTemplateList, - deserializeV1Template, - serializeV1Template, + deserializeLegacyTemplate, + serializeLegacyTemplate, } from './template_serialization'; export { getTemplateParameter } from './utils'; diff --git a/x-pack/plugins/index_management/common/lib/template_serialization.ts b/x-pack/plugins/index_management/common/lib/template_serialization.ts index 33a83d1e9335b..249881f668d9f 100644 --- a/x-pack/plugins/index_management/common/lib/template_serialization.ts +++ b/x-pack/plugins/index_management/common/lib/template_serialization.ts @@ -5,60 +5,34 @@ */ import { TemplateDeserialized, - TemplateV1Serialized, - TemplateV2Serialized, + LegacyTemplateSerialized, + TemplateSerialized, TemplateListItem, } from '../types'; const hasEntries = (data: object = {}) => Object.entries(data).length > 0; -export function serializeV1Template(template: TemplateDeserialized): TemplateV1Serialized { - const { - name, - version, - order, - indexPatterns, - template: { settings, aliases, mappings } = {} as TemplateDeserialized['template'], - } = template; +export function serializeTemplate(templateDeserialized: TemplateDeserialized): TemplateSerialized { + const { version, priority, indexPatterns, template, composedOf } = templateDeserialized; - const serializedTemplate: TemplateV1Serialized = { - name, + return { version, - order, + priority, + template, index_patterns: indexPatterns, - settings, - aliases, - mappings, - }; - - return serializedTemplate; -} - -export function serializeV2Template(template: TemplateDeserialized): TemplateV2Serialized { - const { aliases, mappings, settings, ...templateV1serialized } = serializeV1Template(template); - - return { - ...templateV1serialized, - template: { - aliases, - mappings, - settings, - }, - priority: template.priority, - composed_of: template.composedOf, + composed_of: composedOf, }; } -export function deserializeV2Template( - templateEs: TemplateV2Serialized, +export function deserializeTemplate( + templateEs: TemplateSerialized & { name: string }, managedTemplatePrefix?: string ): TemplateDeserialized { const { name, version, - order, index_patterns: indexPatterns, - template, + template = {}, priority, composed_of: composedOf, } = templateEs; @@ -67,49 +41,92 @@ export function deserializeV2Template( const deserializedTemplate: TemplateDeserialized = { name, version, - order, + priority, indexPatterns: indexPatterns.sort(), template, - ilmPolicy: settings && settings.index && settings.index.lifecycle, - isManaged: Boolean(managedTemplatePrefix && name.startsWith(managedTemplatePrefix)), - priority, + ilmPolicy: settings?.index?.lifecycle, composedOf, _kbnMeta: { - formatVersion: 2, + isManaged: Boolean(managedTemplatePrefix && name.startsWith(managedTemplatePrefix)), }, }; return deserializedTemplate; } -export function deserializeV1Template( - templateEs: TemplateV1Serialized, +export function deserializeTemplateList( + indexTemplates: Array<{ name: string; index_template: TemplateSerialized }>, + managedTemplatePrefix?: string +): TemplateListItem[] { + return indexTemplates.map(({ name, index_template: templateSerialized }) => { + const { + template: { mappings, settings, aliases }, + ...deserializedTemplate + } = deserializeTemplate({ name, ...templateSerialized }, managedTemplatePrefix); + + return { + ...deserializedTemplate, + hasSettings: hasEntries(settings), + hasAliases: hasEntries(aliases), + hasMappings: hasEntries(mappings), + }; + }); +} + +/** + * ------------------------------------------ + * --------- LEGACY INDEX TEMPLATES --------- + * ------------------------------------------ + */ + +export function serializeLegacyTemplate(template: TemplateDeserialized): LegacyTemplateSerialized { + const { + version, + order, + indexPatterns, + template: { settings, aliases, mappings }, + } = template; + + return { + version, + order, + index_patterns: indexPatterns, + settings, + aliases, + mappings, + }; +} + +export function deserializeLegacyTemplate( + templateEs: LegacyTemplateSerialized & { name: string }, managedTemplatePrefix?: string ): TemplateDeserialized { const { settings, aliases, mappings, ...rest } = templateEs; - const deserializedTemplateV2 = deserializeV2Template( + const deserializedTemplate = deserializeTemplate( { ...rest, template: { aliases, settings, mappings } }, managedTemplatePrefix ); return { - ...deserializedTemplateV2, + ...deserializedTemplate, + order: templateEs.order, _kbnMeta: { - formatVersion: 1, + ...deserializedTemplate._kbnMeta, + isLegacy: true, }, }; } -export function deserializeTemplateList( - indexTemplatesByName: { [key: string]: Omit }, +export function deserializeLegacyTemplateList( + indexTemplatesByName: { [key: string]: LegacyTemplateSerialized }, managedTemplatePrefix?: string ): TemplateListItem[] { return Object.entries(indexTemplatesByName).map(([name, templateSerialized]) => { const { template: { mappings, settings, aliases }, ...deserializedTemplate - } = deserializeV1Template({ name, ...templateSerialized }, managedTemplatePrefix); + } = deserializeLegacyTemplate({ name, ...templateSerialized }, managedTemplatePrefix); return { ...deserializedTemplate, diff --git a/x-pack/plugins/index_management/common/lib/utils.test.ts b/x-pack/plugins/index_management/common/lib/utils.test.ts index 221d1b009cede..056101061a82b 100644 --- a/x-pack/plugins/index_management/common/lib/utils.test.ts +++ b/x-pack/plugins/index_management/common/lib/utils.test.ts @@ -3,12 +3,12 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { TemplateV1Serialized, TemplateV2Serialized } from '../types'; -import { getTemplateVersion } from './utils'; +import { LegacyTemplateSerialized, TemplateSerialized } from '../types'; +import { isLegacyTemplate } from './utils'; describe('utils', () => { - describe('getTemplateVersion', () => { - test('should detect v1 template', () => { + describe('isLegacyTemplate', () => { + test('should detect legacy template', () => { const template = { name: 'my_template', index_patterns: ['logs*'], @@ -16,10 +16,10 @@ describe('utils', () => { properties: {}, }, }; - expect(getTemplateVersion(template as TemplateV1Serialized)).toBe(1); + expect(isLegacyTemplate(template as LegacyTemplateSerialized)).toBe(true); }); - test('should detect v2 template', () => { + test('should detect composable template', () => { const template = { name: 'my_template', index_patterns: ['logs*'], @@ -29,7 +29,7 @@ describe('utils', () => { }, }, }; - expect(getTemplateVersion(template as TemplateV2Serialized)).toBe(2); + expect(isLegacyTemplate(template as TemplateSerialized)).toBe(false); }); }); }); diff --git a/x-pack/plugins/index_management/common/lib/utils.ts b/x-pack/plugins/index_management/common/lib/utils.ts index eee35dc1ab467..5a7db8ef50ab4 100644 --- a/x-pack/plugins/index_management/common/lib/utils.ts +++ b/x-pack/plugins/index_management/common/lib/utils.ts @@ -4,26 +4,24 @@ * you may not use this file except in compliance with the Elastic License. */ -import { TemplateDeserialized, TemplateV1Serialized, TemplateV2Serialized } from '../types'; +import { TemplateDeserialized, LegacyTemplateSerialized, TemplateSerialized } from '../types'; /** - * Helper to get the format version of an index template. - * v1 will be supported up until 9.x but marked as deprecated from 7.8 - * v2 will be supported from 7.8 + * Helper to know if a template has the legacy format or not + * legacy format will be supported up until 9.x but marked as deprecated from 7.8 + * new (composable) format is supported from 7.8 */ -export const getTemplateVersion = ( - template: TemplateDeserialized | TemplateV1Serialized | TemplateV2Serialized -): 1 | 2 => { - return {}.hasOwnProperty.call(template, 'template') ? 2 : 1; +export const isLegacyTemplate = ( + template: TemplateDeserialized | LegacyTemplateSerialized | TemplateSerialized +): boolean => { + return {}.hasOwnProperty.call(template, 'template') ? false : true; }; export const getTemplateParameter = ( - template: TemplateV1Serialized | TemplateV2Serialized, + template: LegacyTemplateSerialized | TemplateSerialized, setting: 'aliases' | 'settings' | 'mappings' ) => { - const formatVersion = getTemplateVersion(template); - - return formatVersion === 1 - ? (template as TemplateV1Serialized)[setting] - : (template as TemplateV2Serialized).template[setting]; + return isLegacyTemplate(template) + ? (template as LegacyTemplateSerialized)[setting] + : (template as TemplateSerialized).template[setting]; }; diff --git a/x-pack/plugins/index_management/common/types/templates.ts b/x-pack/plugins/index_management/common/types/templates.ts index c37088982f207..f113aa44d058f 100644 --- a/x-pack/plugins/index_management/common/types/templates.ts +++ b/x-pack/plugins/index_management/common/types/templates.ts @@ -8,28 +8,45 @@ import { IndexSettings } from './indices'; import { Aliases } from './aliases'; import { Mappings } from './mappings'; -// Template serialized (from Elasticsearch) -interface TemplateBaseSerialized { - name: string; +/** + * Index template format from Elasticsearch + */ +export interface TemplateSerialized { index_patterns: string[]; + template: { + settings?: IndexSettings; + aliases?: Aliases; + mappings?: Mappings; + }; + composed_of?: string[]; version?: number; - order?: number; -} - -export interface TemplateV1Serialized extends TemplateBaseSerialized { - settings?: IndexSettings; - aliases?: Aliases; - mappings?: Mappings; + priority?: number; } -export interface TemplateV2Serialized extends TemplateBaseSerialized { +/** + * TemplateDeserialized is the format the UI will be working with, + * regardless if we are loading the new format (composable) index template, + * or the legacy one. Serialization is done server side. + */ +export interface TemplateDeserialized { + name: string; + indexPatterns: string[]; template: { settings?: IndexSettings; aliases?: Aliases; mappings?: Mappings; }; + composedOf?: string[]; // Used on composable index template + version?: number; priority?: number; - composed_of?: string[]; + order?: number; // Used on legacy index template + ilmPolicy?: { + name: string; + }; + _kbnMeta: { + isManaged: boolean; + isLegacy?: boolean; + }; } /** @@ -42,42 +59,30 @@ export interface TemplateListItem { indexPatterns: string[]; version?: number; order?: number; + priority?: number; hasSettings: boolean; hasAliases: boolean; hasMappings: boolean; ilmPolicy?: { name: string; }; - isManaged: boolean; _kbnMeta: { - formatVersion: IndexTemplateFormatVersion; + isManaged: boolean; + isLegacy?: boolean; }; } /** - * TemplateDeserialized falls back to index template V2 format - * The UI will only be dealing with this interface, conversion from and to V1 format - * is done server side. + * ------------------------------------------ + * --------- LEGACY INDEX TEMPLATES --------- + * ------------------------------------------ */ -export interface TemplateDeserialized { - name: string; - indexPatterns: string[]; - isManaged: boolean; - template: { - settings?: IndexSettings; - aliases?: Aliases; - mappings?: Mappings; - }; - _kbnMeta: { - formatVersion: IndexTemplateFormatVersion; - }; + +export interface LegacyTemplateSerialized { + index_patterns: string[]; version?: number; - priority?: number; + settings?: IndexSettings; + aliases?: Aliases; + mappings?: Mappings; order?: number; - ilmPolicy?: { - name: string; - }; - composedOf?: string[]; } - -export type IndexTemplateFormatVersion = 1 | 2; diff --git a/x-pack/plugins/index_management/public/application/components/template_delete_modal.tsx b/x-pack/plugins/index_management/public/application/components/template_delete_modal.tsx index a87412ef92950..06babb0db3bd1 100644 --- a/x-pack/plugins/index_management/public/application/components/template_delete_modal.tsx +++ b/x-pack/plugins/index_management/public/application/components/template_delete_modal.tsx @@ -9,7 +9,6 @@ import { EuiConfirmModal, EuiOverlayMask, EuiCallOut, EuiCheckbox, EuiBadge } fr import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { IndexTemplateFormatVersion } from '../../../common'; import { deleteTemplates } from '../services/api'; import { notificationService } from '../services/notification'; @@ -17,7 +16,7 @@ export const TemplateDeleteModal = ({ templatesToDelete, callback, }: { - templatesToDelete: Array<{ name: string; formatVersion: IndexTemplateFormatVersion }>; + templatesToDelete: Array<{ name: string; isLegacy?: boolean }>; callback: (data?: { hasDeletedTemplates: boolean }) => void; }) => { const [isDeleteConfirmed, setIsDeleteConfirmed] = useState(false); diff --git a/x-pack/plugins/index_management/public/application/components/template_form/steps/step_review.tsx b/x-pack/plugins/index_management/public/application/components/template_form/steps/step_review.tsx index 7b266034bc336..387887239aaf0 100644 --- a/x-pack/plugins/index_management/public/application/components/template_form/steps/step_review.tsx +++ b/x-pack/plugins/index_management/public/application/components/template_form/steps/step_review.tsx @@ -23,8 +23,8 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { serializers } from '../../../../shared_imports'; import { - serializeV1Template, - serializeV2Template, + serializeLegacyTemplate, + serializeTemplate, } from '../../../../../common/lib/template_serialization'; import { TemplateDeserialized, getTemplateParameter } from '../../../../../common'; import { StepProps } from '../types'; @@ -60,16 +60,20 @@ export const StepReview: React.FunctionComponent = ({ template, updat indexPatterns, version, order, - _kbnMeta: { formatVersion }, + _kbnMeta: { isLegacy }, } = template!; - const serializedTemplate = - formatVersion === 1 - ? serializeV1Template(stripEmptyFields(template!) as TemplateDeserialized) - : serializeV2Template(stripEmptyFields(template!) as TemplateDeserialized); - - // Name not included in ES request body - delete serializedTemplate.name; + const serializedTemplate = isLegacy + ? serializeLegacyTemplate( + stripEmptyFields(template!, { + types: ['string'], + }) as TemplateDeserialized + ) + : serializeTemplate( + stripEmptyFields(template!, { + types: ['string'], + }) as TemplateDeserialized + ); const serializedMappings = getTemplateParameter(serializedTemplate, 'mappings'); const serializedSettings = getTemplateParameter(serializedTemplate, 'settings'); diff --git a/x-pack/plugins/index_management/public/application/components/template_form/template_form.tsx b/x-pack/plugins/index_management/public/application/components/template_form/template_form.tsx index 0cdfaae70f151..52e26e6d3e895 100644 --- a/x-pack/plugins/index_management/public/application/components/template_form/template_form.tsx +++ b/x-pack/plugins/index_management/public/application/components/template_form/template_form.tsx @@ -15,7 +15,7 @@ import { } from '@elastic/eui'; import { serializers } from '../../../shared_imports'; -import { TemplateDeserialized, DEFAULT_INDEX_TEMPLATE_VERSION_FORMAT } from '../../../../common'; +import { TemplateDeserialized, CREATE_LEGACY_TEMPLATE_BY_DEFAULT } from '../../../../common'; import { TemplateSteps } from './template_steps'; import { StepAliases, StepLogistics, StepMappings, StepSettings, StepReview } from './steps'; import { StepProps, DataGetterFunc } from './types'; @@ -51,9 +51,9 @@ export const TemplateForm: React.FunctionComponent = ({ name: '', indexPatterns: [], template: {}, - isManaged: false, _kbnMeta: { - formatVersion: DEFAULT_INDEX_TEMPLATE_VERSION_FORMAT, + isManaged: false, + isLegacy: CREATE_LEGACY_TEMPLATE_BY_DEFAULT, }, }, onSave, @@ -246,7 +246,9 @@ export const TemplateForm: React.FunctionComponent = ({ iconType="check" onClick={onSave.bind( null, - stripEmptyFields(template.current!) as TemplateDeserialized + stripEmptyFields(template.current!, { + types: ['string'], + }) as TemplateDeserialized )} data-test-subj="submitButton" isLoading={isSaving} diff --git a/x-pack/plugins/index_management/public/application/lib/index_templates.ts b/x-pack/plugins/index_management/public/application/lib/index_templates.ts index 7129e536287c1..08102ae93cc0e 100644 --- a/x-pack/plugins/index_management/public/application/lib/index_templates.ts +++ b/x-pack/plugins/index_management/public/application/lib/index_templates.ts @@ -6,12 +6,12 @@ import { parse } from 'query-string'; import { Location } from 'history'; -export const getFormatVersionFromQueryparams = (location: Location): 1 | 2 | undefined => { - const { v: version } = parse(location.search.substring(1)); +export const getIsLegacyFromQueryParams = (location: Location): boolean => { + const { legacy } = parse(location.search.substring(1)); - if (!Boolean(version) || typeof version !== 'string') { - return undefined; + if (!Boolean(legacy) || typeof legacy !== 'string') { + return false; } - return +version as 1 | 2; + return legacy === 'true'; }; diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_list.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_list.js index 4b58ff0de17ee..df5ca7f837d10 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_list.js +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_list.js @@ -8,15 +8,10 @@ import React from 'react'; import { DetailPanel } from './detail_panel'; import { IndexTable } from './index_table'; -export function IndexList({ - match: { - params: { filter }, - }, - location, -}) { +export function IndexList() { return (
- +
); diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js index 44d811f490d9d..9a44a02a44f87 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js @@ -5,13 +5,13 @@ */ import { connect } from 'react-redux'; +import { withRouter } from 'react-router-dom'; import { getDetailPanelIndexName, getPageOfIndices, getPager, getFilter, isDetailPanelOpen, - showHiddenIndices, getSortField, isSortAscending, getIndicesAsArray, @@ -26,7 +26,6 @@ import { pageChanged, pageSizeChanged, sortChanged, - showHiddenIndicesChanged, loadIndices, reloadIndices, toggleChanged, @@ -34,15 +33,14 @@ import { import { IndexTable as PresentationComponent } from './index_table'; -const mapStateToProps = (state) => { +const mapStateToProps = (state, props) => { return { allIndices: getIndicesAsArray(state), isDetailPanelOpen: isDetailPanelOpen(state), detailPanelIndexName: getDetailPanelIndexName(state), - indices: getPageOfIndices(state), - pager: getPager(state), + indices: getPageOfIndices(state, props), + pager: getPager(state, props), filter: getFilter(state), - showHiddenIndices: showHiddenIndices(state), sortField: getSortField(state), isSortAscending: isSortAscending(state), indicesLoading: indicesLoading(state), @@ -65,9 +63,6 @@ const mapDispatchToProps = (dispatch) => { sortChanged: (sortField, isSortAscending) => { dispatch(sortChanged({ sortField, isSortAscending })); }, - showHiddenIndicesChanged: (showHiddenIndices) => { - dispatch(showHiddenIndicesChanged({ showHiddenIndices })); - }, toggleChanged: (toggleName, toggleValue) => { dispatch(toggleChanged({ toggleName, toggleValue })); }, @@ -80,10 +75,12 @@ const mapDispatchToProps = (dispatch) => { loadIndices: () => { dispatch(loadIndices()); }, - reloadIndices: () => { - dispatch(reloadIndices()); + reloadIndices: (indexNames) => { + dispatch(reloadIndices(indexNames)); }, }; }; -export const IndexTable = connect(mapStateToProps, mapDispatchToProps)(PresentationComponent); +export const IndexTable = withRouter( + connect(mapStateToProps, mapDispatchToProps)(PresentationComponent) +); diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js index 0d005b2864863..f33d486520a29 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js @@ -8,7 +8,7 @@ import React, { Component, Fragment } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { Route } from 'react-router-dom'; -import { parse } from 'query-string'; +import qs from 'query-string'; import { EuiButton, @@ -66,6 +66,9 @@ const HEADERS = { size: i18n.translate('xpack.idxMgmt.indexTable.headers.storageSizeHeader', { defaultMessage: 'Storage size', }), + data_stream: i18n.translate('xpack.idxMgmt.indexTable.headers.dataStreamHeader', { + defaultMessage: 'Data stream', + }), }; export class IndexTable extends Component { @@ -97,17 +100,14 @@ export class IndexTable extends Component { componentDidMount() { this.props.loadIndices(); - this.interval = setInterval(this.props.reloadIndices, REFRESH_RATE_INDEX_LIST); - const { - filterChanged, - filterFromURI, - showHiddenIndicesChanged, - showHiddenIndices, - location, - } = this.props; - - if (filterFromURI) { - const decodedFilter = decodeURIComponent(filterFromURI); + this.interval = setInterval( + () => this.props.reloadIndices(this.props.indices.map((i) => i.name)), + REFRESH_RATE_INDEX_LIST + ); + const { location, filterChanged } = this.props; + const { filter } = qs.parse((location && location.search) || ''); + if (filter) { + const decodedFilter = decodeURIComponent(filter); try { const filter = EuiSearchBar.Query.parse(decodedFilter); @@ -116,17 +116,30 @@ export class IndexTable extends Component { this.setState({ filterError: e }); } } - - // Check if the we have the includeHidden query param - const { includeHidden } = parse((location && location.search) || ''); - const nextValue = includeHidden === 'true'; - if (nextValue !== showHiddenIndices) { - showHiddenIndicesChanged(nextValue); - } } componentWillUnmount() { clearInterval(this.interval); } + + readURLParams() { + const { location } = this.props; + const { includeHiddenIndices } = qs.parse((location && location.search) || ''); + return { + includeHiddenIndices: includeHiddenIndices === 'true', + }; + } + + setIncludeHiddenParam(hidden) { + const { pathname, search } = this.props.location; + const params = qs.parse(search); + if (hidden) { + params.includeHiddenIndices = 'true'; + } else { + delete params.includeHiddenIndices; + } + this.props.history.push(pathname + '?' + qs.stringify(params)); + } + onSort = (column) => { const { sortField, isSortAscending, sortChanged } = this.props; @@ -416,8 +429,6 @@ export class IndexTable extends Component { render() { const { filter, - showHiddenIndices, - showHiddenIndicesChanged, indices, loadIndices, indicesLoading, @@ -426,6 +437,8 @@ export class IndexTable extends Component { pager, } = this.props; + const { includeHiddenIndices } = this.readURLParams(); + let emptyState; if (indicesLoading) { @@ -477,8 +490,8 @@ export class IndexTable extends Component { showHiddenIndicesChanged(event.target.checked)} + checked={includeHiddenIndices} + onChange={(event) => this.setIncludeHiddenParam(event.target.checked)} label={ { + filters: Filters; + onChange(filters: Filters): void; +} + +export type Filters = { + [key in T]: Filter; +}; + +export function FilterListButton({ onChange, filters }: Props) { + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + + const activeFilters = Object.values(filters).filter((v) => (v as Filter).checked === 'on'); + + const onButtonClick = () => { + setIsPopoverOpen(!isPopoverOpen); + }; + + const closePopover = () => { + setIsPopoverOpen(false); + }; + + const toggleFilter = (filter: T) => { + const previousValue = filters[filter].checked; + onChange({ + ...filters, + [filter]: { + ...filters[filter], + checked: previousValue === 'on' ? 'off' : 'on', + }, + }); + }; + + const button = ( + 0} + numActiveFilters={activeFilters.length} + data-test-subj="viewButton" + > + + + ); + + return ( + +
+ {Object.entries(filters).map(([filter, item], index) => ( + toggleFilter(filter as T)} + data-test-subj="filterItem" + > + {(item as Filter).name} + + ))} +
+
+ ); +} diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/components/index.ts b/x-pack/plugins/index_management/public/application/sections/home/template_list/components/index.ts new file mode 100644 index 0000000000000..dcaba319bb21a --- /dev/null +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/components/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './filter_list_button'; +export * from './template_content_indicator'; diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/components/template_content_indicator.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/components/template_content_indicator.tsx new file mode 100644 index 0000000000000..78e33d7940bd4 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/components/template_content_indicator.tsx @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiBadge, EuiToolTip } from '@elastic/eui'; + +interface Props { + mappings: boolean; + settings: boolean; + aliases: boolean; +} + +const texts = { + settings: i18n.translate('xpack.idxMgmt.templateContentIndicator.indexSettingsTooltipLabel', { + defaultMessage: 'Index settings', + }), + mappings: i18n.translate('xpack.idxMgmt.templateContentIndicator.mappingsTooltipLabel', { + defaultMessage: 'Mappings', + }), + aliases: i18n.translate('xpack.idxMgmt.templateContentIndicator.aliasesTooltipLabel', { + defaultMessage: 'Aliases', + }), +}; + +export const TemplateContentIndicator = ({ mappings, settings, aliases }: Props) => { + const getColor = (flag: boolean) => (flag ? 'primary' : 'hollow'); + + return ( + <> + + <> + M +   + + + + <> + S +   + + + + A + + + ); +}; diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_details/index.ts b/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_details/index.ts new file mode 100644 index 0000000000000..519120b559e7b --- /dev/null +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_details/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { LegacyTemplateDetails } from './template_details'; diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_details/template_details.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_details/template_details.tsx new file mode 100644 index 0000000000000..ec2956973d4f6 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_details/template_details.tsx @@ -0,0 +1,327 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { Fragment, useState } from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; +import { + EuiCallOut, + EuiFlyout, + EuiFlyoutHeader, + EuiTitle, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlexGroup, + EuiFlexItem, + EuiButtonEmpty, + EuiTab, + EuiTabs, + EuiSpacer, + EuiPopover, + EuiButton, + EuiContextMenu, +} from '@elastic/eui'; +import { + UIM_TEMPLATE_DETAIL_PANEL_MAPPINGS_TAB, + UIM_TEMPLATE_DETAIL_PANEL_SUMMARY_TAB, + UIM_TEMPLATE_DETAIL_PANEL_SETTINGS_TAB, + UIM_TEMPLATE_DETAIL_PANEL_ALIASES_TAB, +} from '../../../../../../../common/constants'; +import { TemplateDeserialized } from '../../../../../../../common'; +import { + TemplateDeleteModal, + SectionLoading, + SectionError, + Error, +} from '../../../../../components'; +import { useLoadIndexTemplate } from '../../../../../services/api'; +import { decodePath } from '../../../../../services/routing'; +import { SendRequestResponse } from '../../../../../../shared_imports'; +import { useServices } from '../../../../../app_context'; +import { TabSummary, TabMappings, TabSettings, TabAliases } from '../../template_details/tabs'; + +interface Props { + template: { name: string; isLegacy?: boolean }; + onClose: () => void; + editTemplate: (name: string, isLegacy?: boolean) => void; + cloneTemplate: (name: string, isLegacy?: boolean) => void; + reload: () => Promise; +} + +const SUMMARY_TAB_ID = 'summary'; +const MAPPINGS_TAB_ID = 'mappings'; +const ALIASES_TAB_ID = 'aliases'; +const SETTINGS_TAB_ID = 'settings'; + +const TABS = [ + { + id: SUMMARY_TAB_ID, + name: i18n.translate('xpack.idxMgmt.legacyTemplateDetails.summaryTabTitle', { + defaultMessage: 'Summary', + }), + }, + { + id: SETTINGS_TAB_ID, + name: i18n.translate('xpack.idxMgmt.legacyTemplateDetails.settingsTabTitle', { + defaultMessage: 'Settings', + }), + }, + { + id: MAPPINGS_TAB_ID, + name: i18n.translate('xpack.idxMgmt.legacyTemplateDetails.mappingsTabTitle', { + defaultMessage: 'Mappings', + }), + }, + { + id: ALIASES_TAB_ID, + name: i18n.translate('xpack.idxMgmt.legacyTemplateDetails.aliasesTabTitle', { + defaultMessage: 'Aliases', + }), + }, +]; + +const tabToComponentMap: { + [key: string]: React.FunctionComponent<{ templateDetails: TemplateDeserialized }>; +} = { + [SUMMARY_TAB_ID]: TabSummary, + [SETTINGS_TAB_ID]: TabSettings, + [MAPPINGS_TAB_ID]: TabMappings, + [ALIASES_TAB_ID]: TabAliases, +}; + +const tabToUiMetricMap: { [key: string]: string } = { + [SUMMARY_TAB_ID]: UIM_TEMPLATE_DETAIL_PANEL_SUMMARY_TAB, + [SETTINGS_TAB_ID]: UIM_TEMPLATE_DETAIL_PANEL_SETTINGS_TAB, + [MAPPINGS_TAB_ID]: UIM_TEMPLATE_DETAIL_PANEL_MAPPINGS_TAB, + [ALIASES_TAB_ID]: UIM_TEMPLATE_DETAIL_PANEL_ALIASES_TAB, +}; + +export const LegacyTemplateDetails: React.FunctionComponent = ({ + template: { name: templateName, isLegacy }, + onClose, + editTemplate, + cloneTemplate, + reload, +}) => { + const { uiMetricService } = useServices(); + const decodedTemplateName = decodePath(templateName); + const { error, data: templateDetails, isLoading } = useLoadIndexTemplate( + decodedTemplateName, + isLegacy + ); + const isManaged = templateDetails?._kbnMeta.isManaged ?? false; + const [templateToDelete, setTemplateToDelete] = useState< + Array<{ name: string; isLegacy?: boolean }> + >([]); + const [activeTab, setActiveTab] = useState(SUMMARY_TAB_ID); + const [isPopoverOpen, setIsPopOverOpen] = useState(false); + + let content; + + if (isLoading) { + content = ( + + + + ); + } else if (error) { + content = ( + + } + error={error as Error} + data-test-subj="sectionError" + /> + ); + } else if (templateDetails) { + const Content = tabToComponentMap[activeTab]; + const managedTemplateCallout = isManaged ? ( + + + } + color="primary" + size="s" + > + + + + + ) : null; + + content = ( + + {managedTemplateCallout} + + + {TABS.map((tab) => ( + { + uiMetricService.trackMetric('click', tabToUiMetricMap[tab.id]); + setActiveTab(tab.id); + }} + isSelected={tab.id === activeTab} + key={tab.id} + data-test-subj="tab" + > + {tab.name} + + ))} + + + + + + + ); + } + + return ( + + {templateToDelete && templateToDelete.length > 0 ? ( + { + if (data && data.hasDeletedTemplates) { + reload(); + } else { + setTemplateToDelete([]); + } + onClose(); + }} + templatesToDelete={templateToDelete} + /> + ) : null} + + + + +

+ {decodedTemplateName} +

+
+
+ + {content} + + + + + + + + + {templateDetails && ( + + {/* Manage templates context menu */} + setIsPopOverOpen((prev) => !prev)} + > + + + } + isOpen={isPopoverOpen} + closePopover={() => setIsPopOverOpen(false)} + panelPaddingSize="none" + withTitle + anchorPosition="rightUp" + repositionOnScroll + > + editTemplate(templateName, isLegacy), + disabled: isManaged, + }, + { + name: i18n.translate( + 'xpack.idxMgmt.legacyTemplateDetails.cloneButtonLabel', + { + defaultMessage: 'Clone', + } + ), + icon: 'copy', + onClick: () => cloneTemplate(templateName, isLegacy), + }, + { + name: i18n.translate( + 'xpack.idxMgmt.legacyTemplateDetails.deleteButtonLabel', + { + defaultMessage: 'Delete', + } + ), + icon: 'trash', + onClick: () => + setTemplateToDelete([{ name: decodedTemplateName, isLegacy }]), + disabled: isManaged, + }, + ], + }, + ]} + /> + + + )} + + +
+
+ ); +}; diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_table/index.ts b/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_table/index.ts new file mode 100644 index 0000000000000..a8499df45ce27 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_table/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { LegacyTemplateTable } from './template_table'; diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_table/template_table.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_table/template_table.tsx new file mode 100644 index 0000000000000..92fedd5d68f00 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/legacy_templates/template_table/template_table.tsx @@ -0,0 +1,304 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useState, Fragment } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiInMemoryTable, EuiIcon, EuiButton, EuiLink, EuiBasicTableColumn } from '@elastic/eui'; +import { ScopedHistory } from 'kibana/public'; +import { reactRouterNavigate } from '../../../../../../../../../../src/plugins/kibana_react/public'; +import { TemplateListItem } from '../../../../../../../common'; +import { UIM_TEMPLATE_SHOW_DETAILS_CLICK } from '../../../../../../../common/constants'; +import { TemplateDeleteModal } from '../../../../../components'; +import { useServices } from '../../../../../app_context'; +import { SendRequestResponse } from '../../../../../../shared_imports'; + +interface Props { + templates: TemplateListItem[]; + reload: () => Promise; + editTemplate: (name: string, isLegacy?: boolean) => void; + cloneTemplate: (name: string, isLegacy?: boolean) => void; + history: ScopedHistory; +} + +export const LegacyTemplateTable: React.FunctionComponent = ({ + templates, + reload, + editTemplate, + cloneTemplate, + history, +}) => { + const { uiMetricService } = useServices(); + const [selection, setSelection] = useState([]); + const [templatesToDelete, setTemplatesToDelete] = useState< + Array<{ name: string; isLegacy?: boolean }> + >([]); + + const columns: Array> = [ + { + field: 'name', + name: i18n.translate('xpack.idxMgmt.templateList.legacyTable.nameColumnTitle', { + defaultMessage: 'Name', + }), + truncateText: true, + sortable: true, + render: (name: TemplateListItem['name'], item: TemplateListItem) => { + return ( + /* eslint-disable-next-line @elastic/eui/href-or-on-click */ + uiMetricService.trackMetric('click', UIM_TEMPLATE_SHOW_DETAILS_CLICK) + )} + data-test-subj="templateDetailsLink" + > + {name} + + ); + }, + }, + { + field: 'indexPatterns', + name: i18n.translate('xpack.idxMgmt.templateList.legacyTable.indexPatternsColumnTitle', { + defaultMessage: 'Index patterns', + }), + truncateText: true, + sortable: true, + render: (indexPatterns: string[]) => {indexPatterns.join(', ')}, + }, + { + field: 'ilmPolicy', + name: i18n.translate('xpack.idxMgmt.templateList.legacyTable.ilmPolicyColumnTitle', { + defaultMessage: 'ILM policy', + }), + truncateText: true, + sortable: true, + render: (ilmPolicy: { name: string }) => + ilmPolicy && ilmPolicy.name ? ( + + {ilmPolicy.name} + + ) : null, + }, + { + field: 'order', + name: i18n.translate('xpack.idxMgmt.templateList.legacyTable.orderColumnTitle', { + defaultMessage: 'Order', + }), + truncateText: true, + sortable: true, + }, + { + field: 'hasMappings', + name: i18n.translate('xpack.idxMgmt.templateList.legacyTable.mappingsColumnTitle', { + defaultMessage: 'Mappings', + }), + truncateText: true, + sortable: true, + render: (hasMappings: boolean) => (hasMappings ? : null), + }, + { + field: 'hasSettings', + name: i18n.translate('xpack.idxMgmt.templateList.legacyTable.settingsColumnTitle', { + defaultMessage: 'Settings', + }), + truncateText: true, + sortable: true, + render: (hasSettings: boolean) => (hasSettings ? : null), + }, + { + field: 'hasAliases', + name: i18n.translate('xpack.idxMgmt.templateList.legacyTable.aliasesColumnTitle', { + defaultMessage: 'Aliases', + }), + truncateText: true, + sortable: true, + render: (hasAliases: boolean) => (hasAliases ? : null), + }, + { + name: i18n.translate('xpack.idxMgmt.templateList.legacyTable.actionColumnTitle', { + defaultMessage: 'Actions', + }), + actions: [ + { + name: i18n.translate('xpack.idxMgmt.templateList.legacyTable.actionEditText', { + defaultMessage: 'Edit', + }), + isPrimary: true, + description: i18n.translate( + 'xpack.idxMgmt.templateList.legacyTable.actionEditDecription', + { + defaultMessage: 'Edit this template', + } + ), + icon: 'pencil', + type: 'icon', + onClick: ({ name, _kbnMeta: { isLegacy } }: TemplateListItem) => { + editTemplate(name, isLegacy); + }, + enabled: ({ _kbnMeta: { isManaged } }: TemplateListItem) => !isManaged, + }, + { + type: 'icon', + name: i18n.translate('xpack.idxMgmt.templateList.legacyTable.actionCloneTitle', { + defaultMessage: 'Clone', + }), + description: i18n.translate( + 'xpack.idxMgmt.templateList.legacyTable.actionCloneDescription', + { + defaultMessage: 'Clone this template', + } + ), + icon: 'copy', + onClick: ({ name, _kbnMeta: { isLegacy } }: TemplateListItem) => { + cloneTemplate(name, isLegacy); + }, + }, + { + name: i18n.translate('xpack.idxMgmt.templateList.legacyTable.actionDeleteText', { + defaultMessage: 'Delete', + }), + description: i18n.translate( + 'xpack.idxMgmt.templateList.legacyTable.actionDeleteDecription', + { + defaultMessage: 'Delete this template', + } + ), + icon: 'trash', + color: 'danger', + type: 'icon', + onClick: ({ name, _kbnMeta: { isLegacy } }: TemplateListItem) => { + setTemplatesToDelete([{ name, isLegacy }]); + }, + isPrimary: true, + enabled: ({ _kbnMeta: { isManaged } }: TemplateListItem) => !isManaged, + }, + ], + }, + ]; + + const pagination = { + initialPageSize: 20, + pageSizeOptions: [10, 20, 50], + }; + + const sorting = { + sort: { + field: 'name', + direction: 'asc', + }, + } as const; + + const selectionConfig = { + onSelectionChange: setSelection, + selectable: ({ _kbnMeta: { isManaged } }: TemplateListItem) => !isManaged, + selectableMessage: (selectable: boolean) => { + if (!selectable) { + return i18n.translate( + 'xpack.idxMgmt.templateList.legacyTable.deleteManagedTemplateTooltip', + { + defaultMessage: 'You cannot delete a managed template.', + } + ); + } + return ''; + }, + }; + + const searchConfig = { + box: { + incremental: true, + }, + toolsLeft: + selection.length > 0 ? ( + + setTemplatesToDelete( + selection.map(({ name, _kbnMeta: { isLegacy } }: TemplateListItem) => ({ + name, + isLegacy, + })) + ) + } + color="danger" + > + + + ) : undefined, + toolsRight: [ + + + , + ], + }; + + return ( + + {templatesToDelete && templatesToDelete.length > 0 ? ( + { + if (data && data.hasDeletedTemplates) { + reload(); + } else { + setTemplatesToDelete([]); + } + }} + templatesToDelete={templatesToDelete} + /> + ) : null} + ({ + 'data-test-subj': 'row', + })} + cellProps={() => ({ + 'data-test-subj': 'cell', + })} + data-test-subj="legacyTemplateTable" + message={ + + } + /> + + ); +}; diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/template_details.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/template_details.tsx index ed403276af564..9f51f114176fb 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/template_details.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/template_details.tsx @@ -4,313 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment, useState } from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; -import { - EuiCallOut, - EuiFlyout, - EuiFlyoutHeader, - EuiTitle, - EuiFlyoutBody, - EuiFlyoutFooter, - EuiFlexGroup, - EuiFlexItem, - EuiButtonEmpty, - EuiTab, - EuiTabs, - EuiSpacer, - EuiPopover, - EuiButton, - EuiContextMenu, -} from '@elastic/eui'; -import { - UIM_TEMPLATE_DETAIL_PANEL_MAPPINGS_TAB, - UIM_TEMPLATE_DETAIL_PANEL_SUMMARY_TAB, - UIM_TEMPLATE_DETAIL_PANEL_SETTINGS_TAB, - UIM_TEMPLATE_DETAIL_PANEL_ALIASES_TAB, -} from '../../../../../../common/constants'; -import { TemplateDeserialized, IndexTemplateFormatVersion } from '../../../../../../common'; -import { TemplateDeleteModal, SectionLoading, SectionError, Error } from '../../../../components'; -import { useLoadIndexTemplate } from '../../../../services/api'; -import { decodePath } from '../../../../services/routing'; -import { SendRequestResponse } from '../../../../../shared_imports'; -import { useServices } from '../../../../app_context'; -import { TabSummary, TabMappings, TabSettings, TabAliases } from './tabs'; +import React from 'react'; -interface Props { - template: { name: string; formatVersion: IndexTemplateFormatVersion }; - onClose: () => void; - editTemplate: (name: string, formatVersion: IndexTemplateFormatVersion) => void; - cloneTemplate: (name: string, formatVersion: IndexTemplateFormatVersion) => void; - reload: () => Promise; -} - -const SUMMARY_TAB_ID = 'summary'; -const MAPPINGS_TAB_ID = 'mappings'; -const ALIASES_TAB_ID = 'aliases'; -const SETTINGS_TAB_ID = 'settings'; - -const TABS = [ - { - id: SUMMARY_TAB_ID, - name: i18n.translate('xpack.idxMgmt.templateDetails.summaryTabTitle', { - defaultMessage: 'Summary', - }), - }, - { - id: SETTINGS_TAB_ID, - name: i18n.translate('xpack.idxMgmt.templateDetails.settingsTabTitle', { - defaultMessage: 'Settings', - }), - }, - { - id: MAPPINGS_TAB_ID, - name: i18n.translate('xpack.idxMgmt.templateDetails.mappingsTabTitle', { - defaultMessage: 'Mappings', - }), - }, - { - id: ALIASES_TAB_ID, - name: i18n.translate('xpack.idxMgmt.templateDetails.aliasesTabTitle', { - defaultMessage: 'Aliases', - }), - }, -]; - -const tabToComponentMap: { - [key: string]: React.FunctionComponent<{ templateDetails: TemplateDeserialized }>; -} = { - [SUMMARY_TAB_ID]: TabSummary, - [SETTINGS_TAB_ID]: TabSettings, - [MAPPINGS_TAB_ID]: TabMappings, - [ALIASES_TAB_ID]: TabAliases, -}; - -const tabToUiMetricMap: { [key: string]: string } = { - [SUMMARY_TAB_ID]: UIM_TEMPLATE_DETAIL_PANEL_SUMMARY_TAB, - [SETTINGS_TAB_ID]: UIM_TEMPLATE_DETAIL_PANEL_SETTINGS_TAB, - [MAPPINGS_TAB_ID]: UIM_TEMPLATE_DETAIL_PANEL_MAPPINGS_TAB, - [ALIASES_TAB_ID]: UIM_TEMPLATE_DETAIL_PANEL_ALIASES_TAB, -}; - -export const TemplateDetails: React.FunctionComponent = ({ - template: { name: templateName, formatVersion }, - onClose, - editTemplate, - cloneTemplate, - reload, -}) => { - const { uiMetricService } = useServices(); - const decodedTemplateName = decodePath(templateName); - const { error, data: templateDetails, isLoading } = useLoadIndexTemplate( - decodedTemplateName, - formatVersion - ); - const isManaged = templateDetails?.isManaged; - const [templateToDelete, setTemplateToDelete] = useState< - Array<{ name: string; formatVersion: IndexTemplateFormatVersion }> - >([]); - const [activeTab, setActiveTab] = useState(SUMMARY_TAB_ID); - const [isPopoverOpen, setIsPopOverOpen] = useState(false); - - let content; - - if (isLoading) { - content = ( - - - - ); - } else if (error) { - content = ( - - } - error={error as Error} - data-test-subj="sectionError" - /> - ); - } else if (templateDetails) { - const Content = tabToComponentMap[activeTab]; - const managedTemplateCallout = isManaged ? ( - - - } - color="primary" - size="s" - > - - - - - ) : null; - - content = ( - - {managedTemplateCallout} - - - {TABS.map((tab) => ( - { - uiMetricService.trackMetric('click', tabToUiMetricMap[tab.id]); - setActiveTab(tab.id); - }} - isSelected={tab.id === activeTab} - key={tab.id} - data-test-subj="tab" - > - {tab.name} - - ))} - - - - - - - ); - } - - return ( - - {templateToDelete && templateToDelete.length > 0 ? ( - { - if (data && data.hasDeletedTemplates) { - reload(); - } else { - setTemplateToDelete([]); - } - onClose(); - }} - templatesToDelete={templateToDelete} - /> - ) : null} - - - - -

- {decodedTemplateName} -

-
-
- - {content} - - - - - - - - - {templateDetails && ( - - {/* Manage templates context menu */} - setIsPopOverOpen((prev) => !prev)} - > - - - } - isOpen={isPopoverOpen} - closePopover={() => setIsPopOverOpen(false)} - panelPaddingSize="none" - withTitle - anchorPosition="rightUp" - repositionOnScroll - > - editTemplate(templateName, formatVersion), - disabled: isManaged, - }, - { - name: i18n.translate('xpack.idxMgmt.templateDetails.cloneButtonLabel', { - defaultMessage: 'Clone', - }), - icon: 'copy', - onClick: () => cloneTemplate(templateName, formatVersion), - }, - { - name: i18n.translate( - 'xpack.idxMgmt.templateDetails.deleteButtonLabel', - { - defaultMessage: 'Delete', - } - ), - icon: 'trash', - onClick: () => - setTemplateToDelete([{ name: decodedTemplateName, formatVersion }]), - disabled: isManaged, - }, - ], - }, - ]} - /> - - - )} - - -
-
- ); +export const TemplateDetails: React.FunctionComponent = () => { + // TODO new (V2) templatte details + return null; }; diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_list.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_list.tsx index db0833ea03233..fc3d5125e3066 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_list.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_list.tsx @@ -7,19 +7,20 @@ import React, { Fragment, useState, useEffect, useMemo } from 'react'; import { RouteComponentProps } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; import { ScopedHistory } from 'kibana/public'; import { EuiEmptyPrompt, EuiSpacer, EuiTitle, EuiText, - EuiSwitch, EuiFlexItem, EuiFlexGroup, + EuiButton, } from '@elastic/eui'; import { UIM_TEMPLATE_LIST_LOAD } from '../../../../../common/constants'; -import { IndexTemplateFormatVersion } from '../../../../../common'; +import { TemplateListItem } from '../../../../../common'; import { SectionError, SectionLoading, Error } from '../../../components'; import { useLoadIndexTemplates } from '../../../services/api'; import { useServices } from '../../../app_context'; @@ -28,14 +29,20 @@ import { getTemplateListLink, getTemplateCloneLink, } from '../../../services/routing'; -import { getFormatVersionFromQueryparams } from '../../../lib/index_templates'; +import { getIsLegacyFromQueryParams } from '../../../lib/index_templates'; import { TemplateTable } from './template_table'; -import { TemplateDetails } from './template_details'; +import { LegacyTemplateTable } from './legacy_templates/template_table'; +import { LegacyTemplateDetails } from './legacy_templates/template_details'; +import { FilterListButton, Filters } from './components'; +type FilterName = 'composable' | 'system'; interface MatchParams { templateName?: string; } +const stripOutSystemTemplates = (templates: TemplateListItem[]): TemplateListItem[] => + templates.filter((template) => !template.name.startsWith('.')); + export const TemplateList: React.FunctionComponent> = ({ match: { params: { templateName }, @@ -44,122 +51,188 @@ export const TemplateList: React.FunctionComponent { const { uiMetricService } = useServices(); - const { error, isLoading, data: templates, sendRequest: reload } = useLoadIndexTemplates(); - const queryParamsFormatVersion = getFormatVersionFromQueryparams(location); + const { error, isLoading, data: allTemplates, sendRequest: reload } = useLoadIndexTemplates(); - let content; + const [filters, setFilters] = useState>({ + composable: { + name: i18n.translate('xpack.idxMgmt.indexTemplatesList.viewComposableTemplateLabel', { + defaultMessage: 'Composable templates', + }), + checked: 'on', + }, + system: { + name: i18n.translate('xpack.idxMgmt.indexTemplatesList.viewSystemTemplateLabel', { + defaultMessage: 'System templates', + }), + checked: 'off', + }, + }); - const [showSystemTemplates, setShowSystemTemplates] = useState(false); + const filteredTemplates = useMemo(() => { + if (!allTemplates) { + return { templates: [], legacyTemplates: [] }; + } - // Filter out system index templates - const filteredTemplates = useMemo( - () => (templates ? templates.filter((template) => !template.name.startsWith('.')) : []), - [templates] - ); + return filters.system.checked === 'on' + ? allTemplates + : { + templates: stripOutSystemTemplates(allTemplates.templates), + legacyTemplates: stripOutSystemTemplates(allTemplates.legacyTemplates), + }; + }, [allTemplates, filters.system.checked]); + + const showComposableTemplateTable = filters.composable.checked === 'on'; + + const selectedTemplate = Boolean(templateName) + ? { + name: templateName!, + isLegacy: getIsLegacyFromQueryParams(location), + } + : null; + + const isLegacyTemplateDetailsVisible = selectedTemplate !== null && selectedTemplate.isLegacy; + const hasTemplates = + allTemplates && (allTemplates.legacyTemplates.length > 0 || allTemplates.templates.length > 0); const closeTemplateDetails = () => { history.push(getTemplateListLink()); }; - const editTemplate = (name: string, formatVersion: IndexTemplateFormatVersion) => { - history.push(getTemplateEditLink(name, formatVersion)); + const editTemplate = (name: string, isLegacy?: boolean) => { + history.push(getTemplateEditLink(name, isLegacy)); }; - const cloneTemplate = (name: string, formatVersion: IndexTemplateFormatVersion) => { - history.push(getTemplateCloneLink(name, formatVersion)); + const cloneTemplate = (name: string, isLegacy?: boolean) => { + history.push(getTemplateCloneLink(name, isLegacy)); }; - // Track component loaded - useEffect(() => { - uiMetricService.trackMetric('loaded', UIM_TEMPLATE_LIST_LOAD); - }, [uiMetricService]); + const renderHeader = () => ( + + + + + + + + + + filters={filters} onChange={setFilters} /> + + + + + + + + ); - if (isLoading) { - content = ( - - - - ); - } else if (error) { - content = ( - + showComposableTemplateTable ? ( + <> + + + + ) : null; + + const renderLegacyTemplatesTable = () => ( + <> + + +

- } - error={error as Error} +

+
+ + - ); - } else if (Array.isArray(templates) && templates.length === 0) { - content = ( - + + ); + + const renderContent = () => { + if (isLoading) { + return ( + + + + ); + } else if (error) { + return ( + - - } - data-test-subj="emptyPrompt" - /> - ); - } else if (Array.isArray(templates) && templates.length > 0) { - content = ( - - - - - - - - - - - setShowSystemTemplates(event.target.checked)} - label={ - - } - /> - - - - + ); + } else if (!hasTemplates) { + return ( + + + + } + data-test-subj="emptyPrompt" /> - - ); - } + ); + } else { + return ( + + {/* Header */} + {renderHeader()} + + {/* Composable index templates table */} + {renderTemplatesTable()} + + {/* Legacy index templates table */} + {renderLegacyTemplatesTable()} + + ); + } + }; + + // Track component loaded + useEffect(() => { + uiMetricService.trackMetric('loaded', UIM_TEMPLATE_LIST_LOAD); + }, [uiMetricService]); return (
- {content} - {templateName && queryParamsFormatVersion !== undefined && ( - Promise; - editTemplate: (name: string, formatVersion: IndexTemplateFormatVersion) => void; - cloneTemplate: (name: string, formatVersion: IndexTemplateFormatVersion) => void; - history: ScopedHistory; } -export const TemplateTable: React.FunctionComponent = ({ - templates, - reload, - editTemplate, - cloneTemplate, - history, -}) => { - const { uiMetricService } = useServices(); - const [selection, setSelection] = useState([]); +export const TemplateTable: React.FunctionComponent = ({ templates, reload }) => { const [templatesToDelete, setTemplatesToDelete] = useState< - Array<{ name: string; formatVersion: IndexTemplateFormatVersion }> + Array<{ name: string; isLegacy?: boolean }> >([]); const columns: Array> = [ @@ -45,24 +31,6 @@ export const TemplateTable: React.FunctionComponent = ({ }), truncateText: true, sortable: true, - render: (name: TemplateListItem['name'], item: TemplateListItem) => { - return ( - /* eslint-disable-next-line @elastic/eui/href-or-on-click */ - uiMetricService.trackMetric('click', UIM_TEMPLATE_SHOW_DETAILS_CLICK) - )} - data-test-subj="templateDetailsLink" - > - {name} - - ); - }, }, { field: 'indexPatterns', @@ -95,90 +63,36 @@ export const TemplateTable: React.FunctionComponent = ({ ) : null, }, { - field: 'order', - name: i18n.translate('xpack.idxMgmt.templateList.table.orderColumnTitle', { - defaultMessage: 'Order', + field: 'composedOf', + name: i18n.translate('xpack.idxMgmt.templateList.table.componentsColumnTitle', { + defaultMessage: 'Components', }), truncateText: true, sortable: true, + render: (composedOf: string[] = []) => {composedOf.join(', ')}, }, { - field: 'hasMappings', - name: i18n.translate('xpack.idxMgmt.templateList.table.mappingsColumnTitle', { - defaultMessage: 'Mappings', + field: 'priority', + name: i18n.translate('xpack.idxMgmt.templateList.table.priorityColumnTitle', { + defaultMessage: 'Priority', }), truncateText: true, sortable: true, - render: (hasMappings: boolean) => (hasMappings ? : null), }, { - field: 'hasSettings', - name: i18n.translate('xpack.idxMgmt.templateList.table.settingsColumnTitle', { - defaultMessage: 'Settings', - }), - truncateText: true, - sortable: true, - render: (hasSettings: boolean) => (hasSettings ? : null), - }, - { - field: 'hasAliases', - name: i18n.translate('xpack.idxMgmt.templateList.table.aliasesColumnTitle', { - defaultMessage: 'Aliases', + field: 'hasMappings', + name: i18n.translate('xpack.idxMgmt.templateList.table.overridesColumnTitle', { + defaultMessage: 'Overrides', }), truncateText: true, - sortable: true, - render: (hasAliases: boolean) => (hasAliases ? : null), - }, - { - name: i18n.translate('xpack.idxMgmt.templateList.table.actionColumnTitle', { - defaultMessage: 'Actions', - }), - actions: [ - { - name: i18n.translate('xpack.idxMgmt.templateList.table.actionEditText', { - defaultMessage: 'Edit', - }), - isPrimary: true, - description: i18n.translate('xpack.idxMgmt.templateList.table.actionEditDecription', { - defaultMessage: 'Edit this template', - }), - icon: 'pencil', - type: 'icon', - onClick: ({ name, _kbnMeta: { formatVersion } }: TemplateListItem) => { - editTemplate(name, formatVersion); - }, - enabled: ({ isManaged }: TemplateListItem) => !isManaged, - }, - { - type: 'icon', - name: i18n.translate('xpack.idxMgmt.templateList.table.actionCloneTitle', { - defaultMessage: 'Clone', - }), - description: i18n.translate('xpack.idxMgmt.templateList.table.actionCloneDescription', { - defaultMessage: 'Clone this template', - }), - icon: 'copy', - onClick: ({ name, _kbnMeta: { formatVersion } }: TemplateListItem) => { - cloneTemplate(name, formatVersion); - }, - }, - { - name: i18n.translate('xpack.idxMgmt.templateList.table.actionDeleteText', { - defaultMessage: 'Delete', - }), - description: i18n.translate('xpack.idxMgmt.templateList.table.actionDeleteDecription', { - defaultMessage: 'Delete this template', - }), - icon: 'trash', - color: 'danger', - type: 'icon', - onClick: ({ name, _kbnMeta: { formatVersion } }: TemplateListItem) => { - setTemplatesToDelete([{ name, formatVersion }]); - }, - isPrimary: true, - enabled: ({ isManaged }: TemplateListItem) => !isManaged, - }, - ], + sortable: false, + render: (_, item) => ( + + ), }, ]; @@ -194,70 +108,10 @@ export const TemplateTable: React.FunctionComponent = ({ }, } as const; - const selectionConfig = { - onSelectionChange: setSelection, - selectable: ({ isManaged }: TemplateListItem) => !isManaged, - selectableMessage: (selectable: boolean) => { - if (!selectable) { - return i18n.translate('xpack.idxMgmt.templateList.table.deleteManagedTemplateTooltip', { - defaultMessage: 'You cannot delete a managed template.', - }); - } - return ''; - }, - }; - const searchConfig = { box: { incremental: true, }, - toolsLeft: - selection.length > 0 ? ( - - setTemplatesToDelete( - selection.map(({ name, _kbnMeta: { formatVersion } }: TemplateListItem) => ({ - name, - formatVersion, - })) - ) - } - color="danger" - > - - - ) : undefined, - toolsRight: [ - - - , - - - , - ], }; return ( @@ -280,8 +134,7 @@ export const TemplateTable: React.FunctionComponent = ({ columns={columns} search={searchConfig} sorting={sorting} - isSelectable={true} - selection={selectionConfig} + isSelectable={false} pagination={pagination} rowProps={() => ({ 'data-test-subj': 'row', diff --git a/x-pack/plugins/index_management/public/application/sections/template_clone/template_clone.tsx b/x-pack/plugins/index_management/public/application/sections/template_clone/template_clone.tsx index b69e441feb176..8bdd230f89952 100644 --- a/x-pack/plugins/index_management/public/application/sections/template_clone/template_clone.tsx +++ b/x-pack/plugins/index_management/public/application/sections/template_clone/template_clone.tsx @@ -8,12 +8,12 @@ import { RouteComponentProps } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiPageBody, EuiPageContent, EuiSpacer, EuiTitle } from '@elastic/eui'; -import { TemplateDeserialized, DEFAULT_INDEX_TEMPLATE_VERSION_FORMAT } from '../../../../common'; +import { TemplateDeserialized } from '../../../../common'; import { TemplateForm, SectionLoading, SectionError, Error } from '../../components'; import { breadcrumbService } from '../../services/breadcrumbs'; import { decodePath, getTemplateDetailsLink } from '../../services/routing'; import { saveTemplate, useLoadIndexTemplate } from '../../services/api'; -import { getFormatVersionFromQueryparams } from '../../lib/index_templates'; +import { getIsLegacyFromQueryParams } from '../../lib/index_templates'; interface MatchParams { name: string; @@ -27,14 +27,13 @@ export const TemplateClone: React.FunctionComponent { const decodedTemplateName = decodePath(name); - const formatVersion = - getFormatVersionFromQueryparams(location) ?? DEFAULT_INDEX_TEMPLATE_VERSION_FORMAT; + const isLegacy = getIsLegacyFromQueryParams(location); const [isSaving, setIsSaving] = useState(false); const [saveError, setSaveError] = useState(null); const { error: templateToCloneError, data: templateToClone, isLoading } = useLoadIndexTemplate( decodedTemplateName, - formatVersion + isLegacy ); const onSave = async (template: TemplateDeserialized) => { @@ -52,7 +51,7 @@ export const TemplateClone: React.FunctionComponent { diff --git a/x-pack/plugins/index_management/public/application/sections/template_create/template_create.tsx b/x-pack/plugins/index_management/public/application/sections/template_create/template_create.tsx index 27341685f3dc0..f567b9835d53d 100644 --- a/x-pack/plugins/index_management/public/application/sections/template_create/template_create.tsx +++ b/x-pack/plugins/index_management/public/application/sections/template_create/template_create.tsx @@ -33,7 +33,7 @@ export const TemplateCreate: React.FunctionComponent = ({ h return; } - history.push(getTemplateDetailsLink(name, template._kbnMeta.formatVersion)); + history.push(getTemplateDetailsLink(name, template._kbnMeta.isLegacy)); }; const clearSaveError = () => { diff --git a/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx b/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx index 9ad26d0af802d..d3e539989bc96 100644 --- a/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx +++ b/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx @@ -8,12 +8,12 @@ import { RouteComponentProps } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiPageBody, EuiPageContent, EuiTitle, EuiSpacer, EuiCallOut } from '@elastic/eui'; -import { TemplateDeserialized, DEFAULT_INDEX_TEMPLATE_VERSION_FORMAT } from '../../../../common'; +import { TemplateDeserialized } from '../../../../common'; import { breadcrumbService } from '../../services/breadcrumbs'; import { useLoadIndexTemplate, updateTemplate } from '../../services/api'; import { decodePath, getTemplateDetailsLink } from '../../services/routing'; import { SectionLoading, SectionError, TemplateForm, Error } from '../../components'; -import { getFormatVersionFromQueryparams } from '../../lib/index_templates'; +import { getIsLegacyFromQueryParams } from '../../lib/index_templates'; interface MatchParams { name: string; @@ -27,16 +27,12 @@ export const TemplateEdit: React.FunctionComponent { const decodedTemplateName = decodePath(name); - const formatVersion = - getFormatVersionFromQueryparams(location) ?? DEFAULT_INDEX_TEMPLATE_VERSION_FORMAT; + const isLegacy = getIsLegacyFromQueryParams(location); const [isSaving, setIsSaving] = useState(false); const [saveError, setSaveError] = useState(null); - const { error, data: template, isLoading } = useLoadIndexTemplate( - decodedTemplateName, - formatVersion - ); + const { error, data: template, isLoading } = useLoadIndexTemplate(decodedTemplateName, isLegacy); useEffect(() => { breadcrumbService.setBreadcrumbs('templateEdit'); @@ -55,7 +51,7 @@ export const TemplateEdit: React.FunctionComponent { @@ -87,7 +83,10 @@ export const TemplateEdit: React.FunctionComponent ); } else if (template) { - const { name: templateName, isManaged } = template; + const { + name: templateName, + _kbnMeta: { isManaged }, + } = template; const isSystemTemplate = templateName && templateName.startsWith('.'); if (isManaged) { diff --git a/x-pack/plugins/index_management/public/application/services/api.ts b/x-pack/plugins/index_management/public/application/services/api.ts index 181707b3661b4..3961942b83ea3 100644 --- a/x-pack/plugins/index_management/public/application/services/api.ts +++ b/x-pack/plugins/index_management/public/application/services/api.ts @@ -37,11 +37,7 @@ import { TAB_SETTINGS, TAB_MAPPING, TAB_STATS } from '../constants'; import { useRequest, sendRequest } from './use_request'; import { httpService } from './http'; import { UiMetricService } from './ui_metric'; -import { - TemplateDeserialized, - TemplateListItem, - IndexTemplateFormatVersion, -} from '../../../common'; +import { TemplateDeserialized, TemplateListItem } from '../../../common'; import { IndexMgmtMetricsType } from '../../types'; // Temporary hack to provide the uiMetricService instance to this file. @@ -214,17 +210,15 @@ export async function loadIndexData(type: string, indexName: string) { } export function useLoadIndexTemplates() { - return useRequest({ - path: `${API_BASE_PATH}/templates`, + return useRequest<{ templates: TemplateListItem[]; legacyTemplates: TemplateListItem[] }>({ + path: `${API_BASE_PATH}/index-templates`, method: 'get', }); } -export async function deleteTemplates( - templates: Array<{ name: string; formatVersion: IndexTemplateFormatVersion }> -) { +export async function deleteTemplates(templates: Array<{ name: string; isLegacy?: boolean }>) { const result = sendRequest({ - path: `${API_BASE_PATH}/delete-templates`, + path: `${API_BASE_PATH}/delete-index-templates`, method: 'post', body: { templates }, }); @@ -236,23 +230,20 @@ export async function deleteTemplates( return result; } -export function useLoadIndexTemplate( - name: TemplateDeserialized['name'], - formatVersion: IndexTemplateFormatVersion -) { +export function useLoadIndexTemplate(name: TemplateDeserialized['name'], isLegacy?: boolean) { return useRequest({ - path: `${API_BASE_PATH}/templates/${encodeURIComponent(name)}`, + path: `${API_BASE_PATH}/index-templates/${encodeURIComponent(name)}`, method: 'get', query: { - v: formatVersion, + legacy: isLegacy, }, }); } export async function saveTemplate(template: TemplateDeserialized, isClone?: boolean) { const result = await sendRequest({ - path: `${API_BASE_PATH}/templates`, - method: 'put', + path: `${API_BASE_PATH}/index-templates`, + method: 'post', body: JSON.stringify(template), }); @@ -266,7 +257,7 @@ export async function saveTemplate(template: TemplateDeserialized, isClone?: boo export async function updateTemplate(template: TemplateDeserialized) { const { name } = template; const result = await sendRequest({ - path: `${API_BASE_PATH}/templates/${encodeURIComponent(name)}`, + path: `${API_BASE_PATH}/index-templates/${encodeURIComponent(name)}`, method: 'put', body: JSON.stringify(template), }); diff --git a/x-pack/plugins/index_management/public/application/services/routing.ts b/x-pack/plugins/index_management/public/application/services/routing.ts index fe118b1181082..a999c58f5bb42 100644 --- a/x-pack/plugins/index_management/public/application/services/routing.ts +++ b/x-pack/plugins/index_management/public/application/services/routing.ts @@ -3,33 +3,29 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { IndexTemplateFormatVersion } from '../../../common'; -export const getTemplateListLink = () => { - return `/templates`; -}; +export const getTemplateListLink = () => `/templates`; // Need to add some additonal encoding/decoding logic to work with React Router // For background, see: https://github.com/ReactTraining/history/issues/505 -export const getTemplateDetailsLink = ( - name: string, - formatVersion: IndexTemplateFormatVersion, - withHash = false -) => { - const baseUrl = `/templates/${encodeURIComponent(encodeURIComponent(name))}?v=${formatVersion}`; - const url = withHash ? `#${baseUrl}` : baseUrl; +export const getTemplateDetailsLink = (name: string, isLegacy?: boolean, withHash = false) => { + const baseUrl = `/templates/${encodeURIComponent(encodeURIComponent(name))}`; + let url = withHash ? `#${baseUrl}` : baseUrl; + if (isLegacy) { + url = `${url}?legacy=${isLegacy}`; + } return encodeURI(url); }; -export const getTemplateEditLink = (name: string, formatVersion: IndexTemplateFormatVersion) => { +export const getTemplateEditLink = (name: string, isLegacy?: boolean) => { return encodeURI( - `/edit_template/${encodeURIComponent(encodeURIComponent(name))}?v=${formatVersion}` + `/edit_template/${encodeURIComponent(encodeURIComponent(name))}?legacy=${isLegacy === true}` ); }; -export const getTemplateCloneLink = (name: string, formatVersion: IndexTemplateFormatVersion) => { +export const getTemplateCloneLink = (name: string, isLegacy?: boolean) => { return encodeURI( - `/clone_template/${encodeURIComponent(encodeURIComponent(name))}?v=${formatVersion}` + `/clone_template/${encodeURIComponent(encodeURIComponent(name))}?legacy=${isLegacy === true}` ); }; diff --git a/x-pack/plugins/index_management/public/application/services/sort_table.ts b/x-pack/plugins/index_management/public/application/services/sort_table.ts index ed8c5bb146f53..429f2961c4521 100644 --- a/x-pack/plugins/index_management/public/application/services/sort_table.ts +++ b/x-pack/plugins/index_management/public/application/services/sort_table.ts @@ -14,7 +14,8 @@ type SortField = | 'replica' | 'documents' | 'size' - | 'primary_size'; + | 'primary_size' + | 'data_stream'; type Unit = 'kb' | 'mb' | 'gb' | 'tb' | 'pb'; @@ -55,6 +56,7 @@ const sorters = { documents: numericSort('documents'), size: byteSort('size'), primary_size: byteSort('primary_size'), + data_stream: stringSort('data_stream'), }; export const sortTable = (array = [], sortField: SortField, isSortAscending: boolean) => { diff --git a/x-pack/plugins/index_management/public/application/store/actions/reload_indices.js b/x-pack/plugins/index_management/public/application/store/actions/reload_indices.js index 11329ece8f59f..d70e811ff24e5 100644 --- a/x-pack/plugins/index_management/public/application/store/actions/reload_indices.js +++ b/x-pack/plugins/index_management/public/application/store/actions/reload_indices.js @@ -6,15 +6,13 @@ import { createAction } from 'redux-actions'; import { i18n } from '@kbn/i18n'; -import { getIndexNamesForCurrentPage } from '../selectors'; import { reloadIndices as request } from '../../services'; import { loadIndices } from './load_indices'; import { notificationService } from '../../services/notification'; export const reloadIndicesSuccess = createAction('INDEX_MANAGEMENT_RELOAD_INDICES_SUCCESS'); -export const reloadIndices = (indexNames) => async (dispatch, getState) => { +export const reloadIndices = (indexNames) => async (dispatch) => { let indices; - indexNames = indexNames || getIndexNamesForCurrentPage(getState()); try { indices = await request(indexNames); } catch (error) { diff --git a/x-pack/plugins/index_management/public/application/store/actions/table_state.js b/x-pack/plugins/index_management/public/application/store/actions/table_state.js index 70e0de74d0278..2127d8cd36b1e 100644 --- a/x-pack/plugins/index_management/public/application/store/actions/table_state.js +++ b/x-pack/plugins/index_management/public/application/store/actions/table_state.js @@ -17,8 +17,4 @@ export const pageSizeChanged = createAction('INDEX_MANAGEMENT_PAGE_SIZE_CHANGED' export const sortChanged = createAction('INDEX_MANAGEMENT_SORT_CHANGED'); -export const showHiddenIndicesChanged = createAction( - 'INDEX_MANAGEMENT_SHOW_HIDDEN_INDICES_CHANGED' -); - export const toggleChanged = createAction('INDEX_MANAGEMENT_TOGGLE_CHANGED'); diff --git a/x-pack/plugins/index_management/public/application/store/middlewares/index.ts b/x-pack/plugins/index_management/public/application/store/middlewares/index.ts deleted file mode 100644 index 06d77a9c3d348..0000000000000 --- a/x-pack/plugins/index_management/public/application/store/middlewares/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { syncUrlHashQueryParam } from './sync_url_hash_query_param.js'; diff --git a/x-pack/plugins/index_management/public/application/store/middlewares/sync_url_hash_query_param.js.ts b/x-pack/plugins/index_management/public/application/store/middlewares/sync_url_hash_query_param.js.ts deleted file mode 100644 index 145b4b6c9a8bc..0000000000000 --- a/x-pack/plugins/index_management/public/application/store/middlewares/sync_url_hash_query_param.js.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import * as q from 'query-string'; -import { Middleware } from 'redux'; -// @ts-ignore -import { showHiddenIndicesChanged } from '../actions'; - -export const syncUrlHashQueryParam: Middleware = () => (next) => (action) => { - if (action.type === String(showHiddenIndicesChanged)) { - const { url, query } = q.parseUrl(window.location.hash); - if (action.payload.showHiddenIndices) { - query.includeHidden = 'true'; - } else { - delete query.includeHidden; - } - window.location.hash = url + '?' + q.stringify(query); - } - next(action); -}; diff --git a/x-pack/plugins/index_management/public/application/store/reducers/table_state.js b/x-pack/plugins/index_management/public/application/store/reducers/table_state.js index e90fa72aa62fe..bfb37aa56b129 100644 --- a/x-pack/plugins/index_management/public/application/store/reducers/table_state.js +++ b/x-pack/plugins/index_management/public/application/store/reducers/table_state.js @@ -10,7 +10,6 @@ import { pageChanged, pageSizeChanged, sortChanged, - showHiddenIndicesChanged, toggleChanged, } from '../actions'; @@ -20,7 +19,6 @@ export const defaultTableState = { currentPage: 0, sortField: 'index.name', isSortAscending: true, - showHiddenIndices: false, }; export const tableState = handleActions( @@ -33,14 +31,6 @@ export const tableState = handleActions( currentPage: 0, }; }, - [showHiddenIndicesChanged](state, action) { - const { showHiddenIndices } = action.payload; - - return { - ...state, - showHiddenIndices, - }; - }, [toggleChanged](state, action) { const { toggleName, toggleValue } = action.payload; const toggleNameToVisibleMap = { ...state.toggleNameToVisibleMap }; diff --git a/x-pack/plugins/index_management/public/application/store/selectors/index.d.ts b/x-pack/plugins/index_management/public/application/store/selectors/index.d.ts index 999b11c5d6665..37aaea0e7e3d8 100644 --- a/x-pack/plugins/index_management/public/application/store/selectors/index.d.ts +++ b/x-pack/plugins/index_management/public/application/store/selectors/index.d.ts @@ -6,3 +6,5 @@ import { ExtensionsService } from '../../../services'; export declare function setExtensionsService(extensionsService: ExtensionsService): any; + +export const getFilteredIndices: (state: any, props: any) => any; diff --git a/x-pack/plugins/index_management/public/application/store/selectors/index.js b/x-pack/plugins/index_management/public/application/store/selectors/index.js index c1011680d4da2..c80658581dbee 100644 --- a/x-pack/plugins/index_management/public/application/store/selectors/index.js +++ b/x-pack/plugins/index_management/public/application/store/selectors/index.js @@ -6,6 +6,7 @@ import { Pager, EuiSearchBar } from '@elastic/eui'; import { createSelector } from 'reselect'; +import * as qs from 'query-string'; import { indexStatusLabels } from '../../lib/index_status_labels'; import { sortTable } from '../../services'; @@ -35,6 +36,7 @@ export const getIndexByIndexName = (state, name) => getIndices(state)[name]; export const getFilteredIds = (state) => state.indices.filteredIds; export const getRowStatuses = (state) => state.rowStatus; export const getTableState = (state) => state.tableState; +export const getTableLocationProp = (_, props) => props.location; export const getAllIds = (state) => state.indices.allIds; export const getIndexStatusByIndexName = (state, indexName) => { const indices = getIndices(state); @@ -79,18 +81,24 @@ const filterByToggles = (indices, toggleNameToVisibleMap) => { }); }); }; -const getFilteredIndices = createSelector( + +export const getFilteredIndices = createSelector( getIndices, getAllIds, getTableState, - (indices, allIds, tableState) => { + getTableLocationProp, + (indices, allIds, tableState, tableLocation) => { let indexArray = allIds.map((indexName) => indices[indexName]); indexArray = filterByToggles(indexArray, tableState.toggleNameToVisibleMap); - const systemFilteredIndexes = tableState.showHiddenIndices + const { includeHiddenIndices: includeHiddenParam } = qs.parse(tableLocation.search); + const includeHidden = includeHiddenParam === 'true'; + const filteredIndices = includeHidden ? indexArray - : indexArray.filter((index) => !(index.name + '').startsWith('.') && !index.hidden); + : indexArray.filter((index) => { + return !(index.name + '').startsWith('.') && !index.hidden; + }); const filter = tableState.filter || EuiSearchBar.Query.MATCH_ALL; - return EuiSearchBar.Query.execute(filter, systemFilteredIndexes, { + return EuiSearchBar.Query.execute(filter, filteredIndices, { defaultFields: defaultFilterFields, }); } @@ -133,29 +141,8 @@ export const getPageOfIndices = createSelector( } ); -export const getIndexNamesForCurrentPage = createSelector(getPageOfIndices, (pageOfIndices) => { - return pageOfIndices.map((index) => index.name); -}); - -export const getHasNextPage = createSelector(getPager, (pager) => { - return pager.hasNextPage; -}); - -export const getHasPreviousPage = createSelector(getPager, (pager) => { - return pager.hasPreviousPage; -}); - -export const getCurrentPage = createSelector(getPager, (pager) => { - return pager.currentPage; -}); - export const getFilter = createSelector(getTableState, ({ filter }) => filter); -export const showHiddenIndices = createSelector( - getTableState, - ({ showHiddenIndices }) => showHiddenIndices -); - export const isSortAscending = createSelector( getTableState, ({ isSortAscending }) => isSortAscending diff --git a/x-pack/plugins/index_management/public/application/store/selectors/indices_filter.test.ts b/x-pack/plugins/index_management/public/application/store/selectors/indices_filter.test.ts new file mode 100644 index 0000000000000..f230ddd18e9eb --- /dev/null +++ b/x-pack/plugins/index_management/public/application/store/selectors/indices_filter.test.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { ExtensionsService } from '../../../services'; +import { getFilteredIndices, setExtensionsService } from '.'; +// @ts-ignore +import { defaultTableState } from '../reducers/table_state'; + +describe('getFilteredIndices selector', () => { + let extensionService: ExtensionsService; + beforeAll(() => { + extensionService = new ExtensionsService(); + extensionService.setup(); + setExtensionsService(extensionService); + }); + + const state = { + tableState: { ...defaultTableState }, + indices: { + byId: { + test: { name: 'index1', hidden: true }, + anotherTest: { name: 'index2', hidden: false }, + aTest: { name: 'index3' }, + aFinalTest: { name: '.index4' }, + }, + allIds: ['test', 'anotherTest', 'aTest', 'aFinalTest'], + }, + }; + + it('filters out hidden indices', () => { + expect(getFilteredIndices(state, { location: { search: '' } })).toEqual([ + { name: 'index2', hidden: false }, + { name: 'index3' }, + ]); + }); + + it('includes hidden indices', () => { + expect( + getFilteredIndices(state, { location: { search: '?includeHiddenIndices=true' } }) + ).toEqual([ + { name: 'index1', hidden: true }, + { name: 'index2', hidden: false }, + { name: 'index3' }, + { name: '.index4' }, + ]); + }); +}); diff --git a/x-pack/plugins/index_management/public/application/store/store.js b/x-pack/plugins/index_management/public/application/store/store.js index d2f24d50941c6..b189a7cf38938 100644 --- a/x-pack/plugins/index_management/public/application/store/store.js +++ b/x-pack/plugins/index_management/public/application/store/store.js @@ -9,7 +9,6 @@ import thunk from 'redux-thunk'; import { defaultTableState } from './reducers/table_state'; import { getReducer } from './reducers/'; -import { syncUrlHashQueryParam } from './middlewares'; export function indexManagementStore(services) { const toggleNameToVisibleMap = {}; @@ -17,7 +16,7 @@ export function indexManagementStore(services) { toggleNameToVisibleMap[toggleExtension.name] = false; }); const initialState = { tableState: { ...defaultTableState, toggleNameToVisibleMap } }; - const enhancers = [applyMiddleware(thunk, syncUrlHashQueryParam)]; + const enhancers = [applyMiddleware(thunk)]; window.__REDUX_DEVTOOLS_EXTENSION__ && enhancers.push(window.__REDUX_DEVTOOLS_EXTENSION__()); return createStore(getReducer(services), initialState, compose(...enhancers)); diff --git a/x-pack/plugins/index_management/server/lib/fetch_indices.ts b/x-pack/plugins/index_management/server/lib/fetch_indices.ts index b52a63a414967..ae10629e069e8 100644 --- a/x-pack/plugins/index_management/server/lib/fetch_indices.ts +++ b/x-pack/plugins/index_management/server/lib/fetch_indices.ts @@ -23,6 +23,7 @@ interface Hit { interface IndexInfo { aliases: { [aliasName: string]: unknown }; mappings: unknown; + data_stream?: string; settings: { index: { hidden: 'true' | 'false'; @@ -87,6 +88,7 @@ async function fetchIndicesCall( isFrozen: hit.sth === 'true', // sth value coming back as a string from ES aliases: aliases.length ? aliases : 'none', hidden: index.settings.index.hidden === 'true', + data_stream: index.data_stream, }; }); } diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_create_route.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_create_route.ts index 1409fa8af2ceb..26e74847e3e05 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_create_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_create_route.ts @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; import { TemplateDeserialized } from '../../../../common'; -import { serializeV1Template } from '../../../../common/lib'; +import { serializeLegacyTemplate } from '../../../../common/lib'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '../index'; import { templateSchema } from './validate_schemas'; @@ -15,35 +15,26 @@ import { templateSchema } from './validate_schemas'; const bodySchema = templateSchema; export function registerCreateRoute({ router, license, lib }: RouteDependencies) { - router.put( - { path: addBasePath('/templates'), validate: { body: bodySchema } }, + router.post( + { path: addBasePath('/index-templates'), validate: { body: bodySchema } }, license.guardApiRoute(async (ctx, req, res) => { const { callAsCurrentUser } = ctx.core.elasticsearch.legacy.client; const template = req.body as TemplateDeserialized; const { - _kbnMeta: { formatVersion }, + _kbnMeta: { isLegacy }, } = template; - if (formatVersion !== 1) { - return res.badRequest({ body: 'Only index template version 1 can be created.' }); + if (!isLegacy) { + return res.badRequest({ body: 'Only legacy index templates can be created.' }); } - // For now we format to V1 index templates. - // When the V2 API is ready we will only create V2 template format. - const serializedTemplate = serializeV1Template(template); - - const { - name, - order, - index_patterns, - version, - settings, - mappings, - aliases, - } = serializedTemplate; + const serializedTemplate = serializeLegacyTemplate(template); + const { order, index_patterns, version, settings, mappings, aliases } = serializedTemplate; // Check that template with the same name doesn't already exist - const templateExists = await callAsCurrentUser('indices.existsTemplate', { name }); + const templateExists = await callAsCurrentUser('indices.existsTemplate', { + name: template.name, + }); if (templateExists) { return res.conflict({ @@ -51,7 +42,7 @@ export function registerCreateRoute({ router, license, lib }: RouteDependencies) i18n.translate('xpack.idxMgmt.createRoute.duplicateTemplateIdErrorMessage', { defaultMessage: "There is already a template with name '{name}'.", values: { - name, + name: template.name, }, }) ), @@ -61,7 +52,7 @@ export function registerCreateRoute({ router, license, lib }: RouteDependencies) try { // Otherwise create new index template const response = await callAsCurrentUser('indices.putTemplate', { - name, + name: template.name, order, body: { index_patterns, diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts index 3dc31482b4947..b5cc00ad6d8cc 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_delete_route.ts @@ -16,7 +16,7 @@ const bodySchema = schema.object({ templates: schema.arrayOf( schema.object({ name: schema.string(), - formatVersion: schema.oneOf([schema.literal(1), schema.literal(2)]), + isLegacy: schema.maybe(schema.boolean()), }) ), }); @@ -24,7 +24,7 @@ const bodySchema = schema.object({ export function registerDeleteRoute({ router, license }: RouteDependencies) { router.post( { - path: addBasePath('/delete-templates'), + path: addBasePath('/delete-index-templates'), validate: { body: bodySchema }, }, license.guardApiRoute(async (ctx, req, res) => { @@ -35,10 +35,10 @@ export function registerDeleteRoute({ router, license }: RouteDependencies) { }; await Promise.all( - templates.map(async ({ name, formatVersion }) => { + templates.map(async ({ name, isLegacy }) => { try { - if (formatVersion !== 1) { - return res.badRequest({ body: 'Only index template version 1 can be deleted.' }); + if (!isLegacy) { + return res.badRequest({ body: 'Only legacy index template can be deleted.' }); } await ctx.core.elasticsearch.legacy.client.callAsCurrentUser('indices.deleteTemplate', { diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts index b18a8d88d3a4a..12ec005258a62 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_get_routes.ts @@ -5,20 +5,38 @@ */ import { schema, TypeOf } from '@kbn/config-schema'; -import { deserializeV1Template, deserializeTemplateList } from '../../../../common/lib'; +import { + deserializeLegacyTemplate, + deserializeLegacyTemplateList, + deserializeTemplateList, +} from '../../../../common/lib'; import { getManagedTemplatePrefix } from '../../../lib/get_managed_templates'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '../index'; export function registerGetAllRoute({ router, license }: RouteDependencies) { router.get( - { path: addBasePath('/templates'), validate: false }, + { path: addBasePath('/index-templates'), validate: false }, license.guardApiRoute(async (ctx, req, res) => { const { callAsCurrentUser } = ctx.core.elasticsearch.legacy.client; const managedTemplatePrefix = await getManagedTemplatePrefix(callAsCurrentUser); - const indexTemplatesByName = await callAsCurrentUser('indices.getTemplate'); - const body = deserializeTemplateList(indexTemplatesByName, managedTemplatePrefix); + const _legacyTemplates = await callAsCurrentUser('indices.getTemplate'); + const { index_templates: _templates } = await callAsCurrentUser('transport.request', { + path: '_index_template', + method: 'GET', + }); + + const legacyTemplates = deserializeLegacyTemplateList( + _legacyTemplates, + managedTemplatePrefix + ); + const templates = deserializeTemplateList(_templates, managedTemplatePrefix); + + const body = { + templates, + legacyTemplates, + }; return res.ok({ body }); }) @@ -31,22 +49,22 @@ const paramsSchema = schema.object({ // Require the template format version (V1 or V2) to be provided as Query param const querySchema = schema.object({ - v: schema.oneOf([schema.literal('1'), schema.literal('2')]), + legacy: schema.maybe(schema.boolean()), }); export function registerGetOneRoute({ router, license, lib }: RouteDependencies) { router.get( { - path: addBasePath('/templates/{name}'), + path: addBasePath('/index-templates/{name}'), validate: { params: paramsSchema, query: querySchema }, }, license.guardApiRoute(async (ctx, req, res) => { - const { name } = req.params as typeof paramsSchema.type; + const { name } = req.params as TypeOf; const { callAsCurrentUser } = ctx.core.elasticsearch.legacy.client; - const { v: version } = req.query as TypeOf; + const { legacy } = req.query as TypeOf; - if (version !== '1') { + if (!legacy) { return res.badRequest({ body: 'Only index template version 1 can be fetched.' }); } @@ -56,7 +74,7 @@ export function registerGetOneRoute({ router, license, lib }: RouteDependencies) if (indexTemplateByName[name]) { return res.ok({ - body: deserializeV1Template( + body: deserializeLegacyTemplate( { ...indexTemplateByName[name], name }, managedTemplatePrefix ), diff --git a/x-pack/plugins/index_management/server/routes/api/templates/register_update_route.ts b/x-pack/plugins/index_management/server/routes/api/templates/register_update_route.ts index 81d7aa1b4978c..5b2a0d8722e46 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/register_update_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/register_update_route.ts @@ -6,7 +6,7 @@ import { schema } from '@kbn/config-schema'; import { TemplateDeserialized } from '../../../../common'; -import { serializeV1Template } from '../../../../common/lib'; +import { serializeLegacyTemplate } from '../../../../common/lib'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '../index'; import { templateSchema } from './validate_schemas'; @@ -19,7 +19,7 @@ const paramsSchema = schema.object({ export function registerUpdateRoute({ router, license, lib }: RouteDependencies) { router.put( { - path: addBasePath('/templates/{name}'), + path: addBasePath('/index-templates/{name}'), validate: { body: bodySchema, params: paramsSchema }, }, license.guardApiRoute(async (ctx, req, res) => { @@ -27,14 +27,14 @@ export function registerUpdateRoute({ router, license, lib }: RouteDependencies) const { name } = req.params as typeof paramsSchema.type; const template = req.body as TemplateDeserialized; const { - _kbnMeta: { formatVersion }, + _kbnMeta: { isLegacy }, } = template; - if (formatVersion !== 1) { - return res.badRequest({ body: 'Only index template version 1 can be edited.' }); + if (!isLegacy) { + return res.badRequest({ body: 'Only legacy index template can be edited.' }); } - const serializedTemplate = serializeV1Template(template); + const serializedTemplate = serializeLegacyTemplate(template); const { order, index_patterns, version, settings, mappings, aliases } = serializedTemplate; diff --git a/x-pack/plugins/index_management/server/routes/api/templates/validate_schemas.ts b/x-pack/plugins/index_management/server/routes/api/templates/validate_schemas.ts index 491a686f81177..6ab28e9021123 100644 --- a/x-pack/plugins/index_management/server/routes/api/templates/validate_schemas.ts +++ b/x-pack/plugins/index_management/server/routes/api/templates/validate_schemas.ts @@ -24,8 +24,8 @@ export const templateSchema = schema.object({ rollover_alias: schema.maybe(schema.string()), }) ), - isManaged: schema.maybe(schema.boolean()), _kbnMeta: schema.object({ - formatVersion: schema.oneOf([schema.literal(1), schema.literal(2)]), + isManaged: schema.maybe(schema.boolean()), + isLegacy: schema.maybe(schema.boolean()), }), }); diff --git a/x-pack/plugins/index_management/server/types.ts b/x-pack/plugins/index_management/server/types.ts index b7b1c57b6f04e..b3fb546281f1e 100644 --- a/x-pack/plugins/index_management/server/types.ts +++ b/x-pack/plugins/index_management/server/types.ts @@ -32,6 +32,7 @@ export interface Index { size: any; isFrozen: boolean; aliases: string | string[]; + data_stream?: string; [key: string]: any; } diff --git a/x-pack/plugins/index_management/test/fixtures/template.ts b/x-pack/plugins/index_management/test/fixtures/template.ts index 055c32d5cd5e4..e2e93bfb365d4 100644 --- a/x-pack/plugins/index_management/test/fixtures/template.ts +++ b/x-pack/plugins/index_management/test/fixtures/template.ts @@ -5,7 +5,7 @@ */ import { getRandomString, getRandomNumber } from '../../../../test_utils'; -import { TemplateDeserialized, DEFAULT_INDEX_TEMPLATE_VERSION_FORMAT } from '../../common'; +import { TemplateDeserialized } from '../../common'; export const getTemplate = ({ name = getRandomString(), @@ -14,10 +14,11 @@ export const getTemplate = ({ indexPatterns = [], template: { settings, aliases, mappings } = {}, isManaged = false, - templateFormatVersion = DEFAULT_INDEX_TEMPLATE_VERSION_FORMAT, + isLegacy = false, }: Partial< TemplateDeserialized & { - templateFormatVersion?: 1 | 2; + isLegacy?: boolean; + isManaged: boolean; } > = {}): TemplateDeserialized => ({ name, @@ -29,8 +30,8 @@ export const getTemplate = ({ mappings, settings, }, - isManaged, _kbnMeta: { - formatVersion: templateFormatVersion, + isManaged, + isLegacy, }, }); diff --git a/x-pack/plugins/infra/public/alerting/metric_threshold/components/alert_dropdown.tsx b/x-pack/plugins/infra/public/alerting/metric_threshold/components/alert_dropdown.tsx index 52033a00327c0..d26575f65dfec 100644 --- a/x-pack/plugins/infra/public/alerting/metric_threshold/components/alert_dropdown.tsx +++ b/x-pack/plugins/infra/public/alerting/metric_threshold/components/alert_dropdown.tsx @@ -41,6 +41,7 @@ export const MetricsAlertDropdown = () => { , ]; + /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [kibana.services]); return ( diff --git a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx index f4c7332a88e1d..7a71bb68bc54f 100644 --- a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx +++ b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx @@ -90,6 +90,7 @@ export const Expressions: React.FC = (props) => { aggregation: 'avg', }; } + /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [alertsContext.metadata]); const updateParams = useCallback( @@ -109,6 +110,7 @@ export const Expressions: React.FC = (props) => { timeUnit: timeUnit ?? defaultExpression.timeUnit, }); setAlertParams('criteria', exp); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [setAlertParams, alertParams.criteria, timeSize, timeUnit]); const removeExpression = useCallback( @@ -119,6 +121,7 @@ export const Expressions: React.FC = (props) => { setAlertParams('criteria', exp); } }, + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [setAlertParams, alertParams.criteria] ); @@ -133,6 +136,7 @@ export const Expressions: React.FC = (props) => { [setAlertParams, derivedIndexPattern] ); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const debouncedOnFilterChange = useCallback(debounce(onFilterChange, FILTER_TYPING_DEBOUNCE_MS), [ onFilterChange, ]); @@ -162,6 +166,7 @@ export const Expressions: React.FC = (props) => { setTimeSize(ts || undefined); setAlertParams('criteria', criteria); }, + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [alertParams.criteria, setAlertParams] ); @@ -175,6 +180,7 @@ export const Expressions: React.FC = (props) => { setTimeUnit(tu as TimeUnit); setAlertParams('criteria', criteria); }, + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [alertParams.criteria, setAlertParams] ); @@ -288,6 +294,7 @@ export const Expressions: React.FC = (props) => { />
+
= ({ : (value: number) => `${value}`; }, [data]); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const yAxisFormater = useCallback(createFormatterForMetric(metric), [expression]); if (loading || !data) { diff --git a/x-pack/plugins/infra/public/components/alerting/inventory/alert_dropdown.tsx b/x-pack/plugins/infra/public/components/alerting/inventory/alert_dropdown.tsx index c48b5b9a2cc58..47a0f037816bc 100644 --- a/x-pack/plugins/infra/public/components/alerting/inventory/alert_dropdown.tsx +++ b/x-pack/plugins/infra/public/components/alerting/inventory/alert_dropdown.tsx @@ -41,6 +41,7 @@ export const InventoryAlertDropdown = () => { , ]; + /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [kibana.services]); return ( diff --git a/x-pack/plugins/infra/public/components/alerting/inventory/expression.tsx b/x-pack/plugins/infra/public/components/alerting/inventory/expression.tsx index f4fab113cdd17..074464fb55414 100644 --- a/x-pack/plugins/infra/public/components/alerting/inventory/expression.tsx +++ b/x-pack/plugins/infra/public/components/alerting/inventory/expression.tsx @@ -117,6 +117,7 @@ export const Expressions: React.FC = (props) => { timeUnit: timeUnit ?? defaultExpression.timeUnit, }); setAlertParams('criteria', exp); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [setAlertParams, alertParams.criteria, timeSize, timeUnit]); const removeExpression = useCallback( @@ -141,6 +142,7 @@ export const Expressions: React.FC = (props) => { [derivedIndexPattern, setAlertParams] ); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const debouncedOnFilterChange = useCallback(debounce(onFilterChange, FILTER_TYPING_DEBOUNCE_MS), [ onFilterChange, ]); diff --git a/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/editor.tsx b/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/editor.tsx index d81d11e01d4a5..609f99805fe9c 100644 --- a/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/editor.tsx +++ b/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/editor.tsx @@ -137,6 +137,7 @@ export const Editor: React.FC = (props) => { } else { return []; } + /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [sourceStatus]); const updateCount = useCallback( @@ -176,6 +177,7 @@ export const Editor: React.FC = (props) => { ? [...alertParams.criteria, DEFAULT_CRITERIA] : [DEFAULT_CRITERIA]; setAlertParams('criteria', nextCriteria); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [alertParams, setAlertParams]); const removeCriterion = useCallback( @@ -185,6 +187,7 @@ export const Editor: React.FC = (props) => { }); setAlertParams('criteria', nextCriteria); }, + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [alertParams, setAlertParams] ); diff --git a/x-pack/plugins/infra/public/components/header/header.tsx b/x-pack/plugins/infra/public/components/header/header.tsx index fa71426f83645..47ee1857da591 100644 --- a/x-pack/plugins/infra/public/components/header/header.tsx +++ b/x-pack/plugins/infra/public/components/header/header.tsx @@ -31,10 +31,12 @@ export const Header = ({ breadcrumbs = [], readOnlyBadge = false }: HeaderProps) const setBreadcrumbs = useCallback(() => { return chrome?.setBreadcrumbs(breadcrumbs || []); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [breadcrumbs, chrome]); const setBadge = useCallback(() => { return chrome?.setBadge(badge); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [badge, chrome]); useEffect(() => { diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_actions_column.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_actions_column.tsx index 1ac2e00abca70..e27de7fd6b5a8 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_actions_column.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_actions_column.tsx @@ -5,19 +5,11 @@ */ import React, { useCallback } from 'react'; -import { EuiButtonIcon } from '@elastic/eui'; +import { EuiButtonIcon, EuiPopover, EuiContextMenuPanel, EuiContextMenuItem } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; import { LogEntryColumnContent } from './log_entry_column'; -import { - euiStyled, - ActionMenu, - Section, - SectionTitle, - SectionLinks, - SectionLink, -} from '../../../../../observability/public'; +import { euiStyled } from '../../../../../observability/public'; interface LogEntryActionsColumnProps { isHovered: boolean; @@ -78,29 +70,32 @@ export const LogEntryActionsColumn: React.FC = ({ ); + const items = [ + + {LOG_DETAILS_LABEL} + , + ]; + + if (onViewLogInContext !== undefined) { + items.push( + + {LOG_VIEW_IN_CONTEXT_LABEL} + + ); + } + return ( {isHovered || isMenuOpen ? ( - -
- - - - - - {onViewLogInContext !== undefined ? ( - - ) : null} - -
-
+ + +
) : null}
@@ -115,10 +110,11 @@ const ActionsColumnContent = euiStyled(LogEntryColumnContent)` const ButtonWrapper = euiStyled.div` background: ${(props) => props.theme.eui.euiColorPrimary}; border-radius: 50%; + padding: 4px; + transform: translateY(-6px); `; // this prevents the button from influencing the line height const AbsoluteWrapper = euiStyled.div` - overflow: hidden; position: absolute; `; diff --git a/x-pack/plugins/infra/public/containers/logs/log_entries/index.ts b/x-pack/plugins/infra/public/containers/logs/log_entries/index.ts index 5fe9a45a7ceed..d5b2a0aaa61c0 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_entries/index.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_entries/index.ts @@ -269,6 +269,7 @@ const useFetchEntriesEffect = ( } }; + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const fetchNewerEntries = useCallback( throttle(() => runFetchMoreEntriesRequest(ShouldFetchMoreEntries.After), 500), [props, state.bottomCursor] @@ -330,10 +331,12 @@ const useFetchEntriesEffect = ( props.timestampsLastUpdate, ]; + /* eslint-disable react-hooks/exhaustive-deps */ useEffect(fetchNewEntriesEffect, fetchNewEntriesEffectDependencies); useEffect(fetchMoreEntriesEffect, fetchMoreEntriesEffectDependencies); useEffect(streamEntriesEffect, streamEntriesEffectDependencies); useEffect(expandRangeEffect, expandRangeEffectDependencies); + /* eslint-enable react-hooks/exhaustive-deps */ return { fetchNewerEntries, checkForNewEntries: runFetchNewEntriesRequest }; }; diff --git a/x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts b/x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts index 7c903f59002dc..d5a43c0d6cffa 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_filter/log_filter_state.ts @@ -82,6 +82,7 @@ export const useLogFilterState: (props: { } return true; + /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [filterQueryDraft]); const serializedFilterQuery = useMemo(() => (filterQuery ? filterQuery.serializedQuery : null), [ diff --git a/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts b/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts index 670988d680147..80aab6237518f 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts @@ -78,6 +78,7 @@ export const useLogSource = ({ [sourceId, fetch] ); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const logIndicesExist = useMemo(() => (sourceStatus?.logIndexNames?.length ?? 0) > 0, [ sourceStatus, ]); @@ -87,6 +88,7 @@ export const useLogSource = ({ fields: sourceStatus?.logIndexFields ?? [], title: sourceConfiguration?.configuration.name ?? 'unknown', }), + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [sourceConfiguration, sourceStatus] ); diff --git a/x-pack/plugins/infra/public/containers/source/use_source_via_http.ts b/x-pack/plugins/infra/public/containers/source/use_source_via_http.ts index 94e2537a67a2a..54d565d9ee223 100644 --- a/x-pack/plugins/infra/public/containers/source/use_source_via_http.ts +++ b/x-pack/plugins/infra/public/containers/source/use_source_via_http.ts @@ -76,6 +76,7 @@ export const useSourceViaHttp = ({ title: pickIndexPattern(response?.source, indexType), }; }, + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [response, type] ); diff --git a/x-pack/plugins/infra/public/hooks/use_bulk_get_saved_object.tsx b/x-pack/plugins/infra/public/hooks/use_bulk_get_saved_object.tsx index 2a70edc9b9a57..cfa9a711f7743 100644 --- a/x-pack/plugins/infra/public/hooks/use_bulk_get_saved_object.tsx +++ b/x-pack/plugins/infra/public/hooks/use_bulk_get_saved_object.tsx @@ -35,6 +35,7 @@ export const useBulkGetSavedObject = (type: string) => { }; fetchData(); }, + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [type, kibana.services.savedObjects] ); diff --git a/x-pack/plugins/infra/public/hooks/use_create_saved_object.tsx b/x-pack/plugins/infra/public/hooks/use_create_saved_object.tsx index 8313d496a0651..0efb862ad2eb4 100644 --- a/x-pack/plugins/infra/public/hooks/use_create_saved_object.tsx +++ b/x-pack/plugins/infra/public/hooks/use_create_saved_object.tsx @@ -40,6 +40,7 @@ export const useCreateSavedObject = (type: string) => { }; save(); }, + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [type, kibana.services.savedObjects] ); diff --git a/x-pack/plugins/infra/public/hooks/use_delete_saved_object.tsx b/x-pack/plugins/infra/public/hooks/use_delete_saved_object.tsx index 3f2d15b3b86aa..e353a79b19073 100644 --- a/x-pack/plugins/infra/public/hooks/use_delete_saved_object.tsx +++ b/x-pack/plugins/infra/public/hooks/use_delete_saved_object.tsx @@ -29,6 +29,7 @@ export const useDeleteSavedObject = (type: string) => { }; dobj(); }, + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [type, kibana.services.savedObjects] ); diff --git a/x-pack/plugins/infra/public/hooks/use_find_saved_object.tsx b/x-pack/plugins/infra/public/hooks/use_find_saved_object.tsx index 8b0ab45f6e6d1..8eb6db6103ed8 100644 --- a/x-pack/plugins/infra/public/hooks/use_find_saved_object.tsx +++ b/x-pack/plugins/infra/public/hooks/use_find_saved_object.tsx @@ -37,6 +37,7 @@ export const useFindSavedObject = { title: loadDataErrorTitle, }); }, + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [services.notifications] ); diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx index 156c9a919440e..3c8db3f8246c0 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_results_content.tsx @@ -127,6 +127,7 @@ export const LogEntryRateResultsContent: React.FunctionComponent = () => { [setAutoRefresh] ); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const hasResults = useMemo(() => (logEntryRate?.histogramBuckets?.length ?? 0) > 0, [ logEntryRate, ]); diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx index 11ea137c95a1f..a1d3d56beee2c 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/expanded_row.tsx @@ -29,6 +29,7 @@ export const AnomaliesTableExpandedRow: React.FunctionComponent<{ const logEntryRateSeries = useMemo( () => results?.histogramBuckets ? getLogEntryRateSeriesForPartition(results, partitionId) : [], + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [results, partitionId] ); const anomalyAnnotations = useMemo( @@ -41,6 +42,7 @@ export const AnomaliesTableExpandedRow: React.FunctionComponent<{ major: [], critical: [], }, + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [results, partitionId] ); const totalNumberOfLogEntries = useMemo( @@ -48,6 +50,7 @@ export const AnomaliesTableExpandedRow: React.FunctionComponent<{ results?.histogramBuckets ? getTotalNumberOfLogEntriesForPartition(results, partitionId) : undefined, + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [results, partitionId] ); return ( diff --git a/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx b/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx index 34c4202ab8b65..f41158e114c7d 100644 --- a/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx +++ b/x-pack/plugins/infra/public/pages/logs/settings/source_configuration_settings.tsx @@ -42,6 +42,7 @@ export const LogsSettingsPage = () => { const availableFields = useMemo( () => sourceStatus?.logIndexFields.map((field) => field.name) ?? [], + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [sourceStatus] ); diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx index b6e6710a0b3b4..3ef32c920e293 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_view_log_in_context.tsx @@ -8,12 +8,13 @@ import { EuiFlexGroup, EuiFlexItem, EuiModal, - EuiModalBody, EuiOverlayMask, EuiText, EuiTextColor, EuiToolTip, + EuiSpacer, } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; import { noop } from 'lodash'; import React, { useCallback, useContext, useMemo } from 'react'; import { LogEntry } from '../../../../common/http_api'; @@ -22,12 +23,14 @@ import { useLogSourceContext } from '../../../containers/logs/log_source'; import { LogViewConfiguration } from '../../../containers/logs/log_view_configuration'; import { ViewLogInContext } from '../../../containers/logs/view_log_in_context'; import { useViewportDimensions } from '../../../utils/use_viewport_dimensions'; +import { euiStyled } from '../../../../../observability/public'; const MODAL_MARGIN = 25; export const PageViewLogInContext: React.FC = () => { const { sourceConfiguration } = useLogSourceContext(); const { textScale, textWrap } = useContext(LogViewConfiguration.Context); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const columnConfigurations = useMemo(() => sourceConfiguration?.configuration.logColumns ?? [], [ sourceConfiguration, ]); @@ -54,7 +57,7 @@ export const PageViewLogInContext: React.FC = () => { return ( - + { > + { /> - + ); }; +const LogInContextWrapper = euiStyled.div<{ width: number | string; height: number | string }>` + padding: 16px; + width: ${(props) => (typeof props.width === 'number' ? `${props.width}px` : props.width)}; + height: ${(props) => (typeof props.height === 'number' ? `${props.height}px` : props.height)}; +`; + const LogEntryContext: React.FC<{ context: LogEntry['context'] }> = ({ context }) => { + let text; if ('container.id' in context) { - return

Displayed logs are from container {context['container.id']}

; + text = ( + + ); } if ('host.name' in context) { @@ -104,21 +121,27 @@ const LogEntryContext: React.FC<{ context: LogEntry['context'] }> = ({ context } context['log.file.path'].length > 45 ? context['log.file.path'].slice(0, 20) + '...' + context['log.file.path'].slice(-25) : context['log.file.path']; - - return ( - -

- - Displayed logs are from file{' '} + text = ( + {shortenedFilePath} - {' '} - and host {context['host.name']} - -

-
+ + ), + host: context['host.name'], + }} + /> ); } - return null; + return ( + +

+ {text} +

+
+ ); }; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx index 8b5b191ccfdd9..1452772e49ca1 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx @@ -76,6 +76,7 @@ export const Layout = () => { const intervalAsString = convertIntervalToString(interval); const dataBounds = calculateBoundsFromNodes(nodes); const bounds = autoBounds ? dataBounds : boundsOverride; + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const formatter = useCallback(createInventoryMetricFormatter(options.metric), [options.metric]); return ( diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/legend_controls.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/legend_controls.tsx index 7929cf8292cb6..538cd5f7d9525 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/legend_controls.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/legend_controls.tsx @@ -141,14 +141,16 @@ export const LegendControls = ({ const handleStepsChange = useCallback( (e) => { - setLegendOptions((previous) => ({ ...previous, steps: parseInt(e.target.value, 10) })); + const steps = parseInt(e.target.value, 10); + setLegendOptions((previous) => ({ ...previous, steps })); }, [setLegendOptions] ); const handlePaletteChange = useCallback( (e) => { - setLegendOptions((previous) => ({ ...previous, palette: e.target.value })); + const palette = e.target.value; + setLegendOptions((previous) => ({ ...previous, palette })); }, [setLegendOptions] ); diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/chart_section_vis.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/chart_section_vis.tsx index 6a4d6521855a9..dee2e0c9f457f 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/chart_section_vis.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/chart_section_vis.tsx @@ -45,6 +45,7 @@ export const ChartSectionVis = ({ }: VisSectionProps) => { const isDarkMode = useUiSetting('theme:darkMode'); const [dateFormat] = useKibanaUiSetting('dateFormat'); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const valueFormatter = useCallback(getFormatter(formatter, formatterTemplate), [ formatter, formatterTemplate, diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/sub_section.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/sub_section.tsx index 4c75003616117..88e7c0c08e441 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/sub_section.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/sub_section.tsx @@ -23,6 +23,7 @@ export const SubSection: FunctionComponent = ({ isLiveStreaming, stopLiveStreaming, }) => { + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const metric = useMemo(() => metrics?.find((m) => m.id === id), [id, metrics]); if (!children || !metric) { diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/time_controls.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/time_controls.tsx index ef6486eac0fdb..afee0c0498187 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/time_controls.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/time_controls.tsx @@ -6,6 +6,7 @@ import { EuiSuperDatePicker, OnRefreshChangeProps, OnTimeChangeProps } from '@elastic/eui'; import React, { useCallback } from 'react'; +import { UI_SETTINGS } from '../../../../../../../../src/plugins/data/public'; import { euiStyled } from '../../../../../../observability/public'; import { MetricsTimeInput } from '../hooks/use_metrics_time'; import { useKibanaUiSetting } from '../../../../utils/use_kibana_ui_setting'; @@ -22,7 +23,7 @@ interface MetricsTimeControlsProps { } export const MetricsTimeControls = (props: MetricsTimeControlsProps) => { - const [timepickerQuickRanges] = useKibanaUiSetting('timepicker:quickRanges'); + const [timepickerQuickRanges] = useKibanaUiSetting(UI_SETTINGS.TIMEPICKER_QUICK_RANGES); const { onChangeTimeRange, onRefresh, diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart.tsx index d079b7bb93d73..2a218c1c78aa3 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart.tsx @@ -87,6 +87,7 @@ export const MetricsExplorerChart = ({ [dateFormat] ), }; + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const yAxisFormater = useCallback(createFormatterForMetric(first(metrics)), [options]); const dataDomain = calculateDomain(series, metrics, chartOptions.stack); const domain = diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx index 7ad1d943a9896..1471efbd21e18 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/toolbar.tsx @@ -7,7 +7,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiSuperDatePicker, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import React from 'react'; -import { IIndexPattern } from 'src/plugins/data/public'; +import { IIndexPattern, UI_SETTINGS } from '../../../../../../../../src/plugins/data/public'; import { MetricsExplorerMetric, MetricsExplorerAggregation, @@ -61,7 +61,7 @@ export const MetricsExplorerToolbar = ({ onViewStateChange, }: Props) => { const isDefaultOptions = options.aggregation === 'avg' && options.metrics.length === 0; - const [timepickerQuickRanges] = useKibanaUiSetting('timepicker:quickRanges'); + const [timepickerQuickRanges] = useKibanaUiSetting(UI_SETTINGS.TIMEPICKER_QUICK_RANGES); const commonlyUsedRanges = mapKibanaQuickRangesToDatePickerRanges(timepickerQuickRanges); return ( diff --git a/x-pack/plugins/infra/public/plugin.ts b/x-pack/plugins/infra/public/plugin.ts index ead5644d19fa2..deae78e22c6a1 100644 --- a/x-pack/plugins/infra/public/plugin.ts +++ b/x-pack/plugins/infra/public/plugin.ts @@ -64,7 +64,7 @@ export class Plugin defaultMessage: 'Logs', }), euiIconType: 'logsApp', - order: 8000, + order: 8100, appRoute: '/app/logs', category: DEFAULT_APP_CATEGORIES.observability, mount: async (params: AppMountParameters) => { @@ -89,7 +89,7 @@ export class Plugin defaultMessage: 'Metrics', }), euiIconType: 'metricsApp', - order: 8001, + order: 8200, appRoute: '/app/metrics', category: DEFAULT_APP_CATEGORIES.observability, mount: async (params: AppMountParameters) => { diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts index 7c0c535795638..79c276a1e58f7 100644 --- a/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -32,7 +32,7 @@ import { } from '../../../../../../../src/core/server'; import { RequestHandler } from '../../../../../../../src/core/server'; import { InfraConfig } from '../../../plugin'; -import { IndexPatternsFetcher } from '../../../../../../../src/plugins/data/server'; +import { IndexPatternsFetcher, UI_SETTINGS } from '../../../../../../../src/plugins/data/server'; export class KibanaFramework { public router: IRouter; @@ -197,10 +197,10 @@ export class KibanaFramework { ) { const { elasticsearch, uiSettings } = requestContext.core; - const includeFrozen = await uiSettings.client.get('search:includeFrozen'); + const includeFrozen = await uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); if (endpoint === 'msearch') { const maxConcurrentShardRequests = await uiSettings.client.get( - 'courier:maxConcurrentShardRequests' + UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS ); if (maxConcurrentShardRequests > 0) { params = { ...params, max_concurrent_shard_requests: maxConcurrentShardRequests }; diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts index 233a34a67d1ec..00a1d97dec811 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts @@ -5,6 +5,7 @@ */ import { mapValues, first } from 'lodash'; import { i18n } from '@kbn/i18n'; +import moment from 'moment'; import { InfraDatabaseSearchResponse } from '../../adapters/framework/adapter_types'; import { createAfterKeyHandler } from '../../../utils/create_afterkey_handler'; import { getAllCompositeData } from '../../../utils/get_all_composite_data'; @@ -336,6 +337,10 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs, alertId: s group, alertState: stateToAlertMessage[nextState], reason, + timestamp: moment().toISOString(), + value: mapToConditionsLookup(alertResults, (result) => result[group].currentValue), + threshold: mapToConditionsLookup(criteria, (c) => c.threshold), + metric: mapToConditionsLookup(criteria, (c) => c.metric), }); } @@ -352,3 +357,14 @@ export const FIRED_ACTIONS = { defaultMessage: 'Fired', }), }; + +const mapToConditionsLookup = ( + list: any[], + mapFn: (value: any, index: number, array: any[]) => unknown +) => + list + .map(mapFn) + .reduce( + (result: Record, value, i) => ({ ...result, [`condition${i}`]: value }), + {} + ); diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts index 8b3903f2ee3be..02d9ca3e5f0c9 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts @@ -55,6 +55,37 @@ export function registerMetricThresholdAlertType(libs: InfraBackendLibs) { } ); + const timestampActionVariableDescription = i18n.translate( + 'xpack.infra.metrics.alerting.threshold.alerting.timestampDescription', + { + defaultMessage: 'A timestamp of when the alert was detected.', + } + ); + + const valueActionVariableDescription = i18n.translate( + 'xpack.infra.metrics.alerting.threshold.alerting.valueActionVariableDescription', + { + defaultMessage: + 'The value of the metric in the specified condition. Usage: (ctx.value.condition0, ctx.value.condition1, etc...).', + } + ); + + const metricActionVariableDescription = i18n.translate( + 'xpack.infra.metrics.alerting.threshold.alerting.metricActionVariableDescription', + { + defaultMessage: + 'The metric name in the specified condition. Usage: (ctx.metric.condition0, ctx.metric.condition1, etc...).', + } + ); + + const thresholdActionVariableDescription = i18n.translate( + 'xpack.infra.metrics.alerting.threshold.alerting.thresholdActionVariableDescription', + { + defaultMessage: + 'The threshold value of the metric for the specified condition. Usage: (ctx.threshold.condition0, ctx.threshold.condition1, etc...).', + } + ); + return { id: METRIC_THRESHOLD_ALERT_TYPE_ID, name: 'Metric threshold', @@ -82,6 +113,10 @@ export function registerMetricThresholdAlertType(libs: InfraBackendLibs) { { name: 'group', description: groupActionVariableDescription }, { name: 'alertState', description: alertStateActionVariableDescription }, { name: 'reason', description: reasonActionVariableDescription }, + { name: 'timestamp', description: timestampActionVariableDescription }, + { name: 'value', description: valueActionVariableDescription }, + { name: 'metric', description: metricActionVariableDescription }, + { name: 'threshold', description: thresholdActionVariableDescription }, ], }, producer: 'metrics', diff --git a/x-pack/plugins/ingest_manager/README.md b/x-pack/plugins/ingest_manager/README.md index f0c2466b25b04..50c42544b8bdc 100644 --- a/x-pack/plugins/ingest_manager/README.md +++ b/x-pack/plugins/ingest_manager/README.md @@ -52,12 +52,12 @@ This plugin follows the `common`, `server`, `public` structure from the [Archite 1. In one terminal, change to the `x-pack` directory and start the test server with ``` - node scripts/functional_tests_server.js --config test/api_integration/config.js + node scripts/functional_tests_server.js --config test/api_integration/config.ts ``` 1. in a second terminal, run the tests from the Kibana root directory with ``` - node scripts/functional_test_runner.js --config x-pack/test/api_integration/config.js + node scripts/functional_test_runner.js --config x-pack/test/api_integration/config.ts ``` #### EPM diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/alpha_messaging.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/alpha_messaging.tsx index 2b80ab9f0068e..f43419fc52ef0 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/alpha_messaging.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/alpha_messaging.tsx @@ -15,6 +15,7 @@ const Message = styled(EuiText).attrs((props) => ({ size: 's', }))` padding: ${(props) => props.theme.eui.paddingSizes.m}; + margin-top: auto; `; export const AlphaMessaging: React.FC<{}> = () => { diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx index 47d723dd9a1ac..c79077e68afb0 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/settings_flyout.tsx @@ -167,7 +167,7 @@ export const SettingFlyout: React.FunctionComponent = ({ onClose }) => { 'xpack.ingestManager.settings.integrationUpgradeEnabledFieldLabel', { defaultMessage: - 'Automatically update Integrations to the latest version to receive the latest assets. Agent configurations may need to be updated in order to use new features.', + 'Automatically update integrations to the latest version to receive the latest assets. Agent configurations may need to be updated in order to use new features.', } ), }, @@ -190,7 +190,7 @@ export const SettingFlyout: React.FunctionComponent = ({ onClose }) => {

diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx index 72b12260a1a12..5e0cba7383e9c 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx @@ -9,7 +9,7 @@ import { EuiTabs, EuiTab, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiButtonEmpty } f import { FormattedMessage } from '@kbn/i18n/react'; import { Section } from '../sections'; import { AlphaMessaging, SettingFlyout } from '../components'; -import { useLink, useConfig } from '../hooks'; +import { useLink, useConfig, useCore } from '../hooks'; interface Props { showSettings?: boolean; @@ -20,6 +20,8 @@ interface Props { const Container = styled.div` min-height: calc(100vh - ${(props) => props.theme.eui.euiHeaderChildSize}); background: ${(props) => props.theme.eui.euiColorEmptyShade}; + display: flex; + flex-direction: column; `; const Nav = styled.nav` @@ -40,6 +42,7 @@ export const DefaultLayout: React.FunctionComponent = ({ }) => { const { getHref } = useLink(); const { epm, fleet } = useConfig(); + const { uiSettings } = useCore(); const [isSettingsFlyoutOpen, setIsSettingsFlyoutOpen] = React.useState(false); return ( @@ -52,85 +55,89 @@ export const DefaultLayout: React.FunctionComponent = ({ /> )} - + {children} +
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/components/actions_menu.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/components/actions_menu.tsx index 78ed228012691..dc61da685c88d 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/components/actions_menu.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/components/actions_menu.tsx @@ -58,7 +58,7 @@ export const AgentConfigActionMenu = memo<{ configId: string; fullButton?: boole > , ]} diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/datasources/datasources_table.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/datasources/datasources_table.tsx index 01505fcf4c65e..caf0c149c0199 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/datasources/datasources_table.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/datasources/datasources_table.tsx @@ -280,7 +280,7 @@ export const DatasourcesTable: React.FunctionComponent = ({ > , ], diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/datasources/no_datasources.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/datasources/no_datasources.tsx index 72726f1c855ec..f2c204d955a0b 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/datasources/no_datasources.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/components/datasources/no_datasources.tsx @@ -38,7 +38,7 @@ export const NoDatasources = memo<{ configId: string }>(({ configId }) => { > } diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/index.tsx index 1dd7e660deaa9..6fab78951038f 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/details_page/index.tsx @@ -169,6 +169,7 @@ export const AgentConfigDetailsPage: React.FunctionComponent = () => { ))} ), + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [agentConfig, configId, agentStatus] ); diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/data_stream/list_page/components/data_stream_row_actions.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/data_stream/list_page/components/data_stream_row_actions.tsx index cdc4f1c63a11d..057970aa1ee92 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/data_stream/list_page/components/data_stream_row_actions.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/data_stream/list_page/components/data_stream_row_actions.tsx @@ -48,6 +48,7 @@ export const DataStreamRowActions = memo<{ datastream: DataStream }>(({ datastre items: [ { icon: 'dashboardApp', + /* eslint-disable-next-line react-hooks/rules-of-hooks */ href: useKibanaLink(`/dashboard/${dashboards[0].id || ''}`), name: actionNameSingular, }, @@ -70,6 +71,7 @@ export const DataStreamRowActions = memo<{ datastream: DataStream }>(({ datastre items: dashboards.map((dashboard) => { return { icon: 'dashboardApp', + /* eslint-disable-next-line react-hooks/rules-of-hooks */ href: useKibanaLink(`/dashboard/${dashboard.id || ''}`), name: dashboard.title, }; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/confirm_package_uninstall.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/confirm_package_uninstall.tsx index 14b9bf77c3a00..11cdbe0be7b62 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/confirm_package_uninstall.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/confirm_package_uninstall.tsx @@ -56,7 +56,7 @@ export const ConfirmPackageUninstall = (props: ConfirmPackageUninstallProps) =>

diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/header.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/header.tsx index 318bab6c44951..db046d18ccebc 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/header.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/header.tsx @@ -74,7 +74,10 @@ export function Header(props: HeaderProps) { >
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/settings_panel.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/settings_panel.tsx index 5d24c180268a7..986b946131e33 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/settings_panel.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/detail/settings_panel.tsx @@ -175,7 +175,7 @@ export const SettingsPanel = (

diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/home/header.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/home/header.tsx index a40fe98f93ddc..c378e5a47a9b9 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/home/header.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/screens/home/header.tsx @@ -20,7 +20,7 @@ export const HeroCopy = memo(() => {

@@ -46,7 +46,7 @@ export const HeroImage = memo(() => { const Illustration = styled(EuiImage).attrs((props) => ({ alt: i18n.translate('xpack.ingestManager.epm.illustrationAltText', { - defaultMessage: 'Illustration of an Elastic integration', + defaultMessage: 'Illustration of an integration', }), url: IS_DARK_THEME ? toAssets('illustration_integrations_darkmode.svg') diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/index.tsx index 1a7681584ff15..5bb0464801f70 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/index.tsx @@ -90,6 +90,7 @@ export const AgentDetailsPage: React.FunctionComponent = () => {
), + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [agentData, agentId, getHref] ); @@ -141,6 +142,7 @@ export const AgentDetailsPage: React.FunctionComponent = () => { ))} ) : undefined, + /* eslint-disable-next-line react-hooks/exhaustive-deps */ [agentConfigData, agentData, getHref, isAgentConfigLoading] ); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/agent/agent.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/agent/agent.test.ts index 5e83a976bd7a4..635dce93f0027 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/agent/agent.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/agent/agent.test.ts @@ -83,4 +83,22 @@ foo: bar custom: { foo: 'bar' }, }); }); + + it('should support optional yaml values at root level', () => { + const streamTemplate = ` +input: logs +{{custom}} + `; + const vars = { + custom: { + type: 'yaml', + value: null, + }, + }; + + const output = createStream(vars, streamTemplate); + expect(output).toEqual({ + input: 'logs', + }); + }); }); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/agent/agent.ts b/x-pack/plugins/ingest_manager/server/services/epm/agent/agent.ts index 61f2f95fe20a9..0bcb2464f8d74 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/agent/agent.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/agent/agent.ts @@ -94,7 +94,10 @@ function replaceRootLevelYamlVariables(yamlVariables: { [k: string]: any }, yaml let patchedTemplate = yamlTemplate; Object.entries(yamlVariables).forEach(([key, val]) => { - patchedTemplate = patchedTemplate.replace(new RegExp(`^"${key}"`, 'gm'), safeDump(val)); + patchedTemplate = patchedTemplate.replace( + new RegExp(`^"${key}"`, 'gm'), + val ? safeDump(val) : '' + ); }); return patchedTemplate; diff --git a/x-pack/plugins/lens/public/app_plugin/app.test.tsx b/x-pack/plugins/lens/public/app_plugin/app.test.tsx index 4dd822c74178b..811f42590f07b 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.test.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.test.tsx @@ -20,6 +20,7 @@ import { FilterManager, IFieldType, IIndexPattern, + UI_SETTINGS, } from '../../../../../src/plugins/data/public'; import { dataPluginMock } from '../../../../../src/plugins/data/public/mocks'; const dataStartMock = dataPluginMock.createStartContract(); @@ -191,7 +192,7 @@ describe('Lens App', () => { jest.fn((type) => { if (type === 'timepicker:timeDefaults') { return { from: 'now-7d', to: 'now' }; - } else if (type === 'search:queryLanguage') { + } else if (type === UI_SETTINGS.SEARCH_QUERY_LANGUAGE) { return 'kuery'; } else if (type === 'state:storeInSessionStorage') { return false; diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index a170ae2d74bc4..f88c1c5aca31d 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -35,6 +35,7 @@ import { IndexPattern as IndexPatternInstance, IndexPatternsContract, SavedQuery, + UI_SETTINGS, } from '../../../../../src/plugins/data/public'; interface State { @@ -86,7 +87,8 @@ export function App({ history: History; }) { const language = - storage.get('kibana.userQueryLanguage') || core.uiSettings.get('search:queryLanguage'); + storage.get('kibana.userQueryLanguage') || + core.uiSettings.get(UI_SETTINGS.SEARCH_QUERY_LANGUAGE); const [state, setState] = useState(() => { const currentRange = data.query.timefilter.timefilter.getTime(); @@ -433,7 +435,7 @@ export function App({ query: '', language: storage.get('kibana.userQueryLanguage') || - core.uiSettings.get('search:queryLanguage'), + core.uiSettings.get(UI_SETTINGS.SEARCH_QUERY_LANGUAGE), }, })); }} diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx index e665e8b8dd326..defc142d4976e 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx @@ -12,6 +12,7 @@ import { EuiSwitch, EuiSwitchEvent } from '@elastic/eui'; import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from 'kibana/public'; import { coreMock } from 'src/core/public/mocks'; import { IStorageWrapper } from 'src/plugins/kibana_utils/public'; +import { UI_SETTINGS } from '../../../../../../../src/plugins/data/public'; import { dataPluginMock, getCalculateAutoTimeExpression, @@ -23,7 +24,7 @@ const dataStart = dataPluginMock.createStartContract(); dataStart.search.aggs.calculateAutoTimeExpression = getCalculateAutoTimeExpression({ ...coreMock.createStart().uiSettings, get: (path: string) => { - if (path === 'histogram:maxBars') { + if (path === UI_SETTINGS.HISTOGRAM_MAX_BARS) { return 10; } }, diff --git a/x-pack/plugins/lens/public/plugin.ts b/x-pack/plugins/lens/public/plugin.ts index f9a577e001c64..3000c9321b3b9 100644 --- a/x-pack/plugins/lens/public/plugin.ts +++ b/x-pack/plugins/lens/public/plugin.ts @@ -6,7 +6,7 @@ import { AppMountParameters, CoreSetup, CoreStart } from 'kibana/public'; import { DataPublicPluginSetup, DataPublicPluginStart } from 'src/plugins/data/public'; -import { EmbeddableSetup, EmbeddableStart } from 'src/plugins/embeddable/public'; +import { EmbeddableSetup } from 'src/plugins/embeddable/public'; import { ExpressionsSetup, ExpressionsStart } from 'src/plugins/expressions/public'; import { VisualizationsSetup } from 'src/plugins/visualizations/public'; import { NavigationPublicPluginStart } from 'src/plugins/navigation/public'; @@ -38,7 +38,6 @@ export interface LensPluginSetupDependencies { export interface LensPluginStartDependencies { data: DataPublicPluginStart; - embeddable: EmbeddableStart; expressions: ExpressionsStart; navigation: NavigationPublicPluginStart; uiActions: UiActionsStart; diff --git a/x-pack/plugins/lens/public/xy_visualization/index.ts b/x-pack/plugins/lens/public/xy_visualization/index.ts index 23cf9e7ff818f..cd25cb5729511 100644 --- a/x-pack/plugins/lens/public/xy_visualization/index.ts +++ b/x-pack/plugins/lens/public/xy_visualization/index.ts @@ -8,6 +8,7 @@ import { EUI_CHARTS_THEME_DARK, EUI_CHARTS_THEME_LIGHT } from '@elastic/eui/dist import { CoreSetup, IUiSettingsClient } from 'kibana/public'; import moment from 'moment-timezone'; import { ExpressionsSetup } from '../../../../../src/plugins/expressions/public'; +import { UI_SETTINGS } from '../../../../../src/plugins/data/public'; import { xyVisualization } from './xy_visualization'; import { xyChart, getXyChartRenderer } from './xy_expression'; import { legendConfig, xConfig, layerConfig } from './types'; @@ -47,7 +48,7 @@ export class XyVisualization { ? EUI_CHARTS_THEME_DARK.theme : EUI_CHARTS_THEME_LIGHT.theme, timeZone: getTimeZone(core.uiSettings), - histogramBarTarget: core.uiSettings.get('histogram:barTarget'), + histogramBarTarget: core.uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET), }) ); diff --git a/x-pack/plugins/lens/readme.md b/x-pack/plugins/lens/readme.md index 60b4266edadb3..70d7f16b0f7fc 100644 --- a/x-pack/plugins/lens/readme.md +++ b/x-pack/plugins/lens/readme.md @@ -11,4 +11,4 @@ Run all tests from the `x-pack` root directory - You may want to comment out all imports except for Lens in the config file. - API Functional tests: - Run `node scripts/functional_tests_server` - - Run `node ../scripts/functional_test_runner.js --config ./test/api_integration/config.js --grep=Lens` + - Run `node ../scripts/functional_test_runner.js --config ./test/api_integration/config.ts --grep=Lens` diff --git a/x-pack/plugins/licensing/server/index.ts b/x-pack/plugins/licensing/server/index.ts index 76e65afc595c4..ba577660d865c 100644 --- a/x-pack/plugins/licensing/server/index.ts +++ b/x-pack/plugins/licensing/server/index.ts @@ -10,6 +10,7 @@ import { LicensingPlugin } from './plugin'; export const plugin = (context: PluginInitializerContext) => new LicensingPlugin(context); export * from '../common/types'; +export { FeatureUsageServiceSetup, FeatureUsageServiceStart } from './services'; export * from './types'; export { config } from './licensing_config'; export { CheckLicense, wrapRouteWithLicenseCheck } from './wrap_route_with_license_check'; diff --git a/x-pack/plugins/lists/common/schemas/common/schemas.ts b/x-pack/plugins/lists/common/schemas/common/schemas.ts index 14ae030c63df3..7f086647bbc75 100644 --- a/x-pack/plugins/lists/common/schemas/common/schemas.ts +++ b/x-pack/plugins/lists/common/schemas/common/schemas.ts @@ -8,8 +8,8 @@ import * as t from 'io-ts'; -import { DefaultStringArray, NonEmptyString } from '../types'; import { DefaultNamespace } from '../types/default_namespace'; +import { DefaultStringArray, NonEmptyString } from '../../siem_common_deps'; export const name = t.string; export type Name = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts index c10d441d93aa5..4322ff4c2801b 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.ts @@ -24,8 +24,9 @@ import { tags, } from '../common/schemas'; import { Identity, RequiredKeepUndefined } from '../../types'; -import { DefaultEntryArray, DefaultUuid } from '../types'; +import { DefaultEntryArray } from '../types'; import { EntriesArray } from '../types/entries'; +import { DefaultUuid } from '../../siem_common_deps'; export const createExceptionListItemSchema = t.intersection([ t.exact( diff --git a/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts b/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts index 3da8bfca126ae..a0aaa91c81427 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_exception_list_schema.ts @@ -22,7 +22,7 @@ import { tags, } from '../common/schemas'; import { Identity, RequiredKeepUndefined } from '../../types'; -import { DefaultUuid } from '../types/default_uuid'; +import { DefaultUuid } from '../../siem_common_deps'; export const createExceptionListSchema = t.intersection([ t.exact( diff --git a/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.ts b/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.ts index 94299c93b29d8..0a5e861d84483 100644 --- a/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.ts +++ b/x-pack/plugins/lists/common/schemas/request/import_list_item_schema.ts @@ -6,6 +6,7 @@ /* eslint-disable @typescript-eslint/camelcase */ +// TODO: You cannot import a stream from common into the front end code! CHANGE THIS import { Readable } from 'stream'; import * as t from 'io-ts'; @@ -20,6 +21,7 @@ export const importListItemSchema = t.exact( export type ImportListItemSchema = t.TypeOf; +// TODO: You cannot import a stream from common into the front end code! CHANGE THIS export interface HapiReadableStream extends Readable { hapi: { filename: string; diff --git a/x-pack/plugins/lists/common/schemas/types/index.ts b/x-pack/plugins/lists/common/schemas/types/index.ts index 674d7c40c2970..2f38ff86d4fb2 100644 --- a/x-pack/plugins/lists/common/schemas/types/index.ts +++ b/x-pack/plugins/lists/common/schemas/types/index.ts @@ -4,7 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ export * from './default_entries_array'; -export * from './default_string_array'; -export * from './default_uuid'; export * from './entries'; -export * from './non_empty_string'; diff --git a/x-pack/plugins/lists/common/siem_common_deps.ts b/x-pack/plugins/lists/common/siem_common_deps.ts index eb4b393a36da3..3759305987f79 100644 --- a/x-pack/plugins/lists/common/siem_common_deps.ts +++ b/x-pack/plugins/lists/common/siem_common_deps.ts @@ -4,5 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -export { exactCheck } from '../../siem/common/exact_check'; -export { getPaths, foldLeftRight } from '../../siem/common/test_utils'; +export { NonEmptyString } from '../../security_solution/common/detection_engine/schemas/types/non_empty_string'; +export { DefaultUuid } from '../../security_solution/common/detection_engine/schemas/types/default_uuid'; +export { DefaultStringArray } from '../../security_solution/common/detection_engine/schemas/types/default_string_array'; +export { exactCheck } from '../../security_solution/common/exact_check'; +export { getPaths, foldLeftRight } from '../../security_solution/common/test_utils'; diff --git a/x-pack/plugins/lists/server/siem_server_deps.ts b/x-pack/plugins/lists/server/siem_server_deps.ts index 81ebe9f17b06f..df4b07fc46322 100644 --- a/x-pack/plugins/lists/server/siem_server_deps.ts +++ b/x-pack/plugins/lists/server/siem_server_deps.ts @@ -18,4 +18,4 @@ export { getIndexExists, buildRouteValidation, validate, -} from '../../siem/server'; +} from '../../security_solution/server'; diff --git a/x-pack/plugins/maps/public/actions/data_request_actions.ts b/x-pack/plugins/maps/public/actions/data_request_actions.ts index 13b658af6a0f3..a0c484a82e530 100644 --- a/x-pack/plugins/maps/public/actions/data_request_actions.ts +++ b/x-pack/plugins/maps/public/actions/data_request_actions.ts @@ -42,12 +42,7 @@ import { DataRequestAbortError } from '../classes/util/data_request'; export type DataRequestContext = { startLoading(dataId: string, requestToken: symbol, meta: DataMeta): void; - stopLoading( - dataId: string, - requestToken: symbol, - data: FeatureCollection | object, - meta: DataMeta - ): void; + stopLoading(dataId: string, requestToken: symbol, data: object, meta: DataMeta): void; onLoadError(dataId: string, requestToken: symbol, errorMessage: string): void; updateSourceData(newData: unknown): void; isRequestStillActive(dataId: string, requestToken: symbol): boolean; @@ -106,12 +101,8 @@ function getDataRequestContext( dataFilters: getDataFilters(getState()), startLoading: (dataId: string, requestToken: symbol, meta: DataMeta) => dispatch(startDataLoad(layerId, dataId, requestToken, meta)), - stopLoading: ( - dataId: string, - requestToken: symbol, - data: FeatureCollection | object, - meta: DataMeta - ) => dispatch(endDataLoad(layerId, dataId, requestToken, data, meta)), + stopLoading: (dataId: string, requestToken: symbol, data: object, meta: DataMeta) => + dispatch(endDataLoad(layerId, dataId, requestToken, data, meta)), onLoadError: (dataId: string, requestToken: symbol, errorMessage: string) => dispatch(onDataLoadError(layerId, dataId, requestToken, errorMessage)), updateSourceData: (newData: unknown) => { @@ -197,7 +188,7 @@ function endDataLoad( layerId: string, dataId: string, requestToken: symbol, - data: FeatureCollection | object, + data: object, meta: DataMeta ) { return async (dispatch: Dispatch, getState: () => MapStoreState) => { diff --git a/x-pack/plugins/maps/public/angular/get_initial_query.js b/x-pack/plugins/maps/public/angular/get_initial_query.js index 4f61142413671..84f431cf2b3b6 100644 --- a/x-pack/plugins/maps/public/angular/get_initial_query.js +++ b/x-pack/plugins/maps/public/angular/get_initial_query.js @@ -5,6 +5,7 @@ */ import { getUiSettings } from '../kibana_services'; +import { UI_SETTINGS } from '../../../../../src/plugins/data/public'; export function getInitialQuery({ mapStateJSON, appState = {}, userQueryLanguage }) { const settings = getUiSettings(); @@ -22,6 +23,6 @@ export function getInitialQuery({ mapStateJSON, appState = {}, userQueryLanguage return { query: '', - language: userQueryLanguage || settings.get('search:queryLanguage'), + language: userQueryLanguage || settings.get(UI_SETTINGS.SEARCH_QUERY_LANGUAGE), }; } diff --git a/x-pack/plugins/maps/public/angular/get_initial_refresh_config.js b/x-pack/plugins/maps/public/angular/get_initial_refresh_config.js index f13e435cd1d5c..17a50c6c5f685 100644 --- a/x-pack/plugins/maps/public/angular/get_initial_refresh_config.js +++ b/x-pack/plugins/maps/public/angular/get_initial_refresh_config.js @@ -5,6 +5,7 @@ */ import { getUiSettings } from '../kibana_services'; +import { UI_SETTINGS } from '../../../../../src/plugins/data/public'; export function getInitialRefreshConfig({ mapStateJSON, globalState = {} }) { const uiSettings = getUiSettings(); @@ -16,7 +17,7 @@ export function getInitialRefreshConfig({ mapStateJSON, globalState = {} }) { } } - const defaultRefreshConfig = uiSettings.get('timepicker:refreshIntervalDefaults'); + const defaultRefreshConfig = uiSettings.get(UI_SETTINGS.TIMEPICKER_REFRESH_INTERVAL_DEFAULTS); const refreshInterval = { ...defaultRefreshConfig, ...globalState.refreshInterval }; return { isPaused: refreshInterval.pause, diff --git a/x-pack/plugins/maps/public/classes/layers/tile_layer/tile_layer.js b/x-pack/plugins/maps/public/classes/layers/tile_layer/tile_layer.js index cd8ca44d4478b..02df8acbfffad 100644 --- a/x-pack/plugins/maps/public/classes/layers/tile_layer/tile_layer.js +++ b/x-pack/plugins/maps/public/classes/layers/tile_layer/tile_layer.js @@ -34,7 +34,7 @@ export class TileLayer extends AbstractLayer { startLoading(SOURCE_DATA_REQUEST_ID, requestToken, dataFilters); try { const url = await this.getSource().getUrlTemplate(); - stopLoading(SOURCE_DATA_REQUEST_ID, requestToken, url, {}); + stopLoading(SOURCE_DATA_REQUEST_ID, requestToken, { url }, {}); } catch (error) { onLoadError(SOURCE_DATA_REQUEST_ID, requestToken, error.message); } @@ -68,15 +68,16 @@ export class TileLayer extends AbstractLayer { //when turning the layer back into visible, it's possible the url has not been resovled yet. return; } - const url = sourceDataRequest.getData(); - if (!url) { + + const tmsSourceData = sourceDataRequest.getData(); + if (!tmsSourceData || !tmsSourceData.url) { return; } const sourceId = this.getId(); mbMap.addSource(sourceId, { type: 'raster', - tiles: [url], + tiles: [tmsSourceData.url], tileSize: 256, scheme: 'xyz', }); diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js index 7661ad7020194..91dcb057dd837 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/create_source_editor.js @@ -14,7 +14,7 @@ import { NoIndexPatternCallout } from '../../../components/no_index_pattern_call import { i18n } from '@kbn/i18n'; import { EuiFormRow, EuiSpacer } from '@elastic/eui'; -import { AGGREGATABLE_GEO_FIELD_TYPES, getFieldsWithGeoTileAgg } from '../../../index_pattern_util'; +import { getAggregatableGeoFieldTypes, getFieldsWithGeoTileAgg } from '../../../index_pattern_util'; import { RenderAsSelect } from './render_as_select'; export class CreateSourceEditor extends Component { @@ -176,7 +176,7 @@ export class CreateSourceEditor extends Component { placeholder={i18n.translate('xpack.maps.source.esGeoGrid.indexPatternPlaceholder', { defaultMessage: 'Select index pattern', })} - fieldTypes={AGGREGATABLE_GEO_FIELD_TYPES} + fieldTypes={getAggregatableGeoFieldTypes()} onNoIndexPatterns={this._onNoIndexPatterns} /> diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.js b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.js index e77fd93872612..c05c1f2dd7c1e 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.js +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.js @@ -21,6 +21,7 @@ import { getDataSourceLabel } from '../../../../common/i18n_getters'; import { AbstractESAggSource } from '../es_agg_source'; import { DataRequestAbortError } from '../../util/data_request'; import { registerSource } from '../source_registry'; +import { makeESBbox } from '../../../elasticsearch_geo_utils'; export const MAX_GEOTILE_LEVEL = 29; @@ -146,6 +147,7 @@ export class ESGeoGridSource extends AbstractESAggSource { registerCancelCallback, bucketsPerGrid, isRequestStillActive, + bufferedExtent, }) { const gridsPerRequest = Math.floor(DEFAULT_MAX_BUCKETS_LIMIT / bucketsPerGrid); const aggs = { @@ -156,6 +158,7 @@ export class ESGeoGridSource extends AbstractESAggSource { { gridSplit: { geotile_grid: { + bounds: makeESBbox(bufferedExtent), field: this._descriptor.geoField, precision, }, @@ -234,10 +237,12 @@ export class ESGeoGridSource extends AbstractESAggSource { precision, layerName, registerCancelCallback, + bufferedExtent, }) { searchSource.setField('aggs', { gridSplit: { geotile_grid: { + bounds: makeESBbox(bufferedExtent), field: this._descriptor.geoField, precision, }, @@ -282,6 +287,7 @@ export class ESGeoGridSource extends AbstractESAggSource { precision: searchFilters.geogridPrecision, layerName, registerCancelCallback, + bufferedExtent: searchFilters.buffer, }) : await this._compositeAggRequest({ searchSource, @@ -291,6 +297,7 @@ export class ESGeoGridSource extends AbstractESAggSource { registerCancelCallback, bucketsPerGrid, isRequestStillActive, + bufferedExtent: searchFilters.buffer, }); return { diff --git a/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/create_source_editor.js b/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/create_source_editor.js index f599ba93d40d6..38a5850537200 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/create_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/create_source_editor.js @@ -14,7 +14,8 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiFormRow, EuiCallOut } from '@elastic/eui'; -import { AGGREGATABLE_GEO_FIELD_TYPES, getFieldsWithGeoTileAgg } from '../../../index_pattern_util'; +import { getFieldsWithGeoTileAgg } from '../../../index_pattern_util'; +import { ES_GEO_FIELD_TYPE } from '../../../../common/constants'; export class CreateSourceEditor extends Component { static propTypes = { @@ -177,7 +178,7 @@ export class CreateSourceEditor extends Component { placeholder={i18n.translate('xpack.maps.source.pewPew.indexPatternPlaceholder', { defaultMessage: 'Select index pattern', })} - fieldTypes={AGGREGATABLE_GEO_FIELD_TYPES} + fieldTypes={[ES_GEO_FIELD_TYPE.GEO_POINT]} /> ); diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/__tests__/test_util.ts b/x-pack/plugins/maps/public/classes/styles/vector/properties/__tests__/test_util.ts index a8fba834d65ab..f4ef9bdbe5b6d 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/__tests__/test_util.ts +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/__tests__/test_util.ts @@ -25,6 +25,21 @@ class MockField extends AbstractField { } } +export class MockMbMap { + _paintPropertyCalls: unknown[]; + + constructor() { + this._paintPropertyCalls = []; + } + setPaintProperty(...args: unknown[]) { + this._paintPropertyCalls.push([...args]); + } + + getPaintPropertyCalls(): unknown[] { + return this._paintPropertyCalls; + } +} + export const mockField: IField = new MockField({ fieldName: 'foobar', origin: FIELD_ORIGIN.SOURCE, diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.js b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.js index 898da439c44aa..a0af2fbb939d8 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.js +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.js @@ -110,6 +110,9 @@ export class DynamicSizeProperty extends DynamicStyleProperty { _getMbDataDrivenSize({ targetName, minSize, maxSize, minValue, maxValue }) { const lookup = this.supportsMbFeatureState() ? 'feature-state' : 'get'; + + const stops = + minValue === maxValue ? [maxValue, maxSize] : [minValue, minSize, maxValue, maxSize]; return [ 'interpolate', ['linear'], @@ -120,10 +123,7 @@ export class DynamicSizeProperty extends DynamicStyleProperty { fieldName: targetName, fallback: 0, }), - minValue, - minSize, - maxValue, - maxSize, + ...stops, ]; } diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.test.tsx b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.test.tsx index 34f3e796f409f..c60547f3606c5 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.test.tsx +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_size_property.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { IVectorStyle } from '../vector_style'; - jest.mock('ui/new_platform'); jest.mock('../components/vector_style_editor', () => ({ VectorStyleEditor: () => { @@ -18,68 +16,22 @@ import { shallow } from 'enzyme'; // @ts-ignore import { DynamicSizeProperty } from './dynamic_size_property'; -import { StyleMeta } from '../style_meta'; -import { FIELD_ORIGIN, VECTOR_STYLES } from '../../../../../common/constants'; -import { DataRequest } from '../../../util/data_request'; -import { IVectorLayer } from '../../../layers/vector_layer/vector_layer'; +import { VECTOR_STYLES } from '../../../../../common/constants'; import { IField } from '../../../fields/field'; +import { MockMbMap } from './__tests__/test_util'; -// @ts-ignore -const mockField: IField = { - async getLabel() { - return 'foobar_label'; - }, - getName() { - return 'foobar'; - }, - getRootName() { - return 'foobar'; - }, - getOrigin() { - return FIELD_ORIGIN.SOURCE; - }, - supportsFieldMeta() { - return true; - }, - canValueBeFormatted() { - return true; - }, - async getDataType() { - return 'number'; - }, -}; +import { mockField, MockLayer, MockStyle } from './__tests__/test_util'; -// @ts-ignore -const mockLayer: IVectorLayer = { - getDataRequest(): DataRequest | undefined { - return undefined; - }, - getStyle(): IVectorStyle { - // @ts-ignore - return { - getStyleMeta(): StyleMeta { - return new StyleMeta({ - geometryTypes: { - isPointsOnly: true, - isLinesOnly: false, - isPolygonsOnly: false, - }, - fieldMeta: { - foobar: { - range: { min: 0, max: 100, delta: 100 }, - categories: { categories: [] }, - }, - }, - }); - }, - }; - }, -}; - -const makeProperty: DynamicSizeProperty = (options: object) => { - return new DynamicSizeProperty(options, VECTOR_STYLES.ICON_SIZE, mockField, mockLayer, () => { - return (x: string) => x + '_format'; - }); +const makeProperty = (options: object, mockStyle: MockStyle, field: IField = mockField) => { + return new DynamicSizeProperty( + options, + VECTOR_STYLES.ICON_SIZE, + field, + new MockLayer(mockStyle), + () => { + return (x: string) => x + '_format'; + } + ); }; const defaultLegendParams = { @@ -89,7 +41,7 @@ const defaultLegendParams = { describe('renderLegendDetailRow', () => { test('Should render as range', async () => { - const sizeProp = makeProperty(); + const sizeProp = makeProperty({}, new MockStyle({ min: 0, max: 100 })); const legendRow = sizeProp.renderLegendDetailRow(defaultLegendParams); const component = shallow(legendRow); @@ -100,3 +52,70 @@ describe('renderLegendDetailRow', () => { expect(component).toMatchSnapshot(); }); }); + +describe('syncSize', () => { + test('Should sync with circle-radius prop', async () => { + const sizeProp = makeProperty({ minSize: 8, maxSize: 32 }, new MockStyle({ min: 0, max: 100 })); + const mockMbMap = new MockMbMap(); + + sizeProp.syncCircleRadiusWithMb('foobar', mockMbMap); + + expect(mockMbMap.getPaintPropertyCalls()).toEqual([ + [ + 'foobar', + 'circle-radius', + [ + 'interpolate', + ['linear'], + [ + 'coalesce', + [ + 'case', + ['==', ['feature-state', 'foobar'], null], + -1, + ['max', ['min', ['to-number', ['feature-state', 'foobar']], 100], 0], + ], + 0, + ], + 0, + 8, + 100, + 32, + ], + ], + ]); + }); + + test('Should truncate interpolate expression to max when no delta', async () => { + const sizeProp = makeProperty( + { minSize: 8, maxSize: 32 }, + new MockStyle({ min: 100, max: 100 }) + ); + const mockMbMap = new MockMbMap(); + + sizeProp.syncCircleRadiusWithMb('foobar', mockMbMap); + + expect(mockMbMap.getPaintPropertyCalls()).toEqual([ + [ + 'foobar', + 'circle-radius', + [ + 'interpolate', + ['linear'], + [ + 'coalesce', + [ + 'case', + ['==', ['feature-state', 'foobar'], null], + 99, + ['max', ['min', ['to-number', ['feature-state', 'foobar']], 100], 100], + ], + 0, + ], + 100, + 32, + ], + ], + ]); + }); +}); diff --git a/x-pack/plugins/maps/public/connected_components/layer_panel/filter_editor/filter_editor.js b/x-pack/plugins/maps/public/connected_components/layer_panel/filter_editor/filter_editor.js index 75b6b5d66f1de..45c7507160e98 100644 --- a/x-pack/plugins/maps/public/connected_components/layer_panel/filter_editor/filter_editor.js +++ b/x-pack/plugins/maps/public/connected_components/layer_panel/filter_editor/filter_editor.js @@ -20,6 +20,7 @@ import { import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; +import { UI_SETTINGS } from '../../../../../../../src/plugins/data/public'; import { getIndexPatternService, getUiSettings, getData } from '../../../kibana_services'; import { GlobalFilterCheckbox } from '../../../components/global_filter_checkbox'; @@ -101,7 +102,7 @@ export class FilterEditor extends Component { query={ layerQuery ? layerQuery - : { language: uiSettings.get('search:queryLanguage'), query: '' } + : { language: uiSettings.get(UI_SETTINGS.SEARCH_QUERY_LANGUAGE), query: '' } } onQuerySubmit={this._onQueryChange} indexPatterns={this.state.indexPatterns} diff --git a/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/where_expression.js b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/where_expression.js index d87761d3dabe8..8fdb71de2dfed 100644 --- a/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/where_expression.js +++ b/x-pack/plugins/maps/public/connected_components/layer_panel/join_editor/resources/where_expression.js @@ -8,6 +8,7 @@ import React, { Component } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButton, EuiPopover, EuiExpression, EuiFormHelpText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; +import { UI_SETTINGS } from '../../../../../../../../src/plugins/data/public'; import { getUiSettings, getData } from '../../../../kibana_services'; export class WhereExpression extends Component { @@ -79,7 +80,7 @@ export class WhereExpression extends Component { query={ whereQuery ? whereQuery - : { language: getUiSettings().get('search:queryLanguage'), query: '' } + : { language: getUiSettings().get(UI_SETTINGS.SEARCH_QUERY_LANGUAGE), query: '' } } onQuerySubmit={this._onQueryChange} indexPatterns={[indexPattern]} diff --git a/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_geometry_filter_form.js b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_geometry_filter_form.js index b103fb43af97c..e1779c1afbf47 100644 --- a/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_geometry_filter_form.js +++ b/x-pack/plugins/maps/public/connected_components/map/features_tooltip/feature_geometry_filter_form.js @@ -9,18 +9,16 @@ import { EuiIcon } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; +import { URL_MAX_LENGTH } from '../../../../../../../src/core/public'; import { createSpatialFilterWithGeometry } from '../../../elasticsearch_geo_utils'; import { GEO_JSON_TYPE } from '../../../../common/constants'; import { GeometryFilterForm } from '../../../components/geometry_filter_form'; -import { UrlOverflowService } from '../../../../../../../src/plugins/kibana_legacy/public'; import rison from 'rison-node'; // over estimated and imprecise value to ensure filter has additional room for any meta keys added when filter is mapped. const META_OVERHEAD = 100; -const urlOverflow = new UrlOverflowService(); - export class FeatureGeometryFilterForm extends Component { state = { isLoading: false, @@ -82,7 +80,7 @@ export class FeatureGeometryFilterForm extends Component { // No elasticsearch support for pre-indexed shapes and geo_point spatial queries. if ( window.location.href.length + rison.encode(filter).length + META_OVERHEAD > - urlOverflow.failLength() + URL_MAX_LENGTH ) { this.setState({ errorMsg: i18n.translate('xpack.maps.tooltip.geometryFilterForm.filterTooLargeMessage', { diff --git a/x-pack/plugins/maps/public/elasticsearch_geo_utils.js b/x-pack/plugins/maps/public/elasticsearch_geo_utils.js index b89fda29554ee..efd243595db3e 100644 --- a/x-pack/plugins/maps/public/elasticsearch_geo_utils.js +++ b/x-pack/plugins/maps/public/elasticsearch_geo_utils.js @@ -225,39 +225,36 @@ export function geoShapeToGeometry(value, accumulator) { accumulator.push(geoJson); } -function createGeoBoundBoxFilter({ maxLat, maxLon, minLat, minLon }, geoFieldName) { - const top = clampToLatBounds(maxLat); +export function makeESBbox({ maxLat, maxLon, minLat, minLon }) { const bottom = clampToLatBounds(minLat); - - // geo_bounding_box does not support ranges outside of -180 and 180 - // When the area crosses the 180° meridian, - // the value of the lower left longitude will be greater than the value of the upper right longitude. - // http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#30 - let boundingBox; + const top = clampToLatBounds(maxLat); + let esBbox; if (maxLon - minLon >= 360) { - boundingBox = { + esBbox = { top_left: [-180, top], bottom_right: [180, bottom], }; - } else if (maxLon > 180) { - const overflow = maxLon - 180; - boundingBox = { - top_left: [minLon, top], - bottom_right: [-180 + overflow, bottom], - }; - } else if (minLon < -180) { - const overflow = Math.abs(minLon) - 180; - boundingBox = { - top_left: [180 - overflow, top], - bottom_right: [maxLon, bottom], - }; } else { - boundingBox = { - top_left: [minLon, top], - bottom_right: [maxLon, bottom], + // geo_bounding_box does not support ranges outside of -180 and 180 + // When the area crosses the 180° meridian, + // the value of the lower left longitude will be greater than the value of the upper right longitude. + // http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#30 + // + // This ensures bbox goes West->East in the happy case, + // but will be formatted East->West in case it crosses the date-line + const newMinlon = ((minLon + 180 + 360) % 360) - 180; + const newMaxlon = ((maxLon + 180 + 360) % 360) - 180; + esBbox = { + top_left: [newMinlon, top], + bottom_right: [newMaxlon, bottom], }; } + return esBbox; +} + +function createGeoBoundBoxFilter({ maxLat, maxLon, minLat, minLon }, geoFieldName) { + const boundingBox = makeESBbox({ maxLat, maxLon, minLat, minLon }); return { geo_bounding_box: { [geoFieldName]: boundingBox, diff --git a/x-pack/plugins/maps/public/elasticsearch_geo_utils.test.js b/x-pack/plugins/maps/public/elasticsearch_geo_utils.test.js index 05f6a9eec5bd5..a1e4e43f3ab75 100644 --- a/x-pack/plugins/maps/public/elasticsearch_geo_utils.test.js +++ b/x-pack/plugins/maps/public/elasticsearch_geo_utils.test.js @@ -19,6 +19,7 @@ import { createExtentFilter, roundCoordinates, extractFeaturesFromFilters, + makeESBbox, } from './elasticsearch_geo_utils'; import { indexPatterns } from '../../../../src/plugins/data/public'; @@ -594,3 +595,95 @@ describe('extractFeaturesFromFilters', () => { expect(extractFeaturesFromFilters([spatialFilter])).toEqual([]); }); }); + +describe('makeESBbox', () => { + it('Should invert Y-axis', () => { + const bbox = makeESBbox({ + minLon: 10, + maxLon: 20, + minLat: 0, + maxLat: 1, + }); + expect(bbox).toEqual({ bottom_right: [20, 0], top_left: [10, 1] }); + }); + + it('Should snap to 360 width', () => { + const bbox = makeESBbox({ + minLon: 10, + maxLon: 400, + minLat: 0, + maxLat: 1, + }); + expect(bbox).toEqual({ bottom_right: [180, 0], top_left: [-180, 1] }); + }); + + it('Should clamp latitudes', () => { + const bbox = makeESBbox({ + minLon: 10, + maxLon: 400, + minLat: -100, + maxLat: 100, + }); + expect(bbox).toEqual({ bottom_right: [180, -89], top_left: [-180, 89] }); + }); + + it('Should swap West->East orientation to East->West orientation when crossing dateline (West extension)', () => { + const bbox = makeESBbox({ + minLon: -190, + maxLon: 20, + minLat: -100, + maxLat: 100, + }); + expect(bbox).toEqual({ bottom_right: [20, -89], top_left: [170, 89] }); + }); + + it('Should swap West->East orientation to East->West orientation when crossing dateline (West extension) (overrated)', () => { + const bbox = makeESBbox({ + minLon: -190 + 360 + 360, + maxLon: 20 + 360 + 360, + minLat: -100, + maxLat: 100, + }); + expect(bbox).toEqual({ bottom_right: [20, -89], top_left: [170, 89] }); + }); + + it('Should swap West->East orientation to East->West orientation when crossing dateline (east extension)', () => { + const bbox = makeESBbox({ + minLon: 175, + maxLon: 190, + minLat: -100, + maxLat: 100, + }); + expect(bbox).toEqual({ bottom_right: [-170, -89], top_left: [175, 89] }); + }); + + it('Should preserve West->East orientation when _not_ crossing dateline', () => { + const bbox = makeESBbox({ + minLon: 20, + maxLon: 170, + minLat: -100, + maxLat: 100, + }); + expect(bbox).toEqual({ bottom_right: [170, -89], top_left: [20, 89] }); + }); + + it('Should preserve West->East orientation when _not_ crossing dateline _and_ snap longitudes (west extension)', () => { + const bbox = makeESBbox({ + minLon: -190, + maxLon: -185, + minLat: -100, + maxLat: 100, + }); + expect(bbox).toEqual({ bottom_right: [175, -89], top_left: [170, 89] }); + }); + + it('Should preserve West->East orientation when _not_ crossing dateline _and_ snap longitudes (east extension)', () => { + const bbox = makeESBbox({ + minLon: 185, + maxLon: 190, + minLat: -100, + maxLat: 100, + }); + expect(bbox).toEqual({ bottom_right: [-170, -89], top_left: [-175, 89] }); + }); +}); diff --git a/x-pack/plugins/maps/public/index_pattern_util.js b/x-pack/plugins/maps/public/index_pattern_util.js index d695d1087a38d..514feeaa22072 100644 --- a/x-pack/plugins/maps/public/index_pattern_util.js +++ b/x-pack/plugins/maps/public/index_pattern_util.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { getIndexPatternService } from './kibana_services'; +import { getIndexPatternService, getIsGoldPlus } from './kibana_services'; import { indexPatterns } from '../../../../src/plugins/data/public'; import { ES_GEO_FIELD_TYPE } from '../common/constants'; @@ -30,19 +30,24 @@ export function getTermsFields(fields) { }); } -export const AGGREGATABLE_GEO_FIELD_TYPES = [ES_GEO_FIELD_TYPE.GEO_POINT]; +export function getAggregatableGeoFieldTypes() { + const aggregatableFieldTypes = [ES_GEO_FIELD_TYPE.GEO_POINT]; + if (getIsGoldPlus()) { + aggregatableFieldTypes.push(ES_GEO_FIELD_TYPE.GEO_SHAPE); + } + return aggregatableFieldTypes; +} export function getFieldsWithGeoTileAgg(fields) { return fields.filter(supportsGeoTileAgg); } export function supportsGeoTileAgg(field) { - // TODO add geo_shape support with license check return ( field && field.aggregatable && !indexPatterns.isNestedField(field) && - field.type === ES_GEO_FIELD_TYPE.GEO_POINT + getAggregatableGeoFieldTypes().includes(field.type) ); } diff --git a/x-pack/plugins/maps/public/index_pattern_util.test.js b/x-pack/plugins/maps/public/index_pattern_util.test.js index 7f8f1c175cf15..4fa9eb3cadb49 100644 --- a/x-pack/plugins/maps/public/index_pattern_util.test.js +++ b/x-pack/plugins/maps/public/index_pattern_util.test.js @@ -6,7 +6,12 @@ jest.mock('./kibana_services', () => ({})); -import { getSourceFields } from './index_pattern_util'; +import { + getSourceFields, + getAggregatableGeoFieldTypes, + supportsGeoTileAgg, +} from './index_pattern_util'; +import { ES_GEO_FIELD_TYPE } from '../common/constants'; describe('getSourceFields', () => { test('Should remove multi fields from field list', () => { @@ -27,3 +32,77 @@ describe('getSourceFields', () => { expect(sourceFields).toEqual([{ name: 'agent' }]); }); }); + +describe('Gold+ licensing', () => { + const testStubs = [ + { + field: { + type: 'geo_point', + aggregatable: true, + }, + supportedInBasic: true, + supportedInGold: true, + }, + { + field: { + type: 'geo_shape', + aggregatable: false, + }, + supportedInBasic: false, + supportedInGold: false, + }, + { + field: { + type: 'geo_shape', + aggregatable: true, + }, + supportedInBasic: false, + supportedInGold: true, + }, + ]; + + describe('basic license', () => { + beforeEach(() => { + require('./kibana_services').getIsGoldPlus = () => false; + }); + + describe('getAggregatableGeoFieldTypes', () => { + test('Should only include geo_point fields ', () => { + const aggregatableGeoFieldTypes = getAggregatableGeoFieldTypes(); + expect(aggregatableGeoFieldTypes).toEqual([ES_GEO_FIELD_TYPE.GEO_POINT]); + }); + }); + + describe('supportsGeoTileAgg', () => { + testStubs.forEach((stub, index) => { + test(`stub: ${index}`, () => { + const supported = supportsGeoTileAgg(stub.field); + expect(supported).toEqual(stub.supportedInBasic); + }); + }); + }); + }); + + describe('gold license', () => { + beforeEach(() => { + require('./kibana_services').getIsGoldPlus = () => true; + }); + describe('getAggregatableGeoFieldTypes', () => { + test('Should add geo_shape field', () => { + const aggregatableGeoFieldTypes = getAggregatableGeoFieldTypes(); + expect(aggregatableGeoFieldTypes).toEqual([ + ES_GEO_FIELD_TYPE.GEO_POINT, + ES_GEO_FIELD_TYPE.GEO_SHAPE, + ]); + }); + }); + describe('supportsGeoTileAgg', () => { + testStubs.forEach((stub, index) => { + test(`stub: ${index}`, () => { + const supported = supportsGeoTileAgg(stub.field); + expect(supported).toEqual(stub.supportedInGold); + }); + }); + }); + }); +}); diff --git a/x-pack/plugins/maps/public/kibana_services.d.ts b/x-pack/plugins/maps/public/kibana_services.d.ts index 45a4ace8e27a5..d45d7286ebf68 100644 --- a/x-pack/plugins/maps/public/kibana_services.d.ts +++ b/x-pack/plugins/maps/public/kibana_services.d.ts @@ -48,6 +48,7 @@ export function getShowMapsInspectorAdapter(): boolean; export function getPreserveDrawingBuffer(): boolean; export function getEnableVectorTiles(): boolean; export function getProxyElasticMapsServiceInMaps(): boolean; +export function getIsGoldPlus(): boolean; export function setLicenseId(args: unknown): void; export function setInspector(args: unknown): void; @@ -74,3 +75,4 @@ export function setSearchService(args: DataPublicPluginStart['search']): void; export function setKibanaCommonConfig(config: MapsLegacyConfigType): void; export function setMapAppConfig(config: MapsConfigType): void; export function setKibanaVersion(version: string): void; +export function setIsGoldPlus(isGoldPlus: boolean): void; diff --git a/x-pack/plugins/maps/public/kibana_services.js b/x-pack/plugins/maps/public/kibana_services.js index ba7be7a3b2464..1684acfb0f463 100644 --- a/x-pack/plugins/maps/public/kibana_services.js +++ b/x-pack/plugins/maps/public/kibana_services.js @@ -166,3 +166,12 @@ export const getProxyElasticMapsServiceInMaps = () => getKibanaCommonConfig().proxyElasticMapsServiceInMaps; export const getRegionmapLayers = () => _.get(getKibanaCommonConfig(), 'regionmap.layers', []); export const getTilemap = () => _.get(getKibanaCommonConfig(), 'tilemap', []); + +let isGoldPlus = false; +export const setIsGoldPlus = (igp) => { + isGoldPlus = igp; +}; + +export const getIsGoldPlus = () => { + return isGoldPlus; +}; diff --git a/x-pack/plugins/maps/public/plugin.ts b/x-pack/plugins/maps/public/plugin.ts index 3a20f6738a05a..319be46870ebc 100644 --- a/x-pack/plugins/maps/public/plugin.ts +++ b/x-pack/plugins/maps/public/plugin.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Plugin, CoreSetup, CoreStart, PluginInitializerContext } from 'src/core/public'; +import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'src/core/public'; import { Setup as InspectorSetupContract } from 'src/plugins/inspector/public'; // @ts-ignore import { MapView } from './inspector/views/map_view'; @@ -21,29 +21,31 @@ import { setIndexPatternSelect, setIndexPatternService, setInspector, + setIsGoldPlus, + setKibanaCommonConfig, + setKibanaVersion, setLicenseId, + setMapAppConfig, setMapsCapabilities, setNavigation, setSavedObjectsClient, + setSearchService, setTimeFilter, setToasts, setUiActions, setUiSettings, setVisualizations, - setSearchService, - setMapAppConfig, - setKibanaCommonConfig, - setKibanaVersion, } from './kibana_services'; import { featureCatalogueEntry } from './feature_catalogue_entry'; // @ts-ignore import { getMapsVisTypeAlias } from './maps_vis_type_alias'; import { HomePublicPluginSetup } from '../../../../src/plugins/home/public'; import { VisualizationsSetup } from '../../../../src/plugins/visualizations/public'; -import { MAP_SAVED_OBJECT_TYPE } from '../common/constants'; +import { APP_ID, MAP_SAVED_OBJECT_TYPE } from '../common/constants'; import { MapEmbeddableFactory } from './embeddable/map_embeddable_factory'; import { EmbeddableSetup } from '../../../../src/plugins/embeddable/public'; -import { MapsXPackConfig, MapsConfigType } from '../config'; +import { MapsConfigType, MapsXPackConfig } from '../config'; +import { ILicense } from '../../licensing/common/types'; export interface MapsPluginSetupDependencies { inspector: InspectorSetupContract; @@ -76,7 +78,14 @@ export const bindSetupCoreAndPlugins = ( }; export const bindStartCoreAndPlugins = (core: CoreStart, plugins: any) => { - const { fileUpload, data, inspector } = plugins; + const { fileUpload, data, inspector, licensing } = plugins; + if (licensing) { + licensing.license$.subscribe((license: ILicense) => { + const gold = license.check(APP_ID, 'gold'); + setIsGoldPlus(gold.state === 'valid'); + }); + } + setInspector(inspector); setFileUpload(fileUpload); setIndexPatternSelect(data.ui.IndexPatternSelect); diff --git a/x-pack/plugins/ml/common/types/anomaly_detection_jobs/job.ts b/x-pack/plugins/ml/common/types/anomaly_detection_jobs/job.ts index c75387a4b410b..3dbdb8bf3c002 100644 --- a/x-pack/plugins/ml/common/types/anomaly_detection_jobs/job.ts +++ b/x-pack/plugins/ml/common/types/anomaly_detection_jobs/job.ts @@ -78,6 +78,7 @@ export interface DataDescription { export interface ModelPlotConfig { enabled: boolean; + annotations_enabled?: boolean; terms?: string; } diff --git a/x-pack/plugins/ml/common/util/validators.ts b/x-pack/plugins/ml/common/util/validators.ts index 6f959c50219cf..5dcdec0553106 100644 --- a/x-pack/plugins/ml/common/util/validators.ts +++ b/x-pack/plugins/ml/common/util/validators.ts @@ -65,6 +65,8 @@ export function requiredValidator() { }; } +export type ValidationResult = object | null; + export function memoryInputValidator(allowedUnits = ALLOWED_DATA_UNITS) { return (value: any) => { if (typeof value !== 'string' || value === '') { diff --git a/x-pack/plugins/ml/public/application/components/job_selector/custom_selection_table/custom_selection_table.js b/x-pack/plugins/ml/public/application/components/custom_selection_table/custom_selection_table.js similarity index 84% rename from x-pack/plugins/ml/public/application/components/job_selector/custom_selection_table/custom_selection_table.js rename to x-pack/plugins/ml/public/application/components/custom_selection_table/custom_selection_table.js index af282d53273d1..c86b716b2f49b 100644 --- a/x-pack/plugins/ml/public/application/components/job_selector/custom_selection_table/custom_selection_table.js +++ b/x-pack/plugins/ml/public/application/components/custom_selection_table/custom_selection_table.js @@ -29,7 +29,7 @@ import { import { Pager } from '@elastic/eui/lib/services'; import { i18n } from '@kbn/i18n'; -const JOBS_PER_PAGE = 20; +const ITEMS_PER_PAGE = 20; function getError(error) { if (error !== null) { @@ -43,15 +43,18 @@ function getError(error) { } export function CustomSelectionTable({ + checkboxDisabledCheck, columns, filterDefaultFields, filters, items, + itemsPerPage = ITEMS_PER_PAGE, onTableChange, + radioDisabledCheck, selectedIds, singleSelection, sortableProperties, - timeseriesOnly, + tableItemId = 'id', }) { const [itemIdToSelectedMap, setItemIdToSelectedMap] = useState(getCurrentlySelectedItemIdsMap()); const [currentItems, setCurrentItems] = useState(items); @@ -59,7 +62,7 @@ export function CustomSelectionTable({ const [sortedColumn, setSortedColumn] = useState(''); const [pager, setPager] = useState(); const [pagerSettings, setPagerSettings] = useState({ - itemsPerPage: JOBS_PER_PAGE, + itemsPerPage: itemsPerPage, firstItemIndex: 0, lastItemIndex: 1, }); @@ -77,9 +80,9 @@ export function CustomSelectionTable({ }, [selectedIds]); // eslint-disable-line useEffect(() => { - const tablePager = new Pager(currentItems.length, JOBS_PER_PAGE); + const tablePager = new Pager(currentItems.length, itemsPerPage); setPagerSettings({ - itemsPerPage: JOBS_PER_PAGE, + itemsPerPage: itemsPerPage, firstItemIndex: tablePager.getFirstItemIndex(), lastItemIndex: tablePager.getLastItemIndex(), }); @@ -100,7 +103,7 @@ export function CustomSelectionTable({ function handleTableChange({ isSelected, itemId }) { const selectedMapIds = Object.getOwnPropertyNames(itemIdToSelectedMap); - const currentItemIds = currentItems.map((item) => item.id); + const currentItemIds = currentItems.map((item) => item[tableItemId]); let currentSelected = selectedMapIds.filter( (id) => itemIdToSelectedMap[id] === true && id !== itemId @@ -124,11 +127,11 @@ export function CustomSelectionTable({ onTableChange(currentSelected); } - function handleChangeItemsPerPage(itemsPerPage) { - pager.setItemsPerPage(itemsPerPage); + function handleChangeItemsPerPage(numItemsPerPage) { + pager.setItemsPerPage(numItemsPerPage); setPagerSettings({ ...pagerSettings, - itemsPerPage, + itemsPerPage: numItemsPerPage, firstItemIndex: pager.getFirstItemIndex(), lastItemIndex: pager.getLastItemIndex(), }); @@ -161,7 +164,9 @@ export function CustomSelectionTable({ } function areAllItemsSelected() { - const indexOfUnselectedItem = currentItems.findIndex((item) => !isItemSelected(item.id)); + const indexOfUnselectedItem = currentItems.findIndex( + (item) => !isItemSelected(item[tableItemId]) + ); return indexOfUnselectedItem === -1; } @@ -199,7 +204,7 @@ export function CustomSelectionTable({ function toggleAll() { const allSelected = areAllItemsSelected() || itemIdToSelectedMap.all === true; const newItemIdToSelectedMap = {}; - currentItems.forEach((item) => (newItemIdToSelectedMap[item.id] = !allSelected)); + currentItems.forEach((item) => (newItemIdToSelectedMap[item[tableItemId]] = !allSelected)); setItemIdToSelectedMap(newItemIdToSelectedMap); handleTableChange({ isSelected: !allSelected, itemId: 'all' }); } @@ -255,20 +260,23 @@ export function CustomSelectionTable({ {!singleSelection && ( toggleItem(item.id)} + disabled={ + checkboxDisabledCheck !== undefined ? checkboxDisabledCheck(item) : undefined + } + id={`${item[tableItemId]}-checkbox`} + data-test-subj={`${item[tableItemId]}-checkbox`} + checked={isItemSelected(item[tableItemId])} + onChange={() => toggleItem(item[tableItemId])} type="inList" /> )} {singleSelection && ( toggleItem(item.id)} - disabled={timeseriesOnly && item.isSingleMetricViewerJob === false} + id={item[tableItemId]} + data-test-subj={`${item[tableItemId]}-radio-button`} + checked={isItemSelected(item[tableItemId])} + onChange={() => toggleItem(item[tableItemId])} + disabled={radioDisabledCheck !== undefined ? radioDisabledCheck(item) : undefined} /> )} @@ -299,11 +307,11 @@ export function CustomSelectionTable({ return ( {cells} @@ -331,7 +339,7 @@ export function CustomSelectionTable({ - + {renderSelectAll(true)} - + {renderHeaderCells()} {renderRows()} @@ -368,7 +376,7 @@ export function CustomSelectionTable({ handlePageChange(pageIndex)} @@ -379,13 +387,16 @@ export function CustomSelectionTable({ } CustomSelectionTable.propTypes = { + checkboxDisabledCheck: PropTypes.func, columns: PropTypes.array.isRequired, filterDefaultFields: PropTypes.array, filters: PropTypes.array, items: PropTypes.array.isRequired, + itemsPerPage: PropTypes.number, onTableChange: PropTypes.func.isRequired, + radioDisabledCheck: PropTypes.func, selectedId: PropTypes.array, singleSelection: PropTypes.bool, sortableProperties: PropTypes.object, - timeseriesOnly: PropTypes.bool, + tableItemId: PropTypes.string, }; diff --git a/x-pack/plugins/ml/public/application/components/job_selector/custom_selection_table/index.js b/x-pack/plugins/ml/public/application/components/custom_selection_table/index.js similarity index 100% rename from x-pack/plugins/ml/public/application/components/job_selector/custom_selection_table/index.js rename to x-pack/plugins/ml/public/application/components/custom_selection_table/index.js diff --git a/x-pack/plugins/ml/public/application/components/data_grid/common.ts b/x-pack/plugins/ml/public/application/components/data_grid/common.ts index 44a2473f75937..7d0559c215114 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/common.ts +++ b/x-pack/plugins/ml/public/application/components/data_grid/common.ts @@ -29,6 +29,7 @@ import { FEATURE_IMPORTANCE, FEATURE_INFLUENCE, OUTLIER_SCORE, + TOP_CLASSES, } from '../../data_frame_analytics/common/constants'; import { formatHumanReadableDateTimeSeconds } from '../../util/date_utils'; import { getNestedProperty } from '../../util/object_utils'; @@ -110,7 +111,10 @@ export const getDataGridSchemasFromFieldTypes = (fieldTypes: FieldTypes, results schema = 'numeric'; } - if (field.includes(`${resultsField}.${FEATURE_IMPORTANCE}`)) { + if ( + field.includes(`${resultsField}.${FEATURE_IMPORTANCE}`) || + field.includes(`${resultsField}.${TOP_CLASSES}`) + ) { schema = 'json'; } diff --git a/x-pack/plugins/ml/public/application/components/job_selector/job_selector_table/job_selector_table.js b/x-pack/plugins/ml/public/application/components/job_selector/job_selector_table/job_selector_table.js index 4eeef560dd6d1..7b104ea372ae5 100644 --- a/x-pack/plugins/ml/public/application/components/job_selector/job_selector_table/job_selector_table.js +++ b/x-pack/plugins/ml/public/application/components/job_selector/job_selector_table/job_selector_table.js @@ -6,7 +6,7 @@ import React, { Fragment, useState, useEffect } from 'react'; import { PropTypes } from 'prop-types'; -import { CustomSelectionTable } from '../custom_selection_table'; +import { CustomSelectionTable } from '../../custom_selection_table'; import { JobSelectorBadge } from '../job_selector_badge'; import { TimeRangeBar } from '../timerange_bar'; @@ -107,7 +107,7 @@ export function JobSelectorTable({ id: 'checkbox', isCheckbox: true, textOnly: false, - width: '24px', + width: '32px', }, { label: 'job ID', @@ -157,6 +157,9 @@ export function JobSelectorTable({ filterDefaultFields={!singleSelection ? JOB_FILTER_FIELDS : undefined} items={jobs} onTableChange={(selectionFromTable) => onSelection({ selectionFromTable })} + radioDisabledCheck={(item) => { + return timeseriesOnly && item.isSingleMetricViewerJob === false; + }} selectedIds={selectedIds} singleSelection={singleSelection} sortableProperties={sortableProperties} diff --git a/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js b/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js index 0f3b484402819..eed57aaf1b491 100644 --- a/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js +++ b/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js @@ -402,7 +402,14 @@ class RuleEditorFlyoutUI extends Component { } ) ); - this.closeFlyout(); + const updatedJob = mlJobService.getJob(anomaly.jobId); + const updatedDetector = updatedJob.analysis_config.detectors[detectorIndex]; + const updatedRules = updatedDetector.custom_rules; + if (!updatedRules) { + this.closeFlyout(); + } else { + this.setState({ job: { ...updatedJob } }); + } } else { toasts.addDanger( i18n.translate( diff --git a/x-pack/plugins/ml/public/application/components/rule_editor/select_rule_action/select_rule_action.js b/x-pack/plugins/ml/public/application/components/rule_editor/select_rule_action/select_rule_action.js index 309e271ad26a4..c2f5820f84a9e 100644 --- a/x-pack/plugins/ml/public/application/components/rule_editor/select_rule_action/select_rule_action.js +++ b/x-pack/plugins/ml/public/application/components/rule_editor/select_rule_action/select_rule_action.js @@ -32,7 +32,7 @@ export function SelectRuleAction({ if (rules.length > 0) { ruleActionPanels = rules.map((rule, index) => { return ( - + { + let numTopClasses; + if (isClassificationAnalysis(analysis) && analysis.classification.num_top_classes !== undefined) { + numTopClasses = analysis.classification.num_top_classes; + } + return numTopClasses; +}; + export const getNumTopFeatureImportanceValues = ( analysis: AnalysisConfig ): @@ -263,11 +288,13 @@ export const isClassificationAnalysis = (arg: any): arg is ClassificationAnalysi }; export const isResultsSearchBoolQuery = (arg: any): arg is ResultsSearchBoolQuery => { + if (arg === undefined) return false; const keys = Object.keys(arg); return keys.length === 1 && keys[0] === 'bool'; }; export const isQueryStringQuery = (arg: any): arg is QueryStringQuery => { + if (arg === undefined) return false; const keys = Object.keys(arg); return keys.length === 1 && keys[0] === 'query_string'; }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/constants.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/constants.ts index 51b2918012c8d..2f14dfdfdfca3 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/constants.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/constants.ts @@ -7,4 +7,5 @@ export const DEFAULT_RESULTS_FIELD = 'ml'; export const FEATURE_IMPORTANCE = 'feature_importance'; export const FEATURE_INFLUENCE = 'feature_influence'; +export const TOP_CLASSES = 'top_classes'; export const OUTLIER_SCORE = 'outlier_score'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts index 8db349b395cfc..0a64886c80a63 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts @@ -5,6 +5,7 @@ */ import { + getNumTopClasses, getNumTopFeatureImportanceValues, getPredictedFieldName, getDependentVar, @@ -18,7 +19,7 @@ import { Field } from '../../../../common/types/fields'; import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../../../../../../../src/plugins/data/public'; import { newJobCapsService } from '../../services/new_job_capabilities_service'; -import { FEATURE_IMPORTANCE, FEATURE_INFLUENCE, OUTLIER_SCORE } from './constants'; +import { FEATURE_IMPORTANCE, FEATURE_INFLUENCE, OUTLIER_SCORE, TOP_CLASSES } from './constants'; export type EsId = string; export type EsDocSource = Record; @@ -177,6 +178,7 @@ export const getDefaultFieldsFromJobCaps = ( const featureImportanceFields = []; const featureInfluenceFields = []; + const topClassesFields = []; const allFields: any = []; let type: ES_FIELD_TYPES | undefined; let predictedField: string | undefined; @@ -207,13 +209,14 @@ export const getDefaultFieldsFromJobCaps = ( type = newJobCapsService.getFieldById(dependentVariable)?.type; const predictionFieldName = getPredictionFieldName(jobConfig.analysis); const numTopFeatureImportanceValues = getNumTopFeatureImportanceValues(jobConfig.analysis); + const numTopClasses = getNumTopClasses(jobConfig.analysis); const defaultPredictionField = `${dependentVariable}_prediction`; predictedField = `${resultsField}.${ predictionFieldName ? predictionFieldName : defaultPredictionField }`; - if ((numTopFeatureImportanceValues ?? 0) > 0 && needsDestIndexFields === true) { + if ((numTopFeatureImportanceValues ?? 0) > 0) { featureImportanceFields.push({ id: `${resultsField}.${FEATURE_IMPORTANCE}`, name: `${resultsField}.${FEATURE_IMPORTANCE}`, @@ -221,6 +224,14 @@ export const getDefaultFieldsFromJobCaps = ( }); } + if ((numTopClasses ?? 0) > 0) { + topClassesFields.push({ + id: `${resultsField}.${TOP_CLASSES}`, + name: `${resultsField}.${TOP_CLASSES}`, + type: KBN_FIELD_TYPES.UNKNOWN, + }); + } + // Only need to add these fields if we didn't use dest index pattern to get the fields if (needsDestIndexFields === true) { allFields.push( @@ -234,7 +245,12 @@ export const getDefaultFieldsFromJobCaps = ( } } - allFields.push(...fields, ...featureImportanceFields, ...featureInfluenceFields); + allFields.push( + ...fields, + ...featureImportanceFields, + ...featureInfluenceFields, + ...topClassesFields + ); allFields.sort(({ name: a }: { name: string }, { name: b }: { name: string }) => sortExplorationResultsFields(a, b, jobConfig) ); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/index.ts index 400902c152c9e..58343e26153cc 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/index.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/index.ts @@ -17,6 +17,7 @@ export { IndexPattern, REFRESH_ANALYTICS_LIST_STATE, ANALYSIS_CONFIG_TYPE, + OUTLIER_ANALYSIS_METHOD, RegressionEvaluateResponse, getValuesFromResponse, loadEvalData, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/advanced_step.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/advanced_step.tsx new file mode 100644 index 0000000000000..f957dcab2e87e --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/advanced_step.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC } from 'react'; +import { EuiForm } from '@elastic/eui'; + +import { CreateAnalyticsStepProps } from '../../../analytics_management/hooks/use_create_analytics_form'; +import { AdvancedStepForm } from './advanced_step_form'; +import { AdvancedStepDetails } from './advanced_step_details'; +import { ANALYTICS_STEPS } from '../../page'; + +export const AdvancedStep: FC = ({ + actions, + state, + step, + setCurrentStep, + stepActivated, +}) => { + return ( + + {step === ANALYTICS_STEPS.ADVANCED && ( + + )} + {step !== ANALYTICS_STEPS.ADVANCED && stepActivated === true && ( + + )} + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/advanced_step_details.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/advanced_step_details.tsx new file mode 100644 index 0000000000000..a9c8b6d4040ad --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/advanced_step_details.tsx @@ -0,0 +1,274 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, Fragment } from 'react'; +import { i18n } from '@kbn/i18n'; +import { + EuiButtonEmpty, + EuiDescriptionList, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiTitle, +} from '@elastic/eui'; +import { + UNSET_CONFIG_ITEM, + State, +} from '../../../analytics_management/hooks/use_create_analytics_form/state'; +import { ANALYSIS_CONFIG_TYPE } from '../../../../common/analytics'; +import { ANALYTICS_STEPS } from '../../page'; + +function getStringValue(value: number | undefined) { + return value !== undefined ? `${value}` : UNSET_CONFIG_ITEM; +} + +export interface ListItems { + title: string; + description: string | JSX.Element; +} + +export const AdvancedStepDetails: FC<{ setCurrentStep: any; state: State }> = ({ + setCurrentStep, + state, +}) => { + const { form, isJobCreated } = state; + const { + computeFeatureInfluence, + dependentVariable, + eta, + featureBagFraction, + featureInfluenceThreshold, + gamma, + jobType, + lambda, + method, + maxTrees, + modelMemoryLimit, + nNeighbors, + numTopClasses, + numTopFeatureImportanceValues, + outlierFraction, + predictionFieldName, + randomizeSeed, + standardizationEnabled, + } = form; + + const isRegOrClassJob = + jobType === ANALYSIS_CONFIG_TYPE.REGRESSION || jobType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION; + + const advancedFirstCol: ListItems[] = []; + const advancedSecondCol: ListItems[] = []; + const advancedThirdCol: ListItems[] = []; + + const hyperFirstCol: ListItems[] = []; + const hyperSecondCol: ListItems[] = []; + const hyperThirdCol: ListItems[] = []; + + if (jobType === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION) { + advancedFirstCol.push({ + title: i18n.translate( + 'xpack.ml.dataframe.analytics.create.configDetails.computeFeatureInfluence', + { + defaultMessage: 'Compute feature influence', + } + ), + description: computeFeatureInfluence, + }); + + advancedSecondCol.push({ + title: i18n.translate( + 'xpack.ml.dataframe.analytics.create.configDetails.featureInfluenceThreshold', + { + defaultMessage: 'Feature influence threshold', + } + ), + description: getStringValue(featureInfluenceThreshold), + }); + + advancedThirdCol.push({ + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.modelMemoryLimit', { + defaultMessage: 'Model memory limit', + }), + description: `${modelMemoryLimit}`, + }); + + hyperFirstCol.push( + { + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.nNeighbors', { + defaultMessage: 'N neighbors', + }), + description: getStringValue(nNeighbors), + }, + { + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.outlierFraction', { + defaultMessage: 'Outlier fraction', + }), + description: getStringValue(outlierFraction), + } + ); + + hyperSecondCol.push({ + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.method', { + defaultMessage: 'Method', + }), + description: method !== undefined ? method : UNSET_CONFIG_ITEM, + }); + + hyperThirdCol.push({ + title: i18n.translate( + 'xpack.ml.dataframe.analytics.create.configDetails.standardizationEnabled', + { + defaultMessage: 'Standardization enabled', + } + ), + description: `${standardizationEnabled}`, + }); + } + + if (isRegOrClassJob) { + if (jobType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION) { + advancedFirstCol.push({ + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.numTopClasses', { + defaultMessage: 'Top classes', + }), + description: `${numTopClasses}`, + }); + } + + advancedFirstCol.push({ + title: i18n.translate( + 'xpack.ml.dataframe.analytics.create.configDetails.numTopFeatureImportanceValues', + { + defaultMessage: 'Top feature importance values', + } + ), + description: `${numTopFeatureImportanceValues}`, + }); + + hyperFirstCol.push( + { + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.lambdaFields', { + defaultMessage: 'Lambda', + }), + description: getStringValue(lambda), + }, + { + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.eta', { + defaultMessage: 'Eta', + }), + description: getStringValue(eta), + } + ); + + advancedSecondCol.push({ + title: i18n.translate( + 'xpack.ml.dataframe.analytics.create.configDetails.predictionFieldName', + { + defaultMessage: 'Prediction field name', + } + ), + description: predictionFieldName ? predictionFieldName : `${dependentVariable}_prediction`, + }); + + hyperSecondCol.push( + { + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.maxTreesFields', { + defaultMessage: 'Max trees', + }), + description: getStringValue(maxTrees), + }, + { + title: i18n.translate( + 'xpack.ml.dataframe.analytics.create.configDetails.featureBagFraction', + { + defaultMessage: 'Feature bag fraction', + } + ), + description: getStringValue(featureBagFraction), + } + ); + + advancedThirdCol.push({ + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.modelMemoryLimit', { + defaultMessage: 'Model memory limit', + }), + description: `${modelMemoryLimit}`, + }); + + hyperThirdCol.push( + { + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.gamma', { + defaultMessage: 'Gamma', + }), + description: getStringValue(gamma), + }, + { + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.randomizedSeed', { + defaultMessage: 'Randomized seed', + }), + description: getStringValue(randomizeSeed), + } + ); + } + + return ( + + +

+ {i18n.translate('xpack.ml.dataframe.analytics.create.advancedConfigDetailsTitle', { + defaultMessage: 'Advanced configuration', + })} +

+
+ + + + + + + + + + + + + + +

+ {i18n.translate('xpack.ml.dataframe.analytics.create.hyperParametersDetailsTitle', { + defaultMessage: 'Hyper parameters', + })} +

+
+ + + + + + + + + + + + + + {!isJobCreated && ( + { + setCurrentStep(ANALYTICS_STEPS.ADVANCED); + }} + > + {i18n.translate('xpack.ml.dataframe.analytics.create.advancedDetails.editButtonText', { + defaultMessage: 'Edit', + })} + + )} +
+ ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/advanced_step_form.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/advanced_step_form.tsx new file mode 100644 index 0000000000000..8b137ac72361c --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/advanced_step_form.tsx @@ -0,0 +1,332 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, Fragment, useMemo } from 'react'; +import { + EuiAccordion, + EuiFieldNumber, + EuiFieldText, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiSelect, + EuiSpacer, + EuiTitle, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { HyperParameters } from './hyper_parameters'; +import { CreateAnalyticsStepProps } from '../../../analytics_management/hooks/use_create_analytics_form'; +import { getModelMemoryLimitErrors } from '../../../analytics_management/hooks/use_create_analytics_form/reducer'; +import { + ANALYSIS_CONFIG_TYPE, + NUM_TOP_FEATURE_IMPORTANCE_VALUES_MIN, +} from '../../../../common/analytics'; +import { DEFAULT_MODEL_MEMORY_LIMIT } from '../../../analytics_management/hooks/use_create_analytics_form/state'; +import { ANALYTICS_STEPS } from '../../page'; +import { ContinueButton } from '../continue_button'; +import { OutlierHyperParameters } from './outlier_hyper_parameters'; + +export function getNumberValue(value?: number) { + return value === undefined ? '' : +value; +} + +export const AdvancedStepForm: FC = ({ + actions, + state, + setCurrentStep, +}) => { + const { setFormState } = actions; + const { form, isJobCreated } = state; + const { + computeFeatureInfluence, + featureInfluenceThreshold, + jobType, + modelMemoryLimit, + modelMemoryLimitValidationResult, + numTopClasses, + numTopFeatureImportanceValues, + numTopFeatureImportanceValuesValid, + predictionFieldName, + } = form; + + const mmlErrors = useMemo(() => getModelMemoryLimitErrors(modelMemoryLimitValidationResult), [ + modelMemoryLimitValidationResult, + ]); + + const isRegOrClassJob = + jobType === ANALYSIS_CONFIG_TYPE.REGRESSION || jobType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION; + + const mmlInvalid = modelMemoryLimitValidationResult !== null; + + const outlierDetectionAdvancedConfig = ( + + + + { + setFormState({ + computeFeatureInfluence: e.target.value, + }); + }} + /> + + + + + + setFormState({ + featureInfluenceThreshold: e.target.value === '' ? undefined : +e.target.value, + }) + } + data-test-subj="mlAnalyticsCreateJobWizardFeatureInfluenceThresholdInput" + min={0} + max={1} + step={0.001} + value={getNumberValue(featureInfluenceThreshold)} + /> + + + + ); + + const regAndClassAdvancedConfig = ( + + + + {i18n.translate( + 'xpack.ml.dataframe.analytics.create.numTopFeatureImportanceValuesErrorText', + { + defaultMessage: 'Invalid maximum number of feature importance values.', + } + )} + , + ] + : []), + ]} + > + + setFormState({ + numTopFeatureImportanceValues: e.target.value === '' ? undefined : +e.target.value, + }) + } + step={1} + value={getNumberValue(numTopFeatureImportanceValues)} + /> + +
+ + _prediction.', + } + )} + > + setFormState({ predictionFieldName: e.target.value })} + data-test-subj="mlAnalyticsCreateJobWizardPredictionFieldNameInput" + /> + + + + ); + + return ( + + +

+ {i18n.translate('xpack.ml.dataframe.analytics.create.advancedConfigSectionTitle', { + defaultMessage: 'Advanced configuration', + })} +

+
+ + {jobType === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION && outlierDetectionAdvancedConfig} + {isRegOrClassJob && regAndClassAdvancedConfig} + {jobType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION && ( + + + + setFormState({ + numTopClasses: e.target.value === '' ? undefined : +e.target.value, + }) + } + step={1} + value={getNumberValue(numTopClasses)} + /> + + + )} + + + setFormState({ modelMemoryLimit: e.target.value })} + isInvalid={mmlInvalid} + data-test-subj="mlAnalyticsCreateJobWizardModelMemoryInput" + /> + + + + + +

+ {i18n.translate('xpack.ml.dataframe.analytics.create.hyperParametersSectionTitle', { + defaultMessage: 'Hyper parameters', + })} +

+ + } + initialIsOpen={false} + data-test-subj="mlAnalyticsCreateJobWizardHyperParametersSection" + > + + {jobType === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION && ( + + )} + {isRegOrClassJob && } + +
+ + { + setCurrentStep(ANALYTICS_STEPS.DETAILS); + }} + /> +
+ ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/hyper_parameters.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/hyper_parameters.tsx new file mode 100644 index 0000000000000..144a062106003 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/hyper_parameters.tsx @@ -0,0 +1,188 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, Fragment } from 'react'; +import { EuiFieldNumber, EuiFlexItem, EuiFormRow } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { CreateAnalyticsFormProps } from '../../../analytics_management/hooks/use_create_analytics_form'; +import { getNumberValue } from './advanced_step_form'; + +const MAX_TREES_LIMIT = 2000; + +export const HyperParameters: FC = ({ actions, state }) => { + const { setFormState } = actions; + + const { eta, featureBagFraction, gamma, lambda, maxTrees, randomizeSeed } = state.form; + + return ( + + + + + setFormState({ lambda: e.target.value === '' ? undefined : +e.target.value }) + } + step={0.001} + min={0} + value={getNumberValue(lambda)} + /> + + + + + + setFormState({ maxTrees: e.target.value === '' ? undefined : +e.target.value }) + } + isInvalid={maxTrees !== undefined && !Number.isInteger(maxTrees)} + step={1} + min={1} + max={MAX_TREES_LIMIT} + value={getNumberValue(maxTrees)} + /> + + + + + + setFormState({ gamma: e.target.value === '' ? undefined : +e.target.value }) + } + step={0.001} + min={0} + value={getNumberValue(gamma)} + /> + + + + + + setFormState({ eta: e.target.value === '' ? undefined : +e.target.value }) + } + step={0.001} + min={0.001} + max={1} + value={getNumberValue(eta)} + /> + + + + + + setFormState({ + featureBagFraction: e.target.value === '' ? undefined : +e.target.value, + }) + } + isInvalid={ + featureBagFraction !== undefined && + (featureBagFraction > 1 || featureBagFraction <= 0) + } + step={0.001} + max={1} + value={getNumberValue(featureBagFraction)} + /> + + + + + + setFormState({ randomizeSeed: e.target.value === '' ? undefined : +e.target.value }) + } + isInvalid={randomizeSeed !== undefined && typeof randomizeSeed !== 'number'} + value={getNumberValue(randomizeSeed)} + step={1} + /> + + + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/index.ts new file mode 100644 index 0000000000000..6a19e55b533c1 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { AdvancedStep } from './advanced_step'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/outlier_hyper_parameters.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/outlier_hyper_parameters.tsx new file mode 100644 index 0000000000000..dfe7969d8a6d9 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/outlier_hyper_parameters.tsx @@ -0,0 +1,153 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, Fragment } from 'react'; +import { EuiFieldNumber, EuiFlexItem, EuiFormRow, EuiSelect } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { OUTLIER_ANALYSIS_METHOD } from '../../../../common/analytics'; +import { CreateAnalyticsFormProps } from '../../../analytics_management/hooks/use_create_analytics_form'; +import { getNumberValue } from './advanced_step_form'; + +export const OutlierHyperParameters: FC = ({ actions, state }) => { + const { setFormState } = actions; + + const { method, nNeighbors, outlierFraction, standardizationEnabled } = state.form; + + return ( + + + + ({ + value: outlierMethod, + text: outlierMethod, + }))} + value={method} + hasNoInitialSelection={true} + onChange={(e) => { + setFormState({ method: e.target.value }); + }} + data-test-subj="mlAnalyticsCreateJobWizardMethodInput" + /> + + + + + + setFormState({ nNeighbors: e.target.value === '' ? undefined : +e.target.value }) + } + step={1} + min={1} + value={getNumberValue(nNeighbors)} + /> + + + + + + setFormState({ outlierFraction: e.target.value === '' ? undefined : +e.target.value }) + } + step={0.001} + min={0} + max={1} + value={getNumberValue(outlierFraction)} + /> + + + + + { + setFormState({ standardizationEnabled: e.target.value }); + }} + /> + + + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx new file mode 100644 index 0000000000000..e437d27372a3e --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/back_to_list_panel.tsx @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, Fragment } from 'react'; +import { EuiCard, EuiHorizontalRule, EuiIcon } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +function redirectToAnalyticsManagementPage() { + window.location.href = '#/data_frame_analytics?'; +} + +export const BackToListPanel: FC = () => ( + + + } + title={i18n.translate('xpack.ml.dataframe.analytics.create.analyticsListCardTitle', { + defaultMessage: 'Data Frame Analytics', + })} + description={i18n.translate( + 'xpack.ml.dataframe.analytics.create.analyticsListCardDescription', + { + defaultMessage: 'Return to the analytics management page.', + } + )} + onClick={redirectToAnalyticsManagementPage} + data-test-subj="analyticsWizardCardManagement" + /> + +); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/index.ts new file mode 100644 index 0000000000000..4da6561562879 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/back_to_list_panel/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { BackToListPanel } from './back_to_list_panel'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/analysis_fields_table.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/analysis_fields_table.tsx new file mode 100644 index 0000000000000..ad540285e49f0 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/analysis_fields_table.tsx @@ -0,0 +1,207 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, Fragment, memo, useEffect, useState } from 'react'; +import { EuiCallOut, EuiFormRow, EuiPanel, EuiSpacer, EuiText } from '@elastic/eui'; +// @ts-ignore no declaration +import { LEFT_ALIGNMENT, CENTER_ALIGNMENT, SortableProperties } from '@elastic/eui/lib/services'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { FieldSelectionItem } from '../../../../common/analytics'; +// @ts-ignore could not find declaration file +import { CustomSelectionTable } from '../../../../../components/custom_selection_table'; + +const columns = [ + { + id: 'checkbox', + isCheckbox: true, + textOnly: false, + width: '32px', + }, + { + label: i18n.translate('xpack.ml.dataframe.analytics.create.analyticsTable.fieldNameColumn', { + defaultMessage: 'Field name', + }), + id: 'name', + isSortable: true, + alignment: LEFT_ALIGNMENT, + }, + { + id: 'mapping_types', + label: i18n.translate('xpack.ml.dataframe.analytics.create.analyticsTable.mappingColumn', { + defaultMessage: 'Mapping', + }), + isSortable: false, + alignment: LEFT_ALIGNMENT, + }, + { + label: i18n.translate('xpack.ml.dataframe.analytics.create.analyticsTable.isIncludedColumn', { + defaultMessage: 'Is included', + }), + id: 'is_included', + alignment: LEFT_ALIGNMENT, + isSortable: true, + // eslint-disable-next-line @typescript-eslint/camelcase + render: ({ is_included }: { is_included: boolean }) => (is_included ? 'Yes' : 'No'), + }, + { + label: i18n.translate('xpack.ml.dataframe.analytics.create.analyticsTable.isRequiredColumn', { + defaultMessage: 'Is required', + }), + id: 'is_required', + alignment: LEFT_ALIGNMENT, + isSortable: true, + // eslint-disable-next-line @typescript-eslint/camelcase + render: ({ is_required }: { is_required: boolean }) => (is_required ? 'Yes' : 'No'), + }, + { + label: i18n.translate('xpack.ml.dataframe.analytics.create.analyticsTable.reasonColumn', { + defaultMessage: 'Reason', + }), + id: 'reason', + alignment: LEFT_ALIGNMENT, + isSortable: false, + }, +]; + +const checkboxDisabledCheck = (item: FieldSelectionItem) => + (item.is_included === false && !item.reason?.includes('in excludes list')) || + item.is_required === true; + +export const MemoizedAnalysisFieldsTable: FC<{ + excludes: string[]; + loadingItems: boolean; + setFormState: any; + tableItems: FieldSelectionItem[]; +}> = memo( + ({ excludes, loadingItems, setFormState, tableItems }) => { + const [sortableProperties, setSortableProperties] = useState(); + const [currentSelection, setCurrentSelection] = useState([]); + + useEffect(() => { + if (excludes.length > 0) { + setCurrentSelection(excludes); + } + }, []); + + // Only set form state on unmount to prevent re-renders due to props changing if exludes was updated on each selection + useEffect(() => { + return () => { + setFormState({ excludes: currentSelection }); + }; + }, [currentSelection]); + + useEffect(() => { + let sortablePropertyItems = []; + const defaultSortProperty = 'name'; + + sortablePropertyItems = [ + { + name: 'name', + getValue: (item: any) => item.name.toLowerCase(), + isAscending: true, + }, + { + name: 'is_included', + getValue: (item: any) => item.is_included, + isAscending: true, + }, + { + name: 'is_required', + getValue: (item: any) => item.is_required, + isAscending: true, + }, + ]; + const sortableProps = new SortableProperties(sortablePropertyItems, defaultSortProperty); + + setSortableProperties(sortableProps); + }, []); + + const filters = [ + { + type: 'field_value_selection', + field: 'is_included', + name: i18n.translate('xpack.ml.dataframe.analytics.create.excludedFilterLabel', { + defaultMessage: 'Is included', + }), + multiSelect: false, + options: [ + { + value: true, + view: ( + + {i18n.translate('xpack.ml.dataframe.analytics.create.isIncludedOption', { + defaultMessage: 'Yes', + })} + + ), + }, + { + value: false, + view: ( + + {i18n.translate('xpack.ml.dataframe.analytics.create.isNotIncludedOption', { + defaultMessage: 'No', + })} + + ), + }, + ], + }, + ]; + + return ( + + + + + {tableItems.length === 0 && ( + + + + )} + {tableItems.length > 0 && ( + + { + setCurrentSelection(selection); + }} + selectedIds={currentSelection} + singleSelection={false} + sortableProperties={sortableProperties} + tableItemId={'name'} + /> + + )} + + + ); + }, + (prevProps, nextProps) => prevProps.tableItems.length === nextProps.tableItems.length +); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step.tsx new file mode 100644 index 0000000000000..220910535aafe --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step.tsx @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC } from 'react'; +import { EuiForm } from '@elastic/eui'; + +import { CreateAnalyticsStepProps } from '../../../analytics_management/hooks/use_create_analytics_form'; +import { ConfigurationStepDetails } from './configuration_step_details'; +import { ConfigurationStepForm } from './configuration_step_form'; +import { ANALYTICS_STEPS } from '../../page'; + +export const ConfigurationStep: FC = ({ + actions, + state, + setCurrentStep, + step, + stepActivated, +}) => { + return ( + + {step === ANALYTICS_STEPS.CONFIGURATION && ( + + )} + {step !== ANALYTICS_STEPS.CONFIGURATION && stepActivated === true && ( + + )} + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_details.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_details.tsx new file mode 100644 index 0000000000000..6603af9aa302e --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_details.tsx @@ -0,0 +1,115 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, Fragment } from 'react'; +import { i18n } from '@kbn/i18n'; +import { + EuiButtonEmpty, + EuiDescriptionList, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, +} from '@elastic/eui'; +import { + State, + UNSET_CONFIG_ITEM, +} from '../../../analytics_management/hooks/use_create_analytics_form/state'; +import { ANALYSIS_CONFIG_TYPE } from '../../../../common/analytics'; +import { useMlContext } from '../../../../../contexts/ml'; +import { ANALYTICS_STEPS } from '../../page'; + +interface Props { + setCurrentStep: React.Dispatch>; + state: State; +} + +export const ConfigurationStepDetails: FC = ({ setCurrentStep, state }) => { + const mlContext = useMlContext(); + const { currentIndexPattern } = mlContext; + const { form, isJobCreated } = state; + const { dependentVariable, excludes, jobConfigQueryString, jobType, trainingPercent } = form; + + const isJobTypeWithDepVar = + jobType === ANALYSIS_CONFIG_TYPE.REGRESSION || jobType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION; + + const detailsFirstCol = [ + { + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.sourceIndex', { + defaultMessage: 'Source index', + }), + description: currentIndexPattern.title || UNSET_CONFIG_ITEM, + }, + { + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.Query', { + defaultMessage: 'Query', + }), + description: jobConfigQueryString || UNSET_CONFIG_ITEM, + }, + ]; + + const detailsSecondCol = [ + { + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.jobType', { + defaultMessage: 'Job type', + }), + description: jobType! as string, + }, + ]; + + const detailsThirdCol = [ + { + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.excludedFields', { + defaultMessage: 'Excluded fields', + }), + description: excludes.length > 0 ? excludes.join(', ') : UNSET_CONFIG_ITEM, + }, + ]; + + if (isJobTypeWithDepVar) { + detailsSecondCol.push({ + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.trainingPercent', { + defaultMessage: 'Training percent', + }), + description: `${trainingPercent}`, + }); + detailsThirdCol.unshift({ + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.dependentVariable', { + defaultMessage: 'Dependent variable', + }), + description: dependentVariable, + }); + } + + return ( + + + + + + + + + + + + + + {!isJobCreated && ( + { + setCurrentStep(ANALYTICS_STEPS.CONFIGURATION); + }} + > + {i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.editButtonText', { + defaultMessage: 'Edit', + })} + + )} + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx new file mode 100644 index 0000000000000..9446dfd4ed525 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx @@ -0,0 +1,449 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, Fragment, useEffect, useRef } from 'react'; +import { EuiBadge, EuiComboBox, EuiFormRow, EuiRange, EuiSpacer, EuiText } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { debounce } from 'lodash'; + +import { newJobCapsService } from '../../../../../services/new_job_capabilities_service'; +import { useMlContext } from '../../../../../contexts/ml'; + +import { + DfAnalyticsExplainResponse, + FieldSelectionItem, + ANALYSIS_CONFIG_TYPE, + TRAINING_PERCENT_MIN, + TRAINING_PERCENT_MAX, +} from '../../../../common/analytics'; +import { CreateAnalyticsStepProps } from '../../../analytics_management/hooks/use_create_analytics_form'; +import { Messages } from '../../../analytics_management/components/create_analytics_form/messages'; +import { + DEFAULT_MODEL_MEMORY_LIMIT, + getJobConfigFromFormState, + State, +} from '../../../analytics_management/hooks/use_create_analytics_form/state'; +import { shouldAddAsDepVarOption } from '../../../analytics_management/components/create_analytics_form/form_options_validation'; +import { ml } from '../../../../../services/ml_api_service'; +import { getToastNotifications } from '../../../../../util/dependency_cache'; + +import { ANALYTICS_STEPS } from '../../page'; +import { ContinueButton } from '../continue_button'; +import { JobType } from './job_type'; +import { SupportedFieldsMessage } from './supported_fields_message'; +import { MemoizedAnalysisFieldsTable } from './analysis_fields_table'; +import { DataGrid } from '../../../../../components/data_grid'; +import { useIndexData } from '../../hooks'; +import { ExplorationQueryBar } from '../../../analytics_exploration/components/exploration_query_bar'; +import { useSavedSearch } from './use_saved_search'; + +const requiredFieldsErrorText = i18n.translate( + 'xpack.ml.dataframe.analytics.createWizard.requiredFieldsErrorMessage', + { + defaultMessage: 'At least one field must be included in the analysis.', + } +); + +export const ConfigurationStepForm: FC = ({ + actions, + state, + setCurrentStep, +}) => { + const mlContext = useMlContext(); + const { currentSavedSearch, currentIndexPattern } = mlContext; + const { savedSearchQuery, savedSearchQueryStr } = useSavedSearch(); + + const { initiateWizard, setEstimatedModelMemoryLimit, setFormState } = actions; + const { estimatedModelMemoryLimit, form, isJobCreated, requestMessages } = state; + const firstUpdate = useRef(true); + const { + dependentVariable, + dependentVariableFetchFail, + dependentVariableOptions, + excludes, + excludesTableItems, + fieldOptionsFetchFail, + jobConfigQuery, + jobConfigQueryString, + jobType, + loadingDepVarOptions, + loadingFieldOptions, + maxDistinctValuesError, + modelMemoryLimit, + previousJobType, + requiredFieldsError, + trainingPercent, + } = form; + + const setJobConfigQuery = ({ query, queryString }: { query: any; queryString: string }) => { + setFormState({ jobConfigQuery: query, jobConfigQueryString: queryString }); + }; + + const indexData = useIndexData( + currentIndexPattern, + savedSearchQuery !== undefined ? savedSearchQuery : jobConfigQuery + ); + + const indexPreviewProps = { + ...indexData, + dataTestSubj: 'mlAnalyticsCreationDataGrid', + toastNotifications: getToastNotifications(), + }; + + const isJobTypeWithDepVar = + jobType === ANALYSIS_CONFIG_TYPE.REGRESSION || jobType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION; + + const dependentVariableEmpty = isJobTypeWithDepVar && dependentVariable === ''; + + const isStepInvalid = + dependentVariableEmpty || + jobType === undefined || + maxDistinctValuesError !== undefined || + requiredFieldsError !== undefined; + + const loadDepVarOptions = async (formState: State['form']) => { + setFormState({ + loadingDepVarOptions: true, + maxDistinctValuesError: undefined, + }); + try { + if (currentIndexPattern !== undefined) { + const formStateUpdate: { + loadingDepVarOptions: boolean; + dependentVariableFetchFail: boolean; + dependentVariableOptions: State['form']['dependentVariableOptions']; + dependentVariable?: State['form']['dependentVariable']; + } = { + loadingDepVarOptions: false, + dependentVariableFetchFail: false, + dependentVariableOptions: [] as State['form']['dependentVariableOptions'], + }; + + // Get fields and filter for supported types for job type + const { fields } = newJobCapsService; + + let resetDependentVariable = true; + for (const field of fields) { + if (shouldAddAsDepVarOption(field, jobType)) { + formStateUpdate.dependentVariableOptions.push({ + label: field.id, + }); + + if (formState.dependentVariable === field.id) { + resetDependentVariable = false; + } + } + } + + if (resetDependentVariable) { + formStateUpdate.dependentVariable = ''; + } + + setFormState(formStateUpdate); + } + } catch (e) { + setFormState({ loadingDepVarOptions: false, dependentVariableFetchFail: true }); + } + }; + + const debouncedGetExplainData = debounce(async () => { + const jobTypeChanged = previousJobType !== jobType; + const shouldUpdateModelMemoryLimit = !firstUpdate.current || !modelMemoryLimit; + const shouldUpdateEstimatedMml = + !firstUpdate.current || !modelMemoryLimit || estimatedModelMemoryLimit === ''; + + if (firstUpdate.current) { + firstUpdate.current = false; + } + // Reset if jobType changes (jobType requires dependent_variable to be set - + // which won't be the case if switching from outlier detection) + if (jobTypeChanged) { + setFormState({ + loadingFieldOptions: true, + }); + } + + try { + const jobConfig = getJobConfigFromFormState(form); + delete jobConfig.dest; + delete jobConfig.model_memory_limit; + const resp: DfAnalyticsExplainResponse = await ml.dataFrameAnalytics.explainDataFrameAnalytics( + jobConfig + ); + const expectedMemoryWithoutDisk = resp.memory_estimation?.expected_memory_without_disk; + + if (shouldUpdateEstimatedMml) { + setEstimatedModelMemoryLimit(expectedMemoryWithoutDisk); + } + + const fieldSelection: FieldSelectionItem[] | undefined = resp.field_selection; + + let hasRequiredFields = false; + if (fieldSelection) { + for (let i = 0; i < fieldSelection.length; i++) { + const field = fieldSelection[i]; + if (field.is_included === true && field.is_required === false) { + hasRequiredFields = true; + break; + } + } + } + + // If job type has changed load analysis field options again + if (jobTypeChanged) { + setFormState({ + ...(shouldUpdateModelMemoryLimit ? { modelMemoryLimit: expectedMemoryWithoutDisk } : {}), + excludesTableItems: fieldSelection ? fieldSelection : [], + loadingFieldOptions: false, + fieldOptionsFetchFail: false, + maxDistinctValuesError: undefined, + requiredFieldsError: !hasRequiredFields ? requiredFieldsErrorText : undefined, + }); + } else { + setFormState({ + ...(shouldUpdateModelMemoryLimit ? { modelMemoryLimit: expectedMemoryWithoutDisk } : {}), + requiredFieldsError: !hasRequiredFields ? requiredFieldsErrorText : undefined, + }); + } + } catch (e) { + let errorMessage; + if ( + jobType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION && + e.body && + e.body.message !== undefined && + e.body.message.includes('status_exception') && + (e.body.message.includes('must have at most') || + e.body.message.includes('must have at least')) + ) { + errorMessage = e.body.message; + } + const fallbackModelMemoryLimit = + jobType !== undefined + ? DEFAULT_MODEL_MEMORY_LIMIT[jobType] + : DEFAULT_MODEL_MEMORY_LIMIT.outlier_detection; + setEstimatedModelMemoryLimit(fallbackModelMemoryLimit); + setFormState({ + fieldOptionsFetchFail: true, + maxDistinctValuesError: errorMessage, + loadingFieldOptions: false, + ...(shouldUpdateModelMemoryLimit ? { modelMemoryLimit: fallbackModelMemoryLimit } : {}), + }); + } + }, 300); + + useEffect(() => { + initiateWizard(); + }, []); + + useEffect(() => { + setFormState({ sourceIndex: currentIndexPattern.title }); + }, []); + + useEffect(() => { + if (savedSearchQueryStr !== undefined) { + setFormState({ jobConfigQuery: savedSearchQuery, jobConfigQueryString: savedSearchQueryStr }); + } + }, [JSON.stringify(savedSearchQuery), savedSearchQueryStr]); + + useEffect(() => { + if (isJobTypeWithDepVar) { + loadDepVarOptions(form); + } + }, [jobType]); + + useEffect(() => { + const hasBasicRequiredFields = jobType !== undefined; + + const hasRequiredAnalysisFields = + (isJobTypeWithDepVar && dependentVariable !== '') || + jobType === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION; + + if (hasBasicRequiredFields && hasRequiredAnalysisFields) { + debouncedGetExplainData(); + } + + return () => { + debouncedGetExplainData.cancel(); + }; + }, [jobType, dependentVariable, trainingPercent, JSON.stringify(excludes), jobConfigQueryString]); + + return ( + + + + + {savedSearchQuery === undefined && ( + + + + )} + + {savedSearchQuery !== undefined && ( + + {i18n.translate('xpack.ml.dataframe.analytics.create.savedSearchLabel', { + defaultMessage: 'Saved search', + })} + + )} + + {savedSearchQuery !== undefined + ? currentSavedSearch?.attributes.title + : currentIndexPattern.title} + + + } + fullWidth + > + + + {isJobTypeWithDepVar && ( + + + {i18n.translate( + 'xpack.ml.dataframe.analytics.create.dependentVariableOptionsFetchError', + { + defaultMessage: + 'There was a problem fetching fields. Please refresh the page and try again.', + } + )} + , + ] + : []), + ...(fieldOptionsFetchFail === true && maxDistinctValuesError !== undefined + ? [ + + {i18n.translate( + 'xpack.ml.dataframe.analytics.create.dependentVariableMaxDistictValuesError', + { + defaultMessage: 'Invalid. {message}', + values: { message: maxDistinctValuesError }, + } + )} + , + ] + : []), + ]} + > + + setFormState({ + dependentVariable: selectedOptions[0].label || '', + }) + } + isClearable={false} + isInvalid={dependentVariable === ''} + data-test-subj="mlAnalyticsCreateJobWizardDependentVariableSelect" + /> + + + )} + + + + + {isJobTypeWithDepVar && ( + + setFormState({ trainingPercent: +e.target.value })} + data-test-subj="mlAnalyticsCreateJobWizardTrainingPercentSlider" + /> + + )} + + { + setCurrentStep(ANALYTICS_STEPS.ADVANCED); + }} + /> + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/index.ts new file mode 100644 index 0000000000000..ba67a6f080d45 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { ConfigurationStep } from './configuration_step'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/job_type.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/job_type.tsx new file mode 100644 index 0000000000000..f31c9cd28f65a --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/job_type.tsx @@ -0,0 +1,83 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { Fragment, FC } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { EuiFormRow, EuiSelect } from '@elastic/eui'; +import { ANALYSIS_CONFIG_TYPE } from '../../../../common'; + +import { AnalyticsJobType } from '../../../analytics_management/hooks/use_create_analytics_form/state'; + +interface Props { + type: AnalyticsJobType; + setFormState: React.Dispatch>; +} + +export const JobType: FC = ({ type, setFormState }) => { + const outlierHelpText = i18n.translate( + 'xpack.ml.dataframe.analytics.create.outlierDetectionHelpText', + { + defaultMessage: + 'Outlier detection jobs require a source index that is mapped as a table-like data structure and analyze only numeric and boolean fields. Use the advanced editor to add custom options to the configuration.', + } + ); + + const regressionHelpText = i18n.translate( + 'xpack.ml.dataframe.analytics.create.outlierRegressionHelpText', + { + defaultMessage: + 'Regression jobs analyze only numeric fields. Use the advanced editor to apply custom options, such as the prediction field name.', + } + ); + + const classificationHelpText = i18n.translate( + 'xpack.ml.dataframe.analytics.create.classificationHelpText', + { + defaultMessage: + 'Classification jobs require a source index that is mapped as a table-like data structure and support fields that are numeric, boolean, text, keyword, or ip. Use the advanced editor to apply custom options, such as the prediction field name.', + } + ); + + const helpText = { + [ANALYSIS_CONFIG_TYPE.REGRESSION]: regressionHelpText, + [ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION]: outlierHelpText, + [ANALYSIS_CONFIG_TYPE.CLASSIFICATION]: classificationHelpText, + }; + + return ( + + + ({ + value: jobType, + text: jobType.replace(/_/g, ' '), + 'data-test-subj': `mlAnalyticsCreation-${jobType}-option`, + }))} + value={type} + hasNoInitialSelection={true} + onChange={(e) => { + const value = e.target.value as AnalyticsJobType; + setFormState({ + previousJobType: type, + jobType: value, + excludes: [], + requiredFieldsError: undefined, + }); + }} + data-test-subj="mlAnalyticsCreateJobWizardJobTypeSelect" + /> + + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/supported_fields_message.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/supported_fields_message.tsx new file mode 100644 index 0000000000000..fe13cc1d6edfc --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/supported_fields_message.tsx @@ -0,0 +1,120 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, Fragment, useState, useEffect } from 'react'; +import { EuiSpacer, EuiText } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; + +import { AnalyticsJobType } from '../../../analytics_management/hooks/use_create_analytics_form/state'; +import { ANALYSIS_CONFIG_TYPE } from '../../../../common/analytics'; +import { Field, EVENT_RATE_FIELD_ID } from '../../../../../../../common/types/fields'; +import { BASIC_NUMERICAL_TYPES, EXTENDED_NUMERICAL_TYPES } from '../../../../common/fields'; +import { + OMIT_FIELDS, + CATEGORICAL_TYPES, +} from '../../../analytics_management/components/create_analytics_form/form_options_validation'; +import { ES_FIELD_TYPES } from '../../../../../../../../../../src/plugins/data/public'; +import { newJobCapsService } from '../../../../../services/new_job_capabilities_service'; + +const containsClassificationFieldsCb = ({ name, type }: Field) => + !OMIT_FIELDS.includes(name) && + name !== EVENT_RATE_FIELD_ID && + (BASIC_NUMERICAL_TYPES.has(type) || + CATEGORICAL_TYPES.has(type) || + type === ES_FIELD_TYPES.BOOLEAN); + +const containsRegressionFieldsCb = ({ name, type }: Field) => + !OMIT_FIELDS.includes(name) && + name !== EVENT_RATE_FIELD_ID && + (BASIC_NUMERICAL_TYPES.has(type) || EXTENDED_NUMERICAL_TYPES.has(type)); + +const containsOutlierFieldsCb = ({ name, type }: Field) => + !OMIT_FIELDS.includes(name) && name !== EVENT_RATE_FIELD_ID && BASIC_NUMERICAL_TYPES.has(type); + +const callbacks: Record boolean> = { + [ANALYSIS_CONFIG_TYPE.CLASSIFICATION]: containsClassificationFieldsCb, + [ANALYSIS_CONFIG_TYPE.REGRESSION]: containsRegressionFieldsCb, + [ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION]: containsOutlierFieldsCb, +}; + +const messages: Record = { + [ANALYSIS_CONFIG_TYPE.CLASSIFICATION]: ( + + ), + [ANALYSIS_CONFIG_TYPE.REGRESSION]: ( + + ), + [ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION]: ( + + ), +}; + +interface Props { + jobType: AnalyticsJobType; +} + +export const SupportedFieldsMessage: FC = ({ jobType }) => { + const [sourceIndexContainsSupportedFields, setSourceIndexContainsSupportedFields] = useState< + boolean + >(true); + const [sourceIndexFieldsCheckFailed, setSourceIndexFieldsCheckFailed] = useState(false); + const { fields } = newJobCapsService; + + // Find out if index pattern contains supported fields for job type. Provides a hint in the form + // that job may not run correctly if no supported fields are found. + const validateFields = () => { + if (fields && jobType !== undefined) { + try { + const containsSupportedFields: boolean = fields.some(callbacks[jobType]); + + setSourceIndexContainsSupportedFields(containsSupportedFields); + setSourceIndexFieldsCheckFailed(false); + } catch (e) { + setSourceIndexFieldsCheckFailed(true); + } + } + }; + + useEffect(() => { + if (jobType !== undefined) { + setSourceIndexContainsSupportedFields(true); + setSourceIndexFieldsCheckFailed(false); + validateFields(); + } + }, [jobType]); + + if (sourceIndexContainsSupportedFields === true) return null; + + if (sourceIndexFieldsCheckFailed === true) { + return ( + + + + + ); + } + + return ( + + + {jobType !== undefined && messages[jobType]} + + + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/use_saved_search.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/use_saved_search.ts new file mode 100644 index 0000000000000..856358538b26f --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/use_saved_search.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { useState, useEffect } from 'react'; +import { useMlContext } from '../../../../../contexts/ml'; +import { esQuery, esKuery } from '../../../../../../../../../../src/plugins/data/public'; +import { SEARCH_QUERY_LANGUAGE } from '../../../../../../../common/constants/search'; +import { getQueryFromSavedSearch } from '../../../../../util/index_utils'; + +export function useSavedSearch() { + const [savedSearchQuery, setSavedSearchQuery] = useState(undefined); + const [savedSearchQueryStr, setSavedSearchQueryStr] = useState(undefined); + + const mlContext = useMlContext(); + const { currentSavedSearch, currentIndexPattern, kibanaConfig } = mlContext; + + const getQueryData = () => { + let qry; + let qryString; + + if (currentSavedSearch !== null) { + const { query } = getQueryFromSavedSearch(currentSavedSearch); + const queryLanguage = query.language as SEARCH_QUERY_LANGUAGE; + qryString = query.query; + + if (queryLanguage === SEARCH_QUERY_LANGUAGE.KUERY) { + const ast = esKuery.fromKueryExpression(qryString); + qry = esKuery.toElasticsearchQuery(ast, currentIndexPattern); + } else { + qry = esQuery.luceneStringToDsl(qryString); + esQuery.decorateQuery(qry, kibanaConfig.get('query:queryString:options')); + } + + setSavedSearchQuery(qry); + setSavedSearchQueryStr(qryString); + } + }; + + useEffect(() => { + getQueryData(); + }, []); + + return { + savedSearchQuery, + savedSearchQueryStr, + }; +} diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/continue_button.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/continue_button.tsx new file mode 100644 index 0000000000000..6e95a0a246573 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/continue_button.tsx @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC } from 'react'; +import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +const continueButtonText = i18n.translate( + 'xpack.ml.dataframe.analytics.creation.continueButtonText', + { + defaultMessage: 'Continue', + } +); + +export const ContinueButton: FC<{ isDisabled: boolean; onClick: any }> = ({ + isDisabled, + onClick, +}) => ( + + + + {continueButtonText} + + + +); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/create_step.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/create_step.tsx new file mode 100644 index 0000000000000..2dda5f5d819b7 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/create_step.tsx @@ -0,0 +1,95 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, Fragment, useState } from 'react'; +import { + EuiButton, + EuiCheckbox, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiSpacer, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { CreateAnalyticsFormProps } from '../../../analytics_management/hooks/use_create_analytics_form'; +import { Messages } from '../../../analytics_management/components/create_analytics_form/messages'; +import { ANALYTICS_STEPS } from '../../page'; +import { BackToListPanel } from '../back_to_list_panel'; + +interface Props extends CreateAnalyticsFormProps { + step: ANALYTICS_STEPS; +} + +export const CreateStep: FC = ({ actions, state, step }) => { + const { createAnalyticsJob, startAnalyticsJob } = actions; + const { + isAdvancedEditorValidJson, + isJobCreated, + isJobStarted, + isModalButtonDisabled, + isValid, + requestMessages, + } = state; + + const [checked, setChecked] = useState(true); + + if (step !== ANALYTICS_STEPS.CREATE) return null; + + const handleCreation = async () => { + await createAnalyticsJob(); + + if (checked) { + startAnalyticsJob(); + } + }; + + return ( + + {!isJobCreated && !isJobStarted && ( + + + + setChecked(e.target.checked)} + /> + + + + + {i18n.translate('xpack.ml.dataframe.analytics.create.wizardCreateButton', { + defaultMessage: 'Create', + })} + + + + )} + + + {isJobCreated === true && } + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/index.ts new file mode 100644 index 0000000000000..01c8e4bff934d --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { CreateStep } from './create_step'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step.tsx new file mode 100644 index 0000000000000..a40813ed2fc3e --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC } from 'react'; +import { EuiForm } from '@elastic/eui'; + +import { CreateAnalyticsStepProps } from '../../../analytics_management/hooks/use_create_analytics_form'; +import { DetailsStepDetails } from './details_step_details'; +import { DetailsStepForm } from './details_step_form'; +import { ANALYTICS_STEPS } from '../../page'; + +export const DetailsStep: FC = ({ + actions, + state, + setCurrentStep, + step, + stepActivated, +}) => { + return ( + + {step === ANALYTICS_STEPS.DETAILS && ( + + )} + {step !== ANALYTICS_STEPS.DETAILS && stepActivated === true && ( + + )} + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_details.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_details.tsx new file mode 100644 index 0000000000000..a4d86b48006e8 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_details.tsx @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, Fragment } from 'react'; +import { i18n } from '@kbn/i18n'; +import { + EuiButtonEmpty, + EuiDescriptionList, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, +} from '@elastic/eui'; +import { State } from '../../../analytics_management/hooks/use_create_analytics_form/state'; +import { ANALYTICS_STEPS } from '../../page'; + +export interface ListItems { + title: string; + description: string | JSX.Element; +} + +export const DetailsStepDetails: FC<{ setCurrentStep: any; state: State }> = ({ + setCurrentStep, + state, +}) => { + const { form, isJobCreated } = state; + const { description, jobId, destinationIndex } = form; + + const detailsFirstCol: ListItems[] = [ + { + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.jobId', { + defaultMessage: 'Job ID', + }), + description: jobId, + }, + ]; + + const detailsSecondCol: ListItems[] = [ + { + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.jobDescription', { + defaultMessage: 'Job description', + }), + description, + }, + ]; + + const detailsThirdCol: ListItems[] = [ + { + title: i18n.translate('xpack.ml.dataframe.analytics.create.configDetails.destIndex', { + defaultMessage: 'Destination index', + }), + description: destinationIndex || '', + }, + ]; + + return ( + + + + + + + + + + + + + + {!isJobCreated && ( + { + setCurrentStep(ANALYTICS_STEPS.DETAILS); + }} + > + {i18n.translate('xpack.ml.dataframe.analytics.create.detailsDetails.editButtonText', { + defaultMessage: 'Edit', + })} + + )} + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_form.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_form.tsx new file mode 100644 index 0000000000000..67f8472e7ad14 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_form.tsx @@ -0,0 +1,221 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, Fragment, useRef } from 'react'; +import { EuiFieldText, EuiFormRow, EuiLink, EuiSpacer, EuiSwitch, EuiTextArea } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { useMlKibana } from '../../../../../contexts/kibana'; +import { CreateAnalyticsStepProps } from '../../../analytics_management/hooks/use_create_analytics_form'; +import { JOB_ID_MAX_LENGTH } from '../../../../../../../common/constants/validation'; +import { ContinueButton } from '../continue_button'; +import { ANALYTICS_STEPS } from '../../page'; + +export const DetailsStepForm: FC = ({ + actions, + state, + setCurrentStep, +}) => { + const { + services: { docLinks }, + } = useMlKibana(); + const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = docLinks; + + const { setFormState } = actions; + const { form, isJobCreated } = state; + const { + createIndexPattern, + description, + destinationIndex, + destinationIndexNameEmpty, + destinationIndexNameExists, + destinationIndexNameValid, + destinationIndexPatternTitleExists, + jobId, + jobIdEmpty, + jobIdExists, + jobIdInvalidMaxLength, + jobIdValid, + } = form; + const forceInput = useRef(null); + + const isStepInvalid = + jobIdEmpty === true || + jobIdExists === true || + jobIdValid === false || + destinationIndexNameEmpty === true || + destinationIndexNameValid === false || + (destinationIndexPatternTitleExists === true && createIndexPattern === true); + + return ( + + + { + if (input) { + forceInput.current = input; + } + }} + disabled={isJobCreated} + placeholder={i18n.translate('xpack.ml.dataframe.analytics.create.jobIdPlaceholder', { + defaultMessage: 'Job ID', + })} + value={jobId} + onChange={(e) => setFormState({ jobId: e.target.value })} + aria-label={i18n.translate('xpack.ml.dataframe.analytics.create.jobIdInputAriaLabel', { + defaultMessage: 'Choose a unique analytics job ID.', + })} + isInvalid={(!jobIdEmpty && !jobIdValid) || jobIdExists || jobIdEmpty} + data-test-subj="mlAnalyticsCreateJobFlyoutJobIdInput" + /> + + + { + const value = e.target.value; + setFormState({ description: value }); + }} + data-test-subj="mlDFAnalyticsJobCreationJobDescription" + /> + + + {i18n.translate('xpack.ml.dataframe.analytics.create.destinationIndexInvalidError', { + defaultMessage: 'Invalid destination index name.', + })} +
+ + {i18n.translate( + 'xpack.ml.dataframe.stepDetailsForm.destinationIndexInvalidErrorLink', + { + defaultMessage: 'Learn more about index name limitations.', + } + )} + +
, + ] + } + > + setFormState({ destinationIndex: e.target.value })} + aria-label={i18n.translate( + 'xpack.ml.dataframe.analytics.create.destinationIndexInputAriaLabel', + { + defaultMessage: 'Choose a unique destination index name.', + } + )} + isInvalid={!destinationIndexNameEmpty && !destinationIndexNameValid} + data-test-subj="mlAnalyticsCreateJobFlyoutDestinationIndexInput" + /> + + + setFormState({ createIndexPattern: !createIndexPattern })} + data-test-subj="mlAnalyticsCreateJobWizardCreateIndexPatternSwitch" + /> + + + { + setCurrentStep(ANALYTICS_STEPS.CREATE); + }} + /> + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/index.ts new file mode 100644 index 0000000000000..6cadd87d97e27 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { DetailsStep } from './details_step'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/index.ts new file mode 100644 index 0000000000000..efd7c0634bed4 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { ConfigurationStep } from './configuration_step/index'; +export { AdvancedStep } from './advanced_step/index'; +export { DetailsStep } from './details_step/index'; +export { CreateStep } from './create_step/index'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/index.ts new file mode 100644 index 0000000000000..5199fa1b6e4c6 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { useIndexData } from './use_index_data'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts new file mode 100644 index 0000000000000..e8f25584201e3 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { useEffect } from 'react'; + +import { IndexPattern } from '../../../../../../../../../src/plugins/data/public'; +import { + getDataGridSchemaFromKibanaFieldType, + getFieldsFromKibanaIndexPattern, + useDataGrid, + useRenderCellValue, + EsSorting, + SearchResponse7, + UseIndexDataReturnType, +} from '../../../../components/data_grid'; +import { getErrorMessage } from '../../../../../../common/util/errors'; +import { INDEX_STATUS } from '../../../common/analytics'; +import { ml } from '../../../../services/ml_api_service'; + +type IndexSearchResponse = SearchResponse7; + +export const useIndexData = (indexPattern: IndexPattern, query: any): UseIndexDataReturnType => { + const indexPatternFields = getFieldsFromKibanaIndexPattern(indexPattern); + + // EuiDataGrid State + const columns = [ + ...indexPatternFields.map((id) => { + const field = indexPattern.fields.getByName(id); + const schema = getDataGridSchemaFromKibanaFieldType(field); + return { id, schema }; + }), + ]; + + const dataGrid = useDataGrid(columns); + + const { + pagination, + resetPagination, + setErrorMessage, + setRowCount, + setStatus, + setTableItems, + sortingColumns, + tableItems, + } = dataGrid; + + useEffect(() => { + resetPagination(); + // custom comparison + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [JSON.stringify(query)]); + + const getIndexData = async function () { + setErrorMessage(''); + setStatus(INDEX_STATUS.LOADING); + + const sort: EsSorting = sortingColumns.reduce((s, column) => { + s[column.id] = { order: column.direction }; + return s; + }, {} as EsSorting); + + const esSearchRequest = { + index: indexPattern.title, + body: { + // Instead of using the default query (`*`), fall back to a more efficient `match_all` query. + query, // isDefaultQuery(query) ? matchAllQuery : query, + from: pagination.pageIndex * pagination.pageSize, + size: pagination.pageSize, + ...(Object.keys(sort).length > 0 ? { sort } : {}), + }, + }; + + try { + const resp: IndexSearchResponse = await ml.esSearch(esSearchRequest); + + const docs = resp.hits.hits.map((d) => d._source); + + setRowCount(resp.hits.total.value); + setTableItems(docs); + setStatus(INDEX_STATUS.LOADED); + } catch (e) { + setErrorMessage(getErrorMessage(e)); + setStatus(INDEX_STATUS.ERROR); + } + }; + + useEffect(() => { + getIndexData(); + // custom comparison + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [indexPattern.title, JSON.stringify([query, pagination, sortingColumns])]); + + const renderCellValue = useRenderCellValue(indexPattern, pagination, tableItems); + + return { + ...dataGrid, + columns, + renderCellValue, + }; +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/index.ts new file mode 100644 index 0000000000000..7e2d651439ae3 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { Page } from './page'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/page.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/page.tsx new file mode 100644 index 0000000000000..def862b859162 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/page.tsx @@ -0,0 +1,191 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, useEffect, useState } from 'react'; +import { + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiPage, + EuiPageBody, + EuiPageContent, + EuiSpacer, + EuiSteps, + EuiStepStatus, + EuiText, + EuiTitle, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { useMlContext } from '../../../contexts/ml'; +import { newJobCapsService } from '../../../services/new_job_capabilities_service'; +import { useCreateAnalyticsForm } from '../analytics_management/hooks/use_create_analytics_form'; +import { CreateAnalyticsAdvancedEditor } from '../analytics_management/components/create_analytics_advanced_editor'; +import { AdvancedStep, ConfigurationStep, CreateStep, DetailsStep } from './components'; + +export enum ANALYTICS_STEPS { + CONFIGURATION, + ADVANCED, + DETAILS, + CREATE, +} + +export const Page: FC = () => { + const [currentStep, setCurrentStep] = useState(ANALYTICS_STEPS.CONFIGURATION); + const [activatedSteps, setActivatedSteps] = useState([true, false, false, false]); + + const mlContext = useMlContext(); + const { currentIndexPattern } = mlContext; + + const createAnalyticsForm = useCreateAnalyticsForm(); + const { isAdvancedEditorEnabled } = createAnalyticsForm.state; + const { jobType } = createAnalyticsForm.state.form; + const { switchToAdvancedEditor } = createAnalyticsForm.actions; + + useEffect(() => { + if (activatedSteps[currentStep] === false) { + activatedSteps.splice(currentStep, 1, true); + setActivatedSteps(activatedSteps); + } + }, [currentStep]); + + useEffect(() => { + if (currentIndexPattern) { + (async function () { + await newJobCapsService.initializeFromIndexPattern(currentIndexPattern, false, false); + })(); + } + }, []); + + const analyticsWizardSteps = [ + { + title: i18n.translate('xpack.ml.dataframe.analytics.creation.configurationStepTitle', { + defaultMessage: 'Configuration', + }), + children: ( + + ), + status: + currentStep >= ANALYTICS_STEPS.CONFIGURATION ? undefined : ('incomplete' as EuiStepStatus), + }, + { + title: i18n.translate('xpack.ml.dataframe.analytics.creation.advancedStepTitle', { + defaultMessage: 'Additional options', + }), + children: ( + + ), + status: currentStep >= ANALYTICS_STEPS.ADVANCED ? undefined : ('incomplete' as EuiStepStatus), + 'data-test-subj': 'mlAnalyticsCreateJobWizardAdvancedStep', + }, + { + title: i18n.translate('xpack.ml.dataframe.analytics.creation.detailsStepTitle', { + defaultMessage: 'Job details', + }), + children: ( + + ), + status: currentStep >= ANALYTICS_STEPS.DETAILS ? undefined : ('incomplete' as EuiStepStatus), + 'data-test-subj': 'mlAnalyticsCreateJobWizardDetailsStep', + }, + { + title: i18n.translate('xpack.ml.dataframe.analytics.creation.createStepTitle', { + defaultMessage: 'Create', + }), + children: , + status: currentStep >= ANALYTICS_STEPS.CREATE ? undefined : ('incomplete' as EuiStepStatus), + 'data-test-subj': 'mlAnalyticsCreateJobWizardCreateStep', + }, + ]; + + return ( + + + + + + + + +

+ +

+
+
+ +

+ +

+
+
+
+ {isAdvancedEditorEnabled === false && ( + + + + + {i18n.translate( + 'xpack.ml.dataframe.analytics.create.switchToJsonEditorSwitch', + { + defaultMessage: 'Switch to json editor', + } + )} + + + + + )} +
+ + {isAdvancedEditorEnabled === true && ( + + )} + {isAdvancedEditorEnabled === false && ( + + )} +
+
+
+ ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx index f95e6a93058ba..8c158c1ca14a0 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Dispatch, FC, SetStateAction, useState } from 'react'; +import React, { Dispatch, FC, SetStateAction, useEffect, useState } from 'react'; import { EuiCode, EuiInputPopover } from '@elastic/eui'; @@ -30,11 +30,15 @@ interface ErrorMessage { interface ExplorationQueryBarProps { indexPattern: IIndexPattern; setSearchQuery: Dispatch>; + includeQueryString?: boolean; + defaultQueryString?: string; } export const ExplorationQueryBar: FC = ({ indexPattern, setSearchQuery, + includeQueryString = false, + defaultQueryString, }) => { // The internal state of the input query bar updated on every key stroke. const [searchInput, setSearchInput] = useState({ @@ -44,20 +48,34 @@ export const ExplorationQueryBar: FC = ({ const [errorMessage, setErrorMessage] = useState(undefined); + useEffect(() => { + if (defaultQueryString !== undefined) { + setSearchInput({ query: defaultQueryString, language: SEARCH_QUERY_LANGUAGE.KUERY }); + } + }, []); + const searchChangeHandler = (query: Query) => setSearchInput(query); const searchSubmitHandler = (query: Query) => { try { switch (query.language) { case SEARCH_QUERY_LANGUAGE.KUERY: + const convertedKQuery = esKuery.toElasticsearchQuery( + esKuery.fromKueryExpression(query.query as string), + indexPattern + ); setSearchQuery( - esKuery.toElasticsearchQuery( - esKuery.fromKueryExpression(query.query as string), - indexPattern - ) + includeQueryString + ? { queryString: query.query, query: convertedKQuery } + : convertedKQuery ); return; case SEARCH_QUERY_LANGUAGE.LUCENE: - setSearchQuery(esQuery.luceneStringToDsl(query.query as string)); + const convertedLQuery = esQuery.luceneStringToDsl(query.query as string); + setSearchQuery( + includeQueryString + ? { queryString: query.query, query: convertedLQuery } + : convertedLQuery + ); return; } } catch (e) { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts index e391b90e6eb96..b8b5a16c84e85 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts @@ -19,7 +19,11 @@ import { import { SavedSearchQuery } from '../../../../../contexts/ml'; import { getIndexData, getIndexFields, DataFrameAnalyticsConfig } from '../../../../common'; -import { DEFAULT_RESULTS_FIELD, FEATURE_IMPORTANCE } from '../../../../common/constants'; +import { + DEFAULT_RESULTS_FIELD, + FEATURE_IMPORTANCE, + TOP_CLASSES, +} from '../../../../common/constants'; import { sortExplorationResultsFields, ML__ID_COPY } from '../../../../common/fields'; export const useExplorationResults = ( @@ -47,8 +51,9 @@ export const useExplorationResults = ( 25, // reduce default selected rows from 20 to 8 for performance reasons. 8, - // by default, hide feature-importance columns and the doc id copy - (d) => !d.includes(`.${FEATURE_IMPORTANCE}.`) && d !== ML__ID_COPY + // by default, hide feature-importance and top-classes columns and the doc id copy + (d) => + !d.includes(`.${FEATURE_IMPORTANCE}.`) && !d.includes(`.${TOP_CLASSES}.`) && d !== ML__ID_COPY ); useEffect(() => { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx index 0154f92576c4a..58f8528236bb9 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx @@ -73,6 +73,7 @@ export const OutlierExploration: FC = React.memo(({ jobId }) = ); } + /* eslint-disable-next-line react-hooks/rules-of-hooks */ const colorRange = useColorRange( COLOR_RANGE.BLUE, COLOR_RANGE_SCALE.INFLUENCER, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/actions.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/actions.tsx index 72514c91ff58b..295a3988e1b58 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/actions.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/actions.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; -import { DeepReadonly } from '../../../../../../../common/types/common'; +// import { DeepReadonly } from '../../../../../../../common/types/common'; import { checkPermission, @@ -21,7 +21,7 @@ import { isClassificationAnalysis, } from '../../../../common/analytics'; import { CreateAnalyticsFormProps } from '../../hooks/use_create_analytics_form'; -import { CloneAction } from './action_clone'; +// import { CloneAction } from './action_clone'; import { getResultsUrl, isDataFrameAnalyticsRunning, DataFrameAnalyticsListRow } from './common'; import { stopAnalytics } from '../../services/analytics_service'; @@ -106,10 +106,10 @@ export const getActions = (createAnalyticsForm: CreateAnalyticsFormProps) => { return ; }, }, - { - render: (item: DeepReadonly) => { - return ; - }, - }, + // { + // render: (item: DeepReadonly) => { + // return ; + // }, + // }, ]; }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx index 4a99c042b108b..bb012a2190859 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/analytics_list.tsx @@ -53,6 +53,7 @@ import { CreateAnalyticsButton } from '../create_analytics_button'; import { CreateAnalyticsFormProps } from '../../hooks/use_create_analytics_form'; import { CreateAnalyticsFlyoutWrapper } from '../create_analytics_flyout_wrapper'; import { getSelectedJobIdFromUrl } from '../../../../../jobs/jobs_list/components/utils'; +import { SourceSelection } from '../source_selection'; function getItemIdToExpandedRowMap( itemIds: DataFrameAnalyticsId[], @@ -90,6 +91,7 @@ export const DataFrameAnalyticsList: FC = ({ createAnalyticsForm, }) => { const [isInitialized, setIsInitialized] = useState(false); + const [isSourceIndexModalVisible, setIsSourceIndexModalVisible] = useState(false); const [isLoading, setIsLoading] = useState(false); const [filterActive, setFilterActive] = useState(false); @@ -271,7 +273,7 @@ export const DataFrameAnalyticsList: FC = ({ !isManagementTable && createAnalyticsForm ? [ setIsSourceIndexModalVisible(true)} isDisabled={disabled} data-test-subj="mlAnalyticsCreateFirstButton" > @@ -287,6 +289,9 @@ export const DataFrameAnalyticsList: FC = ({ {!isManagementTable && createAnalyticsForm && ( )} + {isSourceIndexModalVisible === true && ( + setIsSourceIndexModalVisible(false)} /> + )} ); } @@ -402,7 +407,10 @@ export const DataFrameAnalyticsList: FC = ({
{!isManagementTable && createAnalyticsForm && ( - + )} @@ -435,6 +443,9 @@ export const DataFrameAnalyticsList: FC = ({ {!isManagementTable && createAnalyticsForm?.state.isModalVisible && ( )} + {isSourceIndexModalVisible === true && ( + setIsSourceIndexModalVisible(false)} /> + )} ); }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_advanced_editor/create_analytics_advanced_editor.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_advanced_editor/create_analytics_advanced_editor.tsx index 48eb95948bb12..17b905cab135b 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_advanced_editor/create_analytics_advanced_editor.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_advanced_editor/create_analytics_advanced_editor.tsx @@ -23,11 +23,14 @@ import { XJsonMode } from '../../../../../../../shared_imports'; const xJsonMode = new XJsonMode(); import { CreateAnalyticsFormProps } from '../../hooks/use_create_analytics_form'; +import { CreateStep } from '../../../analytics_creation/components/create_step'; +import { ANALYTICS_STEPS } from '../../../analytics_creation/page'; -export const CreateAnalyticsAdvancedEditor: FC = ({ actions, state }) => { +export const CreateAnalyticsAdvancedEditor: FC = (props) => { + const { actions, state } = props; const { setAdvancedEditorRawString, setFormState } = actions; - const { advancedEditorMessages, advancedEditorRawString, isJobCreated, requestMessages } = state; + const { advancedEditorMessages, advancedEditorRawString, isJobCreated } = state; const { createIndexPattern, @@ -56,120 +59,105 @@ export const CreateAnalyticsAdvancedEditor: FC = ({ ac return ( - {requestMessages.map((requestMessage, i) => ( + + { + if (input) { + forceInput.current = input; + } + }} + disabled={isJobCreated} + placeholder="analytics job ID" + value={jobId} + onChange={(e) => setFormState({ jobId: e.target.value })} + aria-label={i18n.translate( + 'xpack.ml.dataframe.analytics.create.advancedEditor.jobIdInputAriaLabel', + { + defaultMessage: 'Choose a unique analytics job ID.', + } + )} + isInvalid={(!jobIdEmpty && !jobIdValid) || jobIdExists} + /> + + + + + + + {advancedEditorMessages.map((advancedEditorMessage, i) => ( - {requestMessage.error !== undefined ?

{requestMessage.error}

: null} + {advancedEditorMessage.message !== '' && advancedEditorMessage.error !== undefined ? ( +

{advancedEditorMessage.error}

+ ) : null}
- +
))} {!isJobCreated && ( - - { - if (input) { - forceInput.current = input; - } - }} - disabled={isJobCreated} - placeholder="analytics job ID" - value={jobId} - onChange={(e) => setFormState({ jobId: e.target.value })} - aria-label={i18n.translate( - 'xpack.ml.dataframe.analytics.create.advancedEditor.jobIdInputAriaLabel', - { - defaultMessage: 'Choose a unique analytics job ID.', - } - )} - isInvalid={(!jobIdEmpty && !jobIdValid) || jobIdExists} - /> - - - - - - - {advancedEditorMessages.map((advancedEditorMessage, i) => ( - - - {advancedEditorMessage.message !== '' && - advancedEditorMessage.error !== undefined ? ( -

{advancedEditorMessage.error}

- ) : null} -
- -
- ))} = ({ ac
)} + +
); }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_button/_index.scss b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_button/_index.scss new file mode 100644 index 0000000000000..14ff9de7ded4d --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_button/_index.scss @@ -0,0 +1,4 @@ +.dataFrameAnalyticsCreateSearchDialog { + width: $euiSizeL * 30; + min-height: $euiSizeL * 25; +} diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_button/create_analytics_button.test.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_button/create_analytics_button.test.tsx index 10565fb4d7a93..8e9b09ef41fa8 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_button/create_analytics_button.test.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_button/create_analytics_button.test.tsx @@ -35,7 +35,9 @@ describe('Data Frame Analytics: ', () => { test('Minimal initialization', () => { const { getLastHookValue } = getMountedHook(); const props = getLastHookValue(); - const wrapper = mount(); + const wrapper = mount( + + ); expect(wrapper.find('EuiButton').text()).toBe('Create analytics job'); }); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_button/create_analytics_button.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_button/create_analytics_button.tsx index 952bd48468b0a..595a1cf73e189 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_button/create_analytics_button.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/create_analytics_button/create_analytics_button.tsx @@ -10,15 +10,26 @@ import { i18n } from '@kbn/i18n'; import { createPermissionFailureMessage } from '../../../../../capabilities/check_capabilities'; import { CreateAnalyticsFormProps } from '../../hooks/use_create_analytics_form'; -export const CreateAnalyticsButton: FC = (props) => { - const { disabled } = props.state; - const { openModal } = props.actions; +interface Props extends CreateAnalyticsFormProps { + setIsSourceIndexModalVisible: React.Dispatch>; +} + +export const CreateAnalyticsButton: FC = ({ + state, + actions, + setIsSourceIndexModalVisible, +}) => { + const { disabled } = state; + + const handleClick = () => { + setIsSourceIndexModalVisible(true); + }; const button = ( = ({ messages }) => { {messages.map((requestMessage, i) => ( void; +} + +export const SourceSelection: FC = ({ onClose }) => { + const { uiSettings, savedObjects } = useMlKibana().services; + + const onSearchSelected = (id: string, type: string) => { + window.location.href = `ml#/data_frame_analytics/new_job?${ + type === 'index-pattern' ? 'index' : 'savedSearchId' + }=${encodeURIComponent(id)}`; + }; + + return ( + <> + + + + + {' '} + /{' '} + + + + + 'search', + name: i18n.translate( + 'xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.search', + { + defaultMessage: 'Saved search', + } + ), + }, + { + type: 'index-pattern', + getIconForSavedObject: () => 'indexPatternApp', + name: i18n.translate( + 'xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.indexPattern', + { + defaultMessage: 'Index pattern', + } + ), + }, + ]} + fixedPageSize={fixedPageSize} + uiSettings={uiSettings} + savedObjects={savedObjects} + /> + + + + + ); +}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/actions.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/actions.ts index 66e4103f5bb41..c42e03b584a56 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/actions.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/actions.ts @@ -72,6 +72,7 @@ export interface ActionDispatchers { closeModal: () => void; createAnalyticsJob: () => void; openModal: () => Promise; + initiateWizard: () => Promise; resetAdvancedEditorMessages: () => void; setAdvancedEditorRawString: (payload: State['advancedEditorRawString']) => void; setFormState: (payload: Partial) => void; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/index.ts index e5e56c084f7b9..8ec415bc2abb4 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/index.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/index.ts @@ -5,4 +5,9 @@ */ export { DEFAULT_NUM_TOP_FEATURE_IMPORTANCE_VALUES } from './state'; -export { useCreateAnalyticsForm, CreateAnalyticsFormProps } from './use_create_analytics_form'; +export { + AnalyticsCreationStep, + useCreateAnalyticsForm, + CreateAnalyticsFormProps, + CreateAnalyticsStepProps, +} from './use_create_analytics_form'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts index 4ff7deab34f26..387ce89ee4120 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts @@ -11,6 +11,7 @@ import { mlNodesAvailable } from '../../../../../ml_nodes_check'; import { newJobCapsService } from '../../../../../services/new_job_capabilities_service'; import { + FieldSelectionItem, isClassificationAnalysis, isRegressionAnalysis, DataFrameAnalyticsId, @@ -26,7 +27,8 @@ export enum DEFAULT_MODEL_MEMORY_LIMIT { classification = '100mb', } -export const DEFAULT_NUM_TOP_FEATURE_IMPORTANCE_VALUES = 2; +export const DEFAULT_NUM_TOP_FEATURE_IMPORTANCE_VALUES = 0; +export const UNSET_CONFIG_ITEM = '--'; export type EsIndexName = string; export type DependentVariable = string; @@ -47,6 +49,7 @@ export interface State { advancedEditorMessages: FormMessage[]; advancedEditorRawString: string; form: { + computeFeatureInfluence: string; createIndexPattern: boolean; dependentVariable: DependentVariable; dependentVariableFetchFail: boolean; @@ -57,31 +60,47 @@ export interface State { destinationIndexNameEmpty: boolean; destinationIndexNameValid: boolean; destinationIndexPatternTitleExists: boolean; + eta: undefined | number; excludes: string[]; + excludesTableItems: FieldSelectionItem[]; excludesOptions: EuiComboBoxOptionOption[]; + featureBagFraction: undefined | number; + featureInfluenceThreshold: undefined | number; fieldOptionsFetchFail: boolean; + gamma: undefined | number; jobId: DataFrameAnalyticsId; jobIdExists: boolean; jobIdEmpty: boolean; jobIdInvalidMaxLength: boolean; jobIdValid: boolean; jobType: AnalyticsJobType; + jobConfigQuery: any; + jobConfigQueryString: string | undefined; + lambda: number | undefined; loadingDepVarOptions: boolean; loadingFieldOptions: boolean; maxDistinctValuesError: string | undefined; + maxTrees: undefined | number; + method: undefined | string; modelMemoryLimit: string | undefined; modelMemoryLimitUnitValid: boolean; modelMemoryLimitValidationResult: any; + nNeighbors: undefined | number; numTopFeatureImportanceValues: number | undefined; numTopFeatureImportanceValuesValid: boolean; + numTopClasses: number; + outlierFraction: undefined | number; + predictionFieldName: undefined | string; previousJobType: null | AnalyticsJobType; previousSourceIndex: EsIndexName | undefined; requiredFieldsError: string | undefined; + randomizeSeed: undefined | number; sourceIndex: EsIndexName; sourceIndexNameEmpty: boolean; sourceIndexNameValid: boolean; sourceIndexContainsNumericalFields: boolean; sourceIndexFieldsCheckFailed: boolean; + standardizationEnabled: undefined | string; trainingPercent: number; }; disabled: boolean; @@ -105,7 +124,8 @@ export const getInitialState = (): State => ({ advancedEditorMessages: [], advancedEditorRawString: '', form: { - createIndexPattern: false, + computeFeatureInfluence: 'true', + createIndexPattern: true, dependentVariable: '', dependentVariableFetchFail: false, dependentVariableOptions: [], @@ -115,8 +135,13 @@ export const getInitialState = (): State => ({ destinationIndexNameEmpty: true, destinationIndexNameValid: false, destinationIndexPatternTitleExists: false, + eta: undefined, excludes: [], + featureBagFraction: undefined, + featureInfluenceThreshold: undefined, fieldOptionsFetchFail: false, + gamma: undefined, + excludesTableItems: [], excludesOptions: [], jobId: '', jobIdExists: false, @@ -124,22 +149,33 @@ export const getInitialState = (): State => ({ jobIdInvalidMaxLength: false, jobIdValid: false, jobType: undefined, + jobConfigQuery: { match_all: {} }, + jobConfigQueryString: undefined, + lambda: undefined, loadingDepVarOptions: false, loadingFieldOptions: false, maxDistinctValuesError: undefined, + maxTrees: undefined, + method: undefined, modelMemoryLimit: undefined, modelMemoryLimitUnitValid: true, modelMemoryLimitValidationResult: null, + nNeighbors: undefined, numTopFeatureImportanceValues: DEFAULT_NUM_TOP_FEATURE_IMPORTANCE_VALUES, numTopFeatureImportanceValuesValid: true, + numTopClasses: 2, + outlierFraction: undefined, + predictionFieldName: undefined, previousJobType: null, previousSourceIndex: undefined, requiredFieldsError: undefined, + randomizeSeed: undefined, sourceIndex: '', sourceIndexNameEmpty: true, sourceIndexNameValid: false, sourceIndexContainsNumericalFields: true, sourceIndexFieldsCheckFailed: false, + standardizationEnabled: 'true', trainingPercent: 80, }, jobConfig: {}, @@ -222,6 +258,7 @@ export const getJobConfigFromFormState = ( index: formState.sourceIndex.includes(',') ? formState.sourceIndex.split(',').map((d) => d.trim()) : formState.sourceIndex, + query: formState.jobConfigQuery, }, dest: { index: formState.destinationIndex, @@ -239,15 +276,55 @@ export const getJobConfigFromFormState = ( formState.jobType === ANALYSIS_CONFIG_TYPE.REGRESSION || formState.jobType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION ) { - jobConfig.analysis = { - [formState.jobType]: { - dependent_variable: formState.dependentVariable, - num_top_feature_importance_values: formState.numTopFeatureImportanceValues, - training_percent: formState.trainingPercent, + let analysis = { + dependent_variable: formState.dependentVariable, + num_top_feature_importance_values: formState.numTopFeatureImportanceValues, + training_percent: formState.trainingPercent, + }; + + analysis = Object.assign( + analysis, + formState.predictionFieldName && { prediction_field_name: formState.predictionFieldName }, + formState.eta && { eta: formState.eta }, + formState.featureBagFraction && { + feature_bag_fraction: formState.featureBagFraction, }, + formState.gamma && { gamma: formState.gamma }, + formState.lambda && { lambda: formState.lambda }, + formState.maxTrees && { max_trees: formState.maxTrees }, + formState.randomizeSeed && { randomize_seed: formState.randomizeSeed } + ); + + jobConfig.analysis = { + [formState.jobType]: analysis, }; } + if ( + formState.jobType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION && + jobConfig?.analysis?.classification !== undefined && + formState.numTopClasses !== undefined + ) { + // @ts-ignore + jobConfig.analysis.classification.num_top_classes = formState.numTopClasses; + } + + if (formState.jobType === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION) { + const analysis = Object.assign( + {}, + formState.method && { method: formState.method }, + formState.nNeighbors && { + n_neighbors: formState.nNeighbors, + }, + formState.outlierFraction && { outlier_fraction: formState.outlierFraction }, + formState.standardizationEnabled && { + standardization_enabled: formState.standardizationEnabled, + } + ); + // @ts-ignore + jobConfig.analysis.outlier_detection = analysis; + } + return jobConfig; }; @@ -279,6 +356,11 @@ export function getCloneFormStateFromJobConfig( resultState.dependentVariable = analysisConfig.dependent_variable; resultState.numTopFeatureImportanceValues = analysisConfig.num_top_feature_importance_values; resultState.trainingPercent = analysisConfig.training_percent; + + if (isClassificationAnalysis(analyticsJobConfig.analysis)) { + // @ts-ignore + resultState.numTopClasses = analysisConfig.num_top_classes; + } } return resultState; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts index 1ec767d014a2e..c4cbe149f88bc 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts @@ -36,11 +36,24 @@ import { getCloneFormStateFromJobConfig, } from './state'; +import { ANALYTICS_STEPS } from '../../../analytics_creation/page'; + +export interface AnalyticsCreationStep { + number: ANALYTICS_STEPS; + completed: boolean; +} + export interface CreateAnalyticsFormProps { actions: ActionDispatchers; state: State; } +export interface CreateAnalyticsStepProps extends CreateAnalyticsFormProps { + setCurrentStep: React.Dispatch>; + step?: ANALYTICS_STEPS; + stepActivated?: boolean; +} + export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { const mlContext = useMlContext(); const [state, dispatch] = useReducer(reducer, getInitialState()); @@ -261,8 +274,12 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { dispatch({ type: ACTION.OPEN_MODAL }); }; + const initiateWizard = async () => { + await mlContext.indexPatterns.clearCache(); + await prepareFormValidation(); + }; + const startAnalyticsJob = async () => { - setIsModalButtonDisabled(true); try { const response = await ml.dataFrameAnalytics.startDataFrameAnalytics(jobId); if (response.acknowledged !== true) { @@ -278,7 +295,6 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { ), }); setIsJobStarted(true); - setIsModalButtonDisabled(false); refresh(); } catch (e) { addRequestMessage({ @@ -290,7 +306,6 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { } ), }); - setIsModalButtonDisabled(false); } }; @@ -331,6 +346,7 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { closeModal, createAnalyticsJob, openModal, + initiateWizard, resetAdvancedEditorMessages, setAdvancedEditorRawString, setFormState, diff --git a/x-pack/plugins/ml/public/application/datavisualizer/index_based/page.tsx b/x-pack/plugins/ml/public/application/datavisualizer/index_based/page.tsx index d68c0342ac857..97b4043c9fd64 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/index_based/page.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/index_based/page.tsx @@ -27,6 +27,7 @@ import { Query, esQuery, esKuery, + UI_SETTINGS, } from '../../../../../../../src/plugins/data/public'; import { SavedSearchSavedObject } from '../../../../common/types/kibana'; import { NavigationMenu } from '../../components/navigation_menu'; @@ -254,7 +255,7 @@ export const Page: FC = () => { qry = esKuery.toElasticsearchQuery(ast, currentIndexPattern); } else { qry = esQuery.luceneStringToDsl(qryString); - esQuery.decorateQuery(qry, kibanaConfig.get('query:queryString:options')); + esQuery.decorateQuery(qry, kibanaConfig.get(UI_SETTINGS.QUERY_STRING_OPTIONS)); } return { diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container_service.js b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container_service.js index c2dd8e6378305..8b30dccc25306 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container_service.js +++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container_service.js @@ -518,7 +518,6 @@ function processRecordsForDisplay(anomalyRecords) { } }); - console.log('explorer charts aggregatedData is:', aggregatedData); let recordsForSeries = []; // Convert to an array of the records with the highest record_score per unique series. _.each(aggregatedData, (detectorsForJob) => { diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_utils.js b/x-pack/plugins/ml/public/application/explorer/explorer_utils.js index f35a000b7f9e1..bd6a7ee59c942 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_utils.js +++ b/x-pack/plugins/ml/public/application/explorer/explorer_utils.js @@ -715,7 +715,6 @@ export async function loadDataForCharts( (selectedCells !== undefined && Object.keys(selectedCells).length > 0) || influencersFilterQuery !== undefined ) { - console.log('Explorer anomaly charts data set:', resp.records); resolve(resp.records); } @@ -764,7 +763,6 @@ export function loadOverallData(selectedJobs, interval, bounds) { interval.asSeconds() ); - console.log('Explorer overall swimlane data set:', overallSwimlaneData); resolve({ loading: false, overallSwimlaneData, @@ -795,7 +793,6 @@ export function loadViewBySwimlane( getSwimlaneContainerWidth(noInfluencersConfigured) ).asSeconds() ); - console.log('Explorer view by swimlane data set:', viewBySwimlaneData); resolve({ viewBySwimlaneData, @@ -879,7 +876,6 @@ export async function loadTopInfluencers( ) .then((resp) => { // TODO - sort the influencers keys so that the partition field(s) are first. - console.log('Explorer top influencers data set:', resp.influencers); resolve(resp.influencers); }); } else { diff --git a/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_creation.tsx b/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_creation.tsx new file mode 100644 index 0000000000000..68af9a2a49cab --- /dev/null +++ b/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_creation.tsx @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC } from 'react'; +import { i18n } from '@kbn/i18n'; +import { parse } from 'query-string'; +import { MlRoute, PageLoader, PageProps } from '../../router'; +import { useResolver } from '../../use_resolver'; +import { basicResolvers } from '../../resolvers'; +import { Page } from '../../../data_frame_analytics/pages/analytics_creation'; +import { ML_BREADCRUMB } from '../../breadcrumbs'; + +const breadcrumbs = [ + ML_BREADCRUMB, + { + text: i18n.translate('xpack.ml.dataFrameAnalyticsBreadcrumbs.dataFrameManagementLabel', { + defaultMessage: 'Data Frame Analytics', + }), + href: '#/data_frame_analytics', + }, +]; + +export const analyticsJobsCreationRoute: MlRoute = { + path: '/data_frame_analytics/new_job', + render: (props, deps) => , + breadcrumbs, +}; + +const PageWrapper: FC = ({ location, deps }) => { + const { index, savedSearchId }: Record = parse(location.search, { sort: false }); + const { context } = useResolver(index, savedSearchId, deps.config, basicResolvers(deps)); + + return ( + + + + ); +}; diff --git a/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/index.ts b/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/index.ts index 552c15a408b65..9b6bcc25c8c7e 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/index.ts +++ b/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/index.ts @@ -6,3 +6,4 @@ export * from './analytics_jobs_list'; export * from './analytics_job_exploration'; +export * from './analytics_job_creation'; diff --git a/x-pack/plugins/ml/public/application/services/explorer_service.ts b/x-pack/plugins/ml/public/application/services/explorer_service.ts index efcec8cf2b954..717ed3ba64c37 100644 --- a/x-pack/plugins/ml/public/application/services/explorer_service.ts +++ b/x-pack/plugins/ml/public/application/services/explorer_service.ts @@ -6,7 +6,11 @@ import { IUiSettingsClient } from 'kibana/public'; import { i18n } from '@kbn/i18n'; -import { TimefilterContract, TimeRange } from '../../../../../../src/plugins/data/public'; +import { + TimefilterContract, + TimeRange, + UI_SETTINGS, +} from '../../../../../../src/plugins/data/public'; import { getBoundsRoundedToInterval, TimeBuckets, TimeRangeBounds } from '../util/time_buckets'; import { ExplorerJob, OverallSwimlaneData, SwimlaneData } from '../explorer/explorer_utils'; import { VIEW_BY_JOB_LABEL } from '../explorer/explorer_constants'; @@ -25,8 +29,8 @@ export class ExplorerService { private mlResultsService: MlResultsService ) { this.timeBuckets = new TimeBuckets({ - 'histogram:maxBars': uiSettings.get('histogram:maxBars'), - 'histogram:barTarget': uiSettings.get('histogram:barTarget'), + 'histogram:maxBars': uiSettings.get(UI_SETTINGS.HISTOGRAM_MAX_BARS), + 'histogram:barTarget': uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET), dateFormat: uiSettings.get('dateFormat'), 'dateFormat:scaled': uiSettings.get('dateFormat:scaled'), }); diff --git a/x-pack/plugins/ml/public/application/services/job_service.js b/x-pack/plugins/ml/public/application/services/job_service.js index 8d59270b36dae..a3be479571702 100644 --- a/x-pack/plugins/ml/public/application/services/job_service.js +++ b/x-pack/plugins/ml/public/application/services/job_service.js @@ -368,6 +368,7 @@ class JobService { delete tempJob.calendars; delete tempJob.timing_stats; delete tempJob.forecasts_stats; + delete tempJob.assignment_explanation; delete tempJob.analysis_config.use_per_partition_normalization; @@ -411,8 +412,7 @@ class JobService { // return the promise chain return ml .updateJob({ jobId, job }) - .then((resp) => { - console.log('update job', resp); + .then(() => { return { success: true }; }) .catch((err) => { @@ -422,7 +422,7 @@ class JobService { values: { jobId }, }) ); - console.log('update job', err); + console.error('update job', err); return { success: false, message: err.message }; }); } diff --git a/x-pack/plugins/ml/public/application/util/time_buckets.d.ts b/x-pack/plugins/ml/public/application/util/time_buckets.d.ts index 9c5d663a6e4ab..91661ea3fd3fa 100644 --- a/x-pack/plugins/ml/public/application/util/time_buckets.d.ts +++ b/x-pack/plugins/ml/public/application/util/time_buckets.d.ts @@ -5,6 +5,7 @@ */ import { Moment } from 'moment'; +import { UI_SETTINGS } from '../../../../../../src/plugins/data/public'; export interface TimeRangeBounds { min?: Moment; diff --git a/x-pack/plugins/ml/public/application/util/time_buckets.js b/x-pack/plugins/ml/public/application/util/time_buckets.js index 2b23eca1ab5c0..1915a4ce6516b 100644 --- a/x-pack/plugins/ml/public/application/util/time_buckets.js +++ b/x-pack/plugins/ml/public/application/util/time_buckets.js @@ -11,7 +11,7 @@ import dateMath from '@elastic/datemath'; import { timeBucketsCalcAutoIntervalProvider } from './calc_auto_interval'; import { parseInterval } from '../../../common/util/parse_interval'; import { getFieldFormats, getUiSettings } from './dependency_cache'; -import { FIELD_FORMAT_IDS } from '../../../../../../src/plugins/data/public'; +import { FIELD_FORMAT_IDS, UI_SETTINGS } from '../../../../../../src/plugins/data/public'; const unitsDesc = dateMath.unitsDesc; const largeMax = unitsDesc.indexOf('w'); // Multiple units of week or longer converted to days for ES intervals. @@ -21,8 +21,8 @@ const calcAuto = timeBucketsCalcAutoIntervalProvider(); export function getTimeBucketsFromCache() { const uiSettings = getUiSettings(); return new TimeBuckets({ - 'histogram:maxBars': uiSettings.get('histogram:maxBars'), - 'histogram:barTarget': uiSettings.get('histogram:barTarget'), + [UI_SETTINGS.HISTOGRAM_MAX_BARS]: uiSettings.get(UI_SETTINGS.HISTOGRAM_MAX_BARS), + [UI_SETTINGS.HISTOGRAM_BAR_TARGET]: uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET), dateFormat: uiSettings.get('dateFormat'), 'dateFormat:scaled': uiSettings.get('dateFormat:scaled'), }); @@ -35,8 +35,8 @@ export function getTimeBucketsFromCache() { */ export function TimeBuckets(timeBucketsConfig) { this._timeBucketsConfig = timeBucketsConfig; - this.barTarget = this._timeBucketsConfig['histogram:barTarget']; - this.maxBars = this._timeBucketsConfig['histogram:maxBars']; + this.barTarget = this._timeBucketsConfig[UI_SETTINGS.HISTOGRAM_BAR_TARGET]; + this.maxBars = this._timeBucketsConfig[UI_SETTINGS.HISTOGRAM_MAX_BARS]; } /** diff --git a/x-pack/plugins/ml/public/application/util/time_buckets.test.js b/x-pack/plugins/ml/public/application/util/time_buckets.test.js index baecf7df90641..250c7255f5b99 100644 --- a/x-pack/plugins/ml/public/application/util/time_buckets.test.js +++ b/x-pack/plugins/ml/public/application/util/time_buckets.test.js @@ -5,6 +5,7 @@ */ import moment from 'moment'; +import { UI_SETTINGS } from '../../../../../../src/plugins/data/public'; import { TimeBuckets, getBoundsRoundedToInterval, calcEsInterval } from './time_buckets'; describe('ML - time buckets', () => { @@ -13,8 +14,8 @@ describe('ML - time buckets', () => { beforeEach(() => { const timeBucketsConfig = { - 'histogram:maxBars': 100, - 'histogram:barTarget': 50, + [UI_SETTINGS.HISTOGRAM_MAX_BARS]: 100, + [UI_SETTINGS.HISTOGRAM_BAR_TARGET]: 50, }; autoBuckets = new TimeBuckets(timeBucketsConfig); diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.ts b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.ts index e48ce9f9a1d92..74a7b432de267 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.ts @@ -27,7 +27,7 @@ import { MlStartDependencies } from '../../plugin'; import { SWIMLANE_TYPE } from '../../application/explorer/explorer_constants'; import { Filter } from '../../../../../../src/plugins/data/common/es_query/filters'; import { Query } from '../../../../../../src/plugins/data/common/query'; -import { esKuery } from '../../../../../../src/plugins/data/public'; +import { esKuery, UI_SETTINGS } from '../../../../../../src/plugins/data/public'; import { ExplorerJob, OverallSwimlaneData } from '../../application/explorer/explorer_utils'; import { parseInterval } from '../../../common/util/parse_interval'; import { AnomalyDetectorService } from '../../application/services/anomaly_detector_service'; @@ -62,8 +62,8 @@ export function useSwimlaneInputResolver( const timeBuckets = useMemo(() => { return new TimeBuckets({ - 'histogram:maxBars': uiSettings.get('histogram:maxBars'), - 'histogram:barTarget': uiSettings.get('histogram:barTarget'), + 'histogram:maxBars': uiSettings.get(UI_SETTINGS.HISTOGRAM_MAX_BARS), + 'histogram:barTarget': uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET), dateFormat: uiSettings.get('dateFormat'), 'dateFormat:scaled': uiSettings.get('dateFormat:scaled'), }); diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_ecommerce/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_ecommerce/manifest.json index 4c0186023b458..11d4f8e0b97df 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_ecommerce/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_ecommerce/manifest.json @@ -7,7 +7,7 @@ "defaultIndexPattern": "kibana_sample_data_ecommerce", "query": { "bool": { - "filter": [{ "term": { "_index": "kibana_sample_data_ecommerce" } }] + "filter": [{ "term": { "event.dataset": "sample_ecommerce" } }] } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_ecommerce/ml/datafeed_high_sum_total_sales.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_ecommerce/ml/datafeed_high_sum_total_sales.json index 0a955a766bd53..d61e6ba22ec2f 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_ecommerce/ml/datafeed_high_sum_total_sales.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_ecommerce/ml/datafeed_high_sum_total_sales.json @@ -3,7 +3,7 @@ "indices": ["INDEX_PATTERN_NAME"], "query": { "bool": { - "filter": [{ "term": { "_index": "kibana_sample_data_ecommerce" } }] + "filter": [{ "term": { "event.dataset": "sample_ecommerce" } }] } } } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/manifest.json index a0b47e7135312..446f56a717e11 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/manifest.json @@ -7,7 +7,7 @@ "defaultIndexPattern": "kibana_sample_data_logs", "query": { "bool": { - "filter": [{ "term": { "_index": "kibana_sample_data_logs" } }] + "filter": [{ "term": { "event.dataset": "sample_web_logs" } }] } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_low_request_rate.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_low_request_rate.json index 843a7d1651dc8..a9865183320d5 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_low_request_rate.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_low_request_rate.json @@ -3,7 +3,7 @@ "indices": ["INDEX_PATTERN_NAME"], "query": { "bool": { - "filter": [{ "term": { "_index": "kibana_sample_data_logs" } }] + "filter": [{ "term": { "event.dataset": "sample_web_logs" } }] } }, "aggregations": { diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_response_code_rates.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_response_code_rates.json index 3a0f67daa392a..9aef3386cb9ef 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_response_code_rates.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_response_code_rates.json @@ -3,7 +3,7 @@ "indices": ["INDEX_PATTERN_NAME"], "query": { "bool": { - "filter": [{ "term": { "_index": "kibana_sample_data_logs" } }] + "filter": [{ "term": { "event.dataset": "sample_web_logs" } }] } } } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_url_scanning.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_url_scanning.json index 3a0f67daa392a..9aef3386cb9ef 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_url_scanning.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/sample_data_weblogs/ml/datafeed_url_scanning.json @@ -3,7 +3,7 @@ "indices": ["INDEX_PATTERN_NAME"], "query": { "bool": { - "filter": [{ "term": { "_index": "kibana_sample_data_logs" } }] + "filter": [{ "term": { "event.dataset": "sample_web_logs" } }] } } } diff --git a/x-pack/plugins/ml/server/routes/schemas/data_analytics_schema.ts b/x-pack/plugins/ml/server/routes/schemas/data_analytics_schema.ts index 0b2469c103578..e6b4e4ccf8582 100644 --- a/x-pack/plugins/ml/server/routes/schemas/data_analytics_schema.ts +++ b/x-pack/plugins/ml/server/routes/schemas/data_analytics_schema.ts @@ -47,6 +47,7 @@ export const dataAnalyticsExplainSchema = schema.object({ /** Source */ source: schema.object({ index: schema.string(), + query: schema.maybe(schema.any()), }), analysis: schema.any(), analyzed_fields: schema.maybe(schema.any()), diff --git a/x-pack/plugins/monitoring/public/plugin.ts b/x-pack/plugins/monitoring/public/plugin.ts index 73133da5a006c..24383028e558c 100644 --- a/x-pack/plugins/monitoring/public/plugin.ts +++ b/x-pack/plugins/monitoring/public/plugin.ts @@ -17,6 +17,7 @@ import { FeatureCatalogueCategory, HomePublicPluginSetup, } from '../../../../src/plugins/home/public'; +import { UI_SETTINGS } from '../../../../src/plugins/data/public'; import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/public'; import { MonitoringPluginDependencies, MonitoringConfig } from './types'; import { @@ -110,7 +111,7 @@ export class MonitoringPlugin timefilter.setRefreshInterval(refreshInterval); timefilter.setTime(time); uiSettings.overrideLocalDefault( - 'timepicker:refreshIntervalDefaults', + UI_SETTINGS.TIMEPICKER_REFRESH_INTERVAL_DEFAULTS, JSON.stringify(refreshInterval) ); uiSettings.overrideLocalDefault('timepicker:timeDefaults', JSON.stringify(time)); diff --git a/x-pack/plugins/monitoring/public/views/access_denied/index.html b/x-pack/plugins/monitoring/public/views/access_denied/index.html index 63cd4440ecf8a..24863559212f7 100644 --- a/x-pack/plugins/monitoring/public/views/access_denied/index.html +++ b/x-pack/plugins/monitoring/public/views/access_denied/index.html @@ -30,12 +30,13 @@
- + + +
diff --git a/x-pack/plugins/monitoring/public/views/access_denied/index.js b/x-pack/plugins/monitoring/public/views/access_denied/index.js index 856e59702963a..f7a4d03a26452 100644 --- a/x-pack/plugins/monitoring/public/views/access_denied/index.js +++ b/x-pack/plugins/monitoring/public/views/access_denied/index.js @@ -4,16 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import { noop } from 'lodash'; +import { kbnBaseUrl } from '../../../../../../src/plugins/kibana_legacy/common/kbn_base_url'; import { uiRoutes } from '../../angular/helpers/routes'; -import { Legacy } from '../../legacy_shims'; import template from './index.html'; const tryPrivilege = ($http, kbnUrl) => { return $http .get('../api/monitoring/v1/check_access') .then(() => kbnUrl.redirect('/home')) - .catch(noop); + .catch(() => true); }; uiRoutes.when('/access-denied', { @@ -31,17 +30,13 @@ uiRoutes.when('/access-denied', { }, }, controllerAs: 'accessDenied', - controller($scope, $injector) { - const $window = $injector.get('$window'); - const kbnBaseUrl = $injector.get('kbnBaseUrl'); + controller: function ($scope, $injector) { const $http = $injector.get('$http'); const kbnUrl = $injector.get('kbnUrl'); const $interval = $injector.get('$interval'); // The template's "Back to Kibana" button click handler - this.goToKibana = () => { - $window.location.href = Legacy.shims.getBasePath() + kbnBaseUrl; - }; + this.goToKibanaURL = kbnBaseUrl; // keep trying to load data in the background const accessPoller = $interval(() => tryPrivilege($http, kbnUrl), 5 * 1000); // every 5 seconds diff --git a/x-pack/plugins/observability/public/application/index.tsx b/x-pack/plugins/observability/public/application/index.tsx new file mode 100644 index 0000000000000..21a9fabf445f1 --- /dev/null +++ b/x-pack/plugins/observability/public/application/index.tsx @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React from 'react'; +import ReactDOM from 'react-dom'; +import { EuiThemeProvider } from '../../../../legacy/common/eui_styled_components'; +import { AppMountParameters, CoreStart } from '../../../../../src/core/public'; +import { Home } from '../pages/home'; +import { PluginContext } from '../context/plugin_context'; + +export const renderApp = (core: CoreStart, { element }: AppMountParameters) => { + const i18nCore = core.i18n; + const isDarkMode = core.uiSettings.get('theme:darkMode'); + ReactDOM.render( + + + + + + + , + element + ); + return () => { + ReactDOM.unmountComponentAtNode(element); + }; +}; diff --git a/x-pack/plugins/observability/public/assets/observability_overview.png b/x-pack/plugins/observability/public/assets/observability_overview.png new file mode 100644 index 0000000000000..70be08af9745a Binary files /dev/null and b/x-pack/plugins/observability/public/assets/observability_overview.png differ diff --git a/x-pack/plugins/observability/public/context/plugin_context.tsx b/x-pack/plugins/observability/public/context/plugin_context.tsx new file mode 100644 index 0000000000000..7d705e7a6cc05 --- /dev/null +++ b/x-pack/plugins/observability/public/context/plugin_context.tsx @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { createContext } from 'react'; +import { AppMountContext } from 'kibana/public'; + +export interface PluginContextValue { + core: AppMountContext['core']; +} + +export const PluginContext = createContext({} as PluginContextValue); diff --git a/x-pack/plugins/observability/public/hooks/use_plugin_context.tsx b/x-pack/plugins/observability/public/hooks/use_plugin_context.tsx new file mode 100644 index 0000000000000..eeec115f0d286 --- /dev/null +++ b/x-pack/plugins/observability/public/hooks/use_plugin_context.tsx @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { useContext } from 'react'; +import { PluginContext } from '../context/plugin_context'; + +export function usePluginContext() { + return useContext(PluginContext); +} diff --git a/x-pack/plugins/observability/public/pages/home/index.tsx b/x-pack/plugins/observability/public/pages/home/index.tsx new file mode 100644 index 0000000000000..072d3c47d3a55 --- /dev/null +++ b/x-pack/plugins/observability/public/pages/home/index.tsx @@ -0,0 +1,205 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiButton, + EuiCard, + EuiFlexGrid, + EuiFlexGroup, + EuiFlexItem, + EuiHorizontalRule, + EuiIcon, + EuiImage, + EuiSpacer, + EuiText, + EuiTitle, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React, { useEffect } from 'react'; +import styled from 'styled-components'; +import { usePluginContext } from '../../hooks/use_plugin_context'; +import { appsSection, tryItOutItemsSection } from './section'; + +const Container = styled.div` + min-height: calc(100vh - 48px); + background: ${(props) => props.theme.eui.euiColorEmptyShade}; +`; + +const Title = styled.div` + background-color: ${(props) => props.theme.eui.euiPageBackgroundColor}; + border-bottom: ${(props) => props.theme.eui.euiBorderThin}; +`; + +const Page = styled.div` + width: 100%; + max-width: 1200px; + margin: 0 auto; + overflow: hidden; +} +`; + +const EuiCardWithoutPadding = styled(EuiCard)` + padding: 0; +`; + +export const Home = () => { + const { core } = usePluginContext(); + + useEffect(() => { + core.chrome.setBreadcrumbs([ + { + text: i18n.translate('xpack.observability.home.breadcrumb.observability', { + defaultMessage: 'Observability', + }), + }, + { + text: i18n.translate('xpack.observability.home.breadcrumb.gettingStarted', { + defaultMessage: 'Getting started', + }), + }, + ]); + }, [core]); + + return ( + + + <Page> + <EuiSpacer size="xxl" /> + <EuiFlexGroup> + <EuiFlexItem grow={false}> + <EuiIcon type="logoObservability" size="xxl" /> + </EuiFlexItem> + <EuiFlexItem> + <EuiTitle size="m"> + <h1> + {i18n.translate('xpack.observability.home.title', { + defaultMessage: 'Observability', + })} + </h1> + </EuiTitle> + </EuiFlexItem> + </EuiFlexGroup> + <EuiSpacer size="xxl" /> + </Page> + + + + + {/* title and description */} + + +

+ {i18n.translate('xpack.observability.home.sectionTitle', { + defaultMessage: 'Observability built on the Elastic Stack', + })} +

+
+ + + {i18n.translate('xpack.observability.home.sectionsubtitle', { + defaultMessage: + 'Bring your logs, metrics, and APM traces together at scale in a single stack so you can monitor and react to events happening anywhere in your environment.', + })} + +
+ + {/* Apps sections */} + + + + + + {appsSection.map((app) => ( + + } + title={ + +

{app.title}

+
+ } + description={app.description} + /> +
+ ))} +
+
+ + + +
+
+ + {/* Get started button */} + + + + + {i18n.translate('xpack.observability.home.getStatedButton', { + defaultMessage: 'Get started', + })} + + + + + + + + {/* Try it out */} + + + + +

+ {i18n.translate('xpack.observability.home.tryItOut', { + defaultMessage: 'Try it out', + })} +

+
+
+
+
+ + {/* Try it out sections */} + + + {tryItOutItemsSection.map((item) => ( + + } + title={ + +

{item.title}

+
+ } + description={item.description} + target={item.target} + href={item.href} + /> +
+ ))} +
+ +
+
+
+
+ ); +}; diff --git a/x-pack/plugins/observability/public/pages/home/section.ts b/x-pack/plugins/observability/public/pages/home/section.ts new file mode 100644 index 0000000000000..f8bbfbfa30548 --- /dev/null +++ b/x-pack/plugins/observability/public/pages/home/section.ts @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { i18n } from '@kbn/i18n'; + +interface ISection { + id: string; + title: string; + icon: string; + description: string; + href?: string; + target?: '_blank'; +} + +export const appsSection: ISection[] = [ + { + id: 'logs', + title: i18n.translate('xpack.observability.section.apps.logs.title', { + defaultMessage: 'Logs', + }), + icon: 'logoLogging', + description: i18n.translate('xpack.observability.section.apps.logs.description', { + defaultMessage: + 'The Elastic Stack (sometimes known as the ELK Stack) is the most popular open source logging platform.', + }), + }, + { + id: 'apm', + title: i18n.translate('xpack.observability.section.apps.apm.title', { + defaultMessage: 'APM', + }), + icon: 'logoAPM', + description: i18n.translate('xpack.observability.section.apps.apm.description', { + defaultMessage: + 'See exactly where your application is spending time so you can quickly fix issues and feel good about the code you push.', + }), + }, + { + id: 'metrics', + title: i18n.translate('xpack.observability.section.apps.metrics.title', { + defaultMessage: 'Metrics', + }), + icon: 'logoMetrics', + description: i18n.translate('xpack.observability.section.apps.metrics.description', { + defaultMessage: + 'Already using the Elastic Stack for logs? Add metrics in just a few steps and correlate metrics and logs in one place.', + }), + }, + { + id: 'uptime', + title: i18n.translate('xpack.observability.section.apps.uptime.title', { + defaultMessage: 'Uptime', + }), + icon: 'logoUptime', + description: i18n.translate('xpack.observability.section.apps.uptime.description', { + defaultMessage: + 'React to availability issues across your apps and services before they affect users.', + }), + }, +]; + +export const tryItOutItemsSection: ISection[] = [ + { + id: 'demo', + title: i18n.translate('xpack.observability.section.tryItOut.demo.title', { + defaultMessage: 'Demo Playground', + }), + icon: 'play', + description: '', + href: 'https://demo.elastic.co/', + target: '_blank', + }, + { + id: 'sampleData', + title: i18n.translate('xpack.observability.section.tryItOut.sampleData.title', { + defaultMessage: 'Add sample data', + }), + icon: 'documents', + description: '', + href: '/app/home#/tutorial_directory/sampleData', + }, +]; diff --git a/x-pack/plugins/observability/public/plugin.ts b/x-pack/plugins/observability/public/plugin.ts index a7eb1c50a0392..f2c88a7b1c056 100644 --- a/x-pack/plugins/observability/public/plugin.ts +++ b/x-pack/plugins/observability/public/plugin.ts @@ -3,13 +3,37 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { Plugin as PluginClass, PluginInitializerContext } from 'kibana/public'; +import { + AppMountParameters, + CoreSetup, + DEFAULT_APP_CATEGORIES, + Plugin as PluginClass, + PluginInitializerContext, +} from '../../../../src/core/public'; export type ClientSetup = void; export type ClientStart = void; -export class Plugin implements PluginClass { +export class Plugin implements PluginClass { constructor(context: PluginInitializerContext) {} - start() {} - setup() {} + + public setup(core: CoreSetup) { + core.application.register({ + id: 'observability-overview', + title: 'Overview', + order: 8000, + appRoute: '/app/observability', + category: DEFAULT_APP_CATEGORIES.observability, + + async mount(params: AppMountParameters) { + // Load application bundle + const { renderApp } = await import('./application'); + // Get start services + const [coreStart] = await core.getStartServices(); + + return renderApp(coreStart, params); + }, + }); + } + public start() {} } diff --git a/x-pack/plugins/oss_telemetry/server/lib/get_past_days.test.ts b/x-pack/plugins/oss_telemetry/server/lib/get_past_days.test.ts new file mode 100644 index 0000000000000..28909779343a5 --- /dev/null +++ b/x-pack/plugins/oss_telemetry/server/lib/get_past_days.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import moment from 'moment'; +import { getPastDays } from './get_past_days'; + +describe('getPastDays', () => { + test('Returns 2 days that have passed from the current date', () => { + const pastDate = moment().subtract(2, 'days').startOf('day').toString(); + + expect(getPastDays(pastDate)).toEqual(2); + }); + + test('Returns 30 days that have passed from the current date', () => { + const pastDate = moment().subtract(30, 'days').startOf('day').toString(); + + expect(getPastDays(pastDate)).toEqual(30); + }); +}); diff --git a/x-pack/plugins/oss_telemetry/server/lib/get_past_days.ts b/x-pack/plugins/oss_telemetry/server/lib/get_past_days.ts new file mode 100644 index 0000000000000..4f25ef147ad43 --- /dev/null +++ b/x-pack/plugins/oss_telemetry/server/lib/get_past_days.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +export const getPastDays = (dateString: string): number => { + const date = new Date(dateString); + const today = new Date(); + const diff = Math.abs(date.getTime() - today.getTime()); + return Math.trunc(diff / (1000 * 60 * 60 * 24)); +}; diff --git a/x-pack/plugins/oss_telemetry/server/lib/tasks/visualizations/task_runner.test.ts b/x-pack/plugins/oss_telemetry/server/lib/tasks/visualizations/task_runner.test.ts index 6a47983a6f4d9..c064f39f4bc6a 100644 --- a/x-pack/plugins/oss_telemetry/server/lib/tasks/visualizations/task_runner.test.ts +++ b/x-pack/plugins/oss_telemetry/server/lib/tasks/visualizations/task_runner.test.ts @@ -13,6 +13,7 @@ import { import { visualizationsTaskRunner } from './task_runner'; import { TaskInstance } from '../../../../../task_manager/server'; import { getNextMidnight } from '../../get_next_midnight'; +import moment from 'moment'; describe('visualizationsTaskRunner', () => { let mockTaskInstance: TaskInstance; @@ -55,6 +56,9 @@ describe('visualizationsTaskRunner', () => { spaces_max: 1, spaces_min: 1, total: 1, + saved_7_days_total: 1, + saved_30_days_total: 1, + saved_90_days_total: 1, }, }, }, @@ -69,6 +73,7 @@ describe('visualizationsTaskRunner', () => { _source: { type: 'visualization', visualization: { visState: '{"type": "cave_painting"}' }, + updated_at: moment().subtract(7, 'days').startOf('day').toString(), }, }, { @@ -76,11 +81,16 @@ describe('visualizationsTaskRunner', () => { _source: { type: 'visualization', visualization: { visState: '{"type": "printing_press"}' }, + updated_at: moment().subtract(20, 'days').startOf('day').toString(), }, }, { _id: 'meat:visualization:coolviz-789', - _source: { type: 'visualization', visualization: { visState: '{"type": "floppy_disk"}' } }, + _source: { + type: 'visualization', + visualization: { visState: '{"type": "floppy_disk"}' }, + updated_at: moment().subtract(2, 'months').startOf('day').toString(), + }, }, // meat space { @@ -88,38 +98,99 @@ describe('visualizationsTaskRunner', () => { _source: { type: 'visualization', visualization: { visState: '{"type": "cave_painting"}' }, + updated_at: moment().subtract(89, 'days').startOf('day').toString(), }, }, { _id: 'meat:visualization:coolviz-789', - _source: { type: 'visualization', visualization: { visState: '{"type": "cuneiform"}' } }, + _source: { + type: 'visualization', + visualization: { visState: '{"type": "cuneiform"}' }, + updated_at: moment().subtract(5, 'months').startOf('day').toString(), + }, }, { _id: 'meat:visualization:coolviz-789', - _source: { type: 'visualization', visualization: { visState: '{"type": "cuneiform"}' } }, + _source: { + type: 'visualization', + visualization: { visState: '{"type": "cuneiform"}' }, + updated_at: moment().subtract(2, 'days').startOf('day').toString(), + }, }, { _id: 'meat:visualization:coolviz-789', - _source: { type: 'visualization', visualization: { visState: '{"type": "floppy_disk"}' } }, + _source: { + type: 'visualization', + visualization: { visState: '{"type": "floppy_disk"}' }, + updated_at: moment().subtract(7, 'days').startOf('day').toString(), + }, }, // cyber space { _id: 'cyber:visualization:coolviz-789', - _source: { type: 'visualization', visualization: { visState: '{"type": "floppy_disk"}' } }, + _source: { + type: 'visualization', + visualization: { visState: '{"type": "floppy_disk"}' }, + updated_at: moment().subtract(7, 'months').startOf('day').toString(), + }, }, { _id: 'cyber:visualization:coolviz-789', - _source: { type: 'visualization', visualization: { visState: '{"type": "floppy_disk"}' } }, + _source: { + type: 'visualization', + visualization: { visState: '{"type": "floppy_disk"}' }, + updated_at: moment().subtract(3, 'days').startOf('day').toString(), + }, }, { _id: 'cyber:visualization:coolviz-123', _source: { type: 'visualization', visualization: { visState: '{"type": "cave_painting"}' }, + updated_at: moment().subtract(15, 'days').startOf('day').toString(), }, }, ]); + const expectedStats = { + cave_painting: { + total: 3, + spaces_min: 1, + spaces_max: 1, + spaces_avg: 1, + saved_7_days_total: 1, + saved_30_days_total: 2, + saved_90_days_total: 3, + }, + printing_press: { + total: 1, + spaces_min: 1, + spaces_max: 1, + spaces_avg: 1, + saved_7_days_total: 0, + saved_30_days_total: 1, + saved_90_days_total: 1, + }, + cuneiform: { + total: 2, + spaces_min: 2, + spaces_max: 2, + spaces_avg: 2, + saved_7_days_total: 1, + saved_30_days_total: 1, + saved_90_days_total: 1, + }, + floppy_disk: { + total: 4, + spaces_min: 2, + spaces_max: 2, + spaces_avg: 2, + saved_7_days_total: 2, + saved_30_days_total: 2, + saved_90_days_total: 3, + }, + }; + const runner = visualizationsTaskRunner( mockTaskInstance, getMockConfig(), @@ -131,13 +202,10 @@ describe('visualizationsTaskRunner', () => { error: undefined, state: { runs: 1, - stats: { - cave_painting: { total: 3, spaces_min: 1, spaces_max: 1, spaces_avg: 1 }, - printing_press: { total: 1, spaces_min: 1, spaces_max: 1, spaces_avg: 1 }, - cuneiform: { total: 2, spaces_min: 2, spaces_max: 2, spaces_avg: 2 }, - floppy_disk: { total: 4, spaces_min: 2, spaces_max: 2, spaces_avg: 2 }, - }, + stats: expectedStats, }, }); + + expect(result.state.stats).toMatchObject(expectedStats); }); }); diff --git a/x-pack/plugins/oss_telemetry/server/lib/tasks/visualizations/task_runner.ts b/x-pack/plugins/oss_telemetry/server/lib/tasks/visualizations/task_runner.ts index b15ead36a75f6..5f7f70ee5d62a 100644 --- a/x-pack/plugins/oss_telemetry/server/lib/tasks/visualizations/task_runner.ts +++ b/x-pack/plugins/oss_telemetry/server/lib/tasks/visualizations/task_runner.ts @@ -10,12 +10,14 @@ import { first } from 'rxjs/operators'; import { APICaller, IClusterClient } from 'src/core/server'; import { getNextMidnight } from '../../get_next_midnight'; +import { getPastDays } from '../../get_past_days'; import { TaskInstance } from '../../../../../task_manager/server'; import { ESSearchHit } from '../../../../../apm/typings/elasticsearch'; interface VisSummary { type: string; space: string; + past_days: number; } /* @@ -26,7 +28,11 @@ async function getStats(callCluster: APICaller, index: string) { size: 10000, // elasticsearch index.max_result_window default value index, ignoreUnavailable: true, - filterPath: ['hits.hits._id', 'hits.hits._source.visualization'], + filterPath: [ + 'hits.hits._id', + 'hits.hits._source.visualization', + 'hits.hits._source.updated_at', + ], body: { query: { bool: { filter: { term: { type: 'visualization' } } }, @@ -43,13 +49,14 @@ async function getStats(callCluster: APICaller, index: string) { const visSummaries: VisSummary[] = esResponse.hits.hits.map( (hit: ESSearchHit<{ visState: string }>) => { const spacePhrases: string[] = hit._id.split(':'); + const lastUpdated: string = _.get(hit, '_source.updated_at'); const space = spacePhrases.length === 3 ? spacePhrases[0] : 'default'; // if in a custom space, the format of a saved object ID is space:type:id const visualization = _.get(hit, '_source.visualization', { visState: '{}' }); const visState: { type?: string } = JSON.parse(visualization.visState); - return { type: visState.type || '_na_', space, + past_days: getPastDays(lastUpdated), }; } ); @@ -68,6 +75,9 @@ async function getStats(callCluster: APICaller, index: string) { spaces_min: _.min(spaceCounts), spaces_max: _.max(spaceCounts), spaces_avg: total / spaceCounts.length, + saved_7_days_total: curr.filter((c) => c.past_days <= 7).length, + saved_30_days_total: curr.filter((c) => c.past_days <= 30).length, + saved_90_days_total: curr.filter((c) => c.past_days <= 90).length, }; }); } diff --git a/x-pack/plugins/oss_telemetry/server/test_utils/index.ts b/x-pack/plugins/oss_telemetry/server/test_utils/index.ts index 428909dc7feed..93bde69629fbd 100644 --- a/x-pack/plugins/oss_telemetry/server/test_utils/index.ts +++ b/x-pack/plugins/oss_telemetry/server/test_utils/index.ts @@ -7,6 +7,7 @@ import { APICaller } from 'kibana/server'; import { of } from 'rxjs'; +import moment from 'moment'; import { elasticsearchServiceMock } from '../../../../../src/core/server/mocks'; import { ConcreteTaskInstance, @@ -38,6 +39,7 @@ const defaultMockSavedObjects = [ _source: { type: 'visualization', visualization: { visState: '{"type": "shell_beads"}' }, + updated_at: moment().subtract(7, 'days').startOf('day').toString(), }, }, ]; diff --git a/x-pack/plugins/painless_lab/public/application/components/output_pane/parameters_tab.tsx b/x-pack/plugins/painless_lab/public/application/components/output_pane/parameters_tab.tsx index 5a417933e8022..b707fd493bcdd 100644 --- a/x-pack/plugins/painless_lab/public/application/components/output_pane/parameters_tab.tsx +++ b/x-pack/plugins/painless_lab/public/application/components/output_pane/parameters_tab.tsx @@ -14,7 +14,7 @@ import { EuiText, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { monaco } from '@kbn/ui-shared-deps/monaco'; +import { monaco } from '@kbn/monaco'; import { i18n } from '@kbn/i18n'; import { CodeEditor } from '../../../../../../../src/plugins/kibana_react/public'; diff --git a/x-pack/plugins/painless_lab/public/application/hooks/use_submit_code.ts b/x-pack/plugins/painless_lab/public/application/hooks/use_submit_code.ts index 36cd4f280ac4c..d0426a5e67e46 100644 --- a/x-pack/plugins/painless_lab/public/application/hooks/use_submit_code.ts +++ b/x-pack/plugins/painless_lab/public/application/hooks/use_submit_code.ts @@ -19,6 +19,7 @@ export const useSubmitCode = (http: HttpSetup) => { const [response, setResponse] = useState(undefined); const [inProgress, setInProgress] = useState(false); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ const submit = useCallback( debounce( async (config: Payload) => { diff --git a/x-pack/plugins/painless_lab/public/lib/monaco_painless_lang.ts b/x-pack/plugins/painless_lab/public/lib/monaco_painless_lang.ts index 602697064a768..4278c77b4c791 100644 --- a/x-pack/plugins/painless_lab/public/lib/monaco_painless_lang.ts +++ b/x-pack/plugins/painless_lab/public/lib/monaco_painless_lang.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import * as monaco from 'monaco-editor'; +import { monaco } from '@kbn/monaco'; /** * Extends the default type for a Monarch language so we can use diff --git a/x-pack/plugins/painless_lab/public/services/language_service.ts b/x-pack/plugins/painless_lab/public/services/language_service.ts index efff9cd0e78d5..68ac3ca290ad8 100644 --- a/x-pack/plugins/painless_lab/public/services/language_service.ts +++ b/x-pack/plugins/painless_lab/public/services/language_service.ts @@ -7,7 +7,7 @@ // It is important that we use this specific monaco instance so that // editor settings are registered against the instance our React component // uses. -import { monaco } from '@kbn/ui-shared-deps/monaco'; +import { monaco } from '@kbn/monaco'; // @ts-ignore import workerSrc from 'raw-loader!monaco-editor/min/vs/base/worker/workerMain.js'; diff --git a/x-pack/plugins/reporting/server/config/schema.ts b/x-pack/plugins/reporting/server/config/schema.ts index dfabfa98f8cbf..b1234a6ddf0b6 100644 --- a/x-pack/plugins/reporting/server/config/schema.ts +++ b/x-pack/plugins/reporting/server/config/schema.ts @@ -162,6 +162,7 @@ const PollSchema = schema.object({ }); export const ConfigSchema = schema.object({ + enabled: schema.boolean({ defaultValue: true }), kibanaServer: KibanaServerSchema, queue: QueueSchema, capture: CaptureSchema, diff --git a/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.test.ts b/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.test.ts index 6f227d00974ca..ddcf94079ade4 100644 --- a/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.test.ts +++ b/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.test.ts @@ -8,7 +8,7 @@ import nodeCrypto from '@elastic/node-crypto'; // @ts-ignore import Puid from 'puid'; import sinon from 'sinon'; -import { fieldFormats } from '../../../../../../../src/plugins/data/server'; +import { fieldFormats, UI_SETTINGS } from '../../../../../../../src/plugins/data/server'; import { CancellationToken } from '../../../../common'; import { CSV_BOM_CHARS } from '../../../../common/constants'; import { LevelLogger } from '../../../lib'; @@ -16,6 +16,10 @@ import { setFieldFormats } from '../../../services'; import { createMockReportingCore } from '../../../test_helpers'; import { JobDocPayloadDiscoverCsv } from '../types'; import { executeJobFactory } from './execute_job'; +import { + CSV_SEPARATOR_SETTING, + CSV_QUOTE_VALUES_SETTING, +} from '../../../../../../../src/plugins/share/server'; const delay = (ms: number) => new Promise((resolve) => setTimeout(() => resolve(), ms)); @@ -94,13 +98,13 @@ describe('CSV Execute Job', function () { .stub(clusterStub, 'callAsCurrentUser') .resolves(defaultElasticsearchResponse); - mockUiSettingsClient.get.withArgs('csv:separator').returns(','); - mockUiSettingsClient.get.withArgs('csv:quoteValues').returns(true); + mockUiSettingsClient.get.withArgs(CSV_SEPARATOR_SETTING).returns(','); + mockUiSettingsClient.get.withArgs(CSV_QUOTE_VALUES_SETTING).returns(true); setFieldFormats({ fieldFormatServiceFactory() { const uiConfigMock = {}; - (uiConfigMock as any)['format:defaultTypeMap'] = { + (uiConfigMock as any)[UI_SETTINGS.FORMAT_DEFAULT_TYPE_MAP] = { _default_: { id: 'string', params: {} }, }; @@ -748,7 +752,7 @@ describe('CSV Execute Job', function () { }); it('should use custom uiSettings csv:separator for header', async function () { - mockUiSettingsClient.get.withArgs('csv:separator').returns(';'); + mockUiSettingsClient.get.withArgs(CSV_SEPARATOR_SETTING).returns(';'); const executeJob = await executeJobFactory(mockReportingCore, mockLogger); const jobParams = getJobDocPayload({ headers: encryptedHeaders, @@ -760,7 +764,7 @@ describe('CSV Execute Job', function () { }); it('should escape column headers if uiSettings csv:quoteValues is true', async function () { - mockUiSettingsClient.get.withArgs('csv:quoteValues').returns(true); + mockUiSettingsClient.get.withArgs(CSV_QUOTE_VALUES_SETTING).returns(true); const executeJob = await executeJobFactory(mockReportingCore, mockLogger); const jobParams = getJobDocPayload({ headers: encryptedHeaders, @@ -772,7 +776,7 @@ describe('CSV Execute Job', function () { }); it(`shouldn't escape column headers if uiSettings csv:quoteValues is false`, async function () { - mockUiSettingsClient.get.withArgs('csv:quoteValues').returns(false); + mockUiSettingsClient.get.withArgs(CSV_QUOTE_VALUES_SETTING).returns(false); const executeJob = await executeJobFactory(mockReportingCore, mockLogger); const jobParams = getJobDocPayload({ headers: encryptedHeaders, diff --git a/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.ts b/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.ts index de5ddb2503b2f..4b17cc669efe1 100644 --- a/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.ts +++ b/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.ts @@ -7,6 +7,10 @@ import { i18n } from '@kbn/i18n'; import Hapi from 'hapi'; import { IUiSettingsClient, KibanaRequest } from '../../../../../../../src/core/server'; +import { + CSV_SEPARATOR_SETTING, + CSV_QUOTE_VALUES_SETTING, +} from '../../../../../../../src/plugins/share/server'; import { ReportingCore } from '../../..'; import { CSV_BOM_CHARS, CSV_JOB_TYPE } from '../../../../common/constants'; import { getFieldFormats } from '../../../../server/services'; @@ -94,8 +98,8 @@ export const executeJobFactory: ExecuteJobFactory { const [separator, quoteValues, timezone] = await Promise.all([ - client.get('csv:separator'), - client.get('csv:quoteValues'), + client.get(CSV_SEPARATOR_SETTING), + client.get(CSV_QUOTE_VALUES_SETTING), client.get('dateFormat:tz'), ]); diff --git a/x-pack/plugins/reporting/server/export_types/csv/server/lib/field_format_map.test.ts b/x-pack/plugins/reporting/server/export_types/csv/server/lib/field_format_map.test.ts index 0434da3d11fe1..83aa23de67663 100644 --- a/x-pack/plugins/reporting/server/export_types/csv/server/lib/field_format_map.test.ts +++ b/x-pack/plugins/reporting/server/export_types/csv/server/lib/field_format_map.test.ts @@ -9,6 +9,7 @@ import expect from '@kbn/expect'; import { fieldFormats, FieldFormatsGetConfigFn, + UI_SETTINGS, } from '../../../../../../../../src/plugins/data/server'; import { fieldFormatMapFactory } from './field_format_map'; @@ -28,10 +29,10 @@ describe('field format map', function () { }, }; const configMock: Record = {}; - configMock['format:defaultTypeMap'] = { + configMock[UI_SETTINGS.FORMAT_DEFAULT_TYPE_MAP] = { number: { id: 'number', params: {} }, }; - configMock['format:number:defaultPattern'] = '0,0.[000]'; + configMock[UI_SETTINGS.FORMAT_NUMBER_DEFAULT_PATTERN] = '0,0.[000]'; const getConfig = ((key: string) => configMock[key]) as FieldFormatsGetConfigFn; const testValue = '4000'; diff --git a/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts b/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts index a9e4366f4eda6..3f997a703bef1 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts @@ -16,7 +16,12 @@ import { Filter, IIndexPattern, Query, + UI_SETTINGS, } from '../../../../../../../../src/plugins/data/server'; +import { + CSV_SEPARATOR_SETTING, + CSV_QUOTE_VALUES_SETTING, +} from '../../../../../../../../src/plugins/share/server'; import { CancellationToken } from '../../../../../common'; import { LevelLogger } from '../../../../lib'; import { createGenerateCsv } from '../../../csv/server/lib/generate_csv'; @@ -32,9 +37,9 @@ import { getFilters } from './get_filters'; const getEsQueryConfig = async (config: IUiSettingsClient) => { const configs = await Promise.all([ - config.get('query:allowLeadingWildcards'), - config.get('query:queryString:options'), - config.get('courier:ignoreFilterIfFieldNotInIndex'), + config.get(UI_SETTINGS.QUERY_ALLOW_LEADING_WILDCARDS), + config.get(UI_SETTINGS.QUERY_STRING_OPTIONS), + config.get(UI_SETTINGS.COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX), ]); const [allowLeadingWildcards, queryStringOptions, ignoreFilterIfFieldNotInIndex] = configs; return { @@ -45,7 +50,10 @@ const getEsQueryConfig = async (config: IUiSettingsClient) => { }; const getUiSettings = async (config: IUiSettingsClient) => { - const configs = await Promise.all([config.get('csv:separator'), config.get('csv:quoteValues')]); + const configs = await Promise.all([ + config.get(CSV_SEPARATOR_SETTING), + config.get(CSV_QUOTE_VALUES_SETTING), + ]); const [separator, quoteValues] = configs; return { separator, quoteValues }; }; diff --git a/x-pack/plugins/reporting/server/routes/generation.test.ts b/x-pack/plugins/reporting/server/routes/generation.test.ts index eb75109c704c7..f9b3e5446cfce 100644 --- a/x-pack/plugins/reporting/server/routes/generation.test.ts +++ b/x-pack/plugins/reporting/server/routes/generation.test.ts @@ -6,8 +6,7 @@ import supertest from 'supertest'; import { UnwrapPromise } from '@kbn/utility-types'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { setupServer } from 'src/core/server/saved_objects/routes/integration_tests/test_utils'; +import { setupServer } from 'src/core/server/test_utils'; import { registerJobGenerationRoutes } from './generation'; import { createMockReportingCore } from '../test_helpers'; import { ReportingCore } from '..'; diff --git a/x-pack/plugins/reporting/server/routes/jobs.test.ts b/x-pack/plugins/reporting/server/routes/jobs.test.ts index d13b3e72ca8e7..22d60d62d5fdb 100644 --- a/x-pack/plugins/reporting/server/routes/jobs.test.ts +++ b/x-pack/plugins/reporting/server/routes/jobs.test.ts @@ -6,8 +6,7 @@ import { UnwrapPromise } from '@kbn/utility-types'; import { of } from 'rxjs'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { setupServer } from 'src/core/server/saved_objects/routes/integration_tests/test_utils'; +import { setupServer } from 'src/core/server/test_utils'; import supertest from 'supertest'; import { ReportingCore } from '..'; import { ReportingInternalSetup } from '../core'; diff --git a/x-pack/plugins/security/public/account_management/account_management_app.ts b/x-pack/plugins/security/public/account_management/account_management_app.ts index 41567a04fe030..0bb7785259c0e 100644 --- a/x-pack/plugins/security/public/account_management/account_management_app.ts +++ b/x-pack/plugins/security/public/account_management/account_management_app.ts @@ -5,7 +5,12 @@ */ import { i18n } from '@kbn/i18n'; -import { StartServicesAccessor, ApplicationSetup, AppMountParameters } from 'src/core/public'; +import { + ApplicationSetup, + AppMountParameters, + AppNavLinkStatus, + StartServicesAccessor, +} from '../../../../../src/core/public'; import { AuthenticationServiceSetup } from '../authentication'; interface CreateDeps { @@ -23,8 +28,7 @@ export const accountManagementApp = Object.freeze({ application.register({ id: this.id, title, - // TODO: switch to proper enum once https://github.com/elastic/kibana/issues/58327 is resolved. - navLinkStatus: 3, + navLinkStatus: AppNavLinkStatus.hidden, appRoute: '/security/account', async mount({ element }: AppMountParameters) { const [ diff --git a/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.scss b/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.scss index 6784052ef4337..344cde9c7825c 100644 --- a/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.scss +++ b/x-pack/plugins/security/public/authentication/login/components/login_form/login_form.scss @@ -23,9 +23,10 @@ } &:focus { + @include euiFocusRing; + border-color: transparent; border-radius: $euiBorderRadius; - @include euiFocusRing; .secLoginCard__title { text-decoration: underline; diff --git a/x-pack/plugins/security/public/management/roles/__fixtures__/kibana_privileges.ts b/x-pack/plugins/security/public/management/roles/__fixtures__/kibana_privileges.ts index 98110a83103aa..6821c163d817d 100644 --- a/x-pack/plugins/security/public/management/roles/__fixtures__/kibana_privileges.ts +++ b/x-pack/plugins/security/public/management/roles/__fixtures__/kibana_privileges.ts @@ -11,13 +11,15 @@ import { Feature } from '../../../../../features/public'; import { KibanaPrivileges } from '../model'; import { SecurityLicenseFeatures } from '../../..'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { featuresPluginMock } from '../../../../../features/server/mocks'; + export const createRawKibanaPrivileges = ( features: Feature[], { allowSubFeaturePrivileges = true } = {} ) => { - const featuresService = { - getFeatures: () => features, - }; + const featuresService = featuresPluginMock.createSetup(); + featuresService.getFeatures.mockReturnValue(features); const licensingService = { getFeatures: () => ({ allowSubFeaturePrivileges } as SecurityLicenseFeatures), diff --git a/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.test.tsx b/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.test.tsx index afb8b6ec5dbe0..43387d913e6fc 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.test.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.test.tsx @@ -163,7 +163,12 @@ function getProps({ const { http, docLinks, notifications } = coreMock.createStart(); http.get.mockImplementation(async (path: any) => { if (path === '/api/spaces/space') { - return buildSpaces(); + if (spacesEnabled) { + return buildSpaces(); + } + + const notFoundError = { response: { status: 404 } }; + throw notFoundError; } }); @@ -181,7 +186,6 @@ function getProps({ notifications, docLinks: new DocumentationLinksService(docLinks), fatalErrors, - spacesEnabled, uiCapabilities: buildUICapabilities(canManageSpaces), history: (scopedHistoryMock.create() as unknown) as ScopedHistory, }; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.tsx b/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.tsx index 77f4455d813c6..15888733ec424 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/edit_role_page.tsx @@ -80,7 +80,6 @@ interface Props { docLinks: DocumentationLinksService; http: HttpStart; license: SecurityLicense; - spacesEnabled: boolean; uiCapabilities: Capabilities; notifications: NotificationsStart; fatalErrors: FatalErrorsSetup; @@ -225,14 +224,21 @@ function useRole( return [role, setRole] as [Role | null, typeof setRole]; } -function useSpaces(http: HttpStart, fatalErrors: FatalErrorsSetup, spacesEnabled: boolean) { - const [spaces, setSpaces] = useState(null); +function useSpaces(http: HttpStart, fatalErrors: FatalErrorsSetup) { + const [spaces, setSpaces] = useState<{ enabled: boolean; list: Space[] } | null>(null); useEffect(() => { - (spacesEnabled ? http.get('/api/spaces/space') : Promise.resolve([])).then( - (fetchedSpaces) => setSpaces(fetchedSpaces), - (err) => fatalErrors.add(err) + http.get('/api/spaces/space').then( + (fetchedSpaces) => setSpaces({ enabled: true, list: fetchedSpaces }), + (err: IHttpFetchError) => { + // Spaces plugin can be disabled and hence this endpoint can be unavailable. + if (err.response?.status === 404) { + setSpaces({ enabled: false, list: [] }); + } else { + fatalErrors.add(err); + } + } ); - }, [http, fatalErrors, spacesEnabled]); + }, [http, fatalErrors]); return spaces; } @@ -278,7 +284,6 @@ export const EditRolePage: FunctionComponent = ({ roleName, action, fatalErrors, - spacesEnabled, license, docLinks, uiCapabilities, @@ -295,7 +300,7 @@ export const EditRolePage: FunctionComponent = ({ const runAsUsers = useRunAsUsers(userAPIClient, fatalErrors); const indexPatternsTitles = useIndexPatternsTitles(indexPatterns, fatalErrors, notifications); const privileges = usePrivileges(privilegesAPIClient, fatalErrors); - const spaces = useSpaces(http, fatalErrors, spacesEnabled); + const spaces = useSpaces(http, fatalErrors); const features = useFeatures(getFeatures, fatalErrors); const [role, setRole] = useRole( rolesAPIClient, @@ -434,8 +439,8 @@ export const EditRolePage: FunctionComponent = ({ = ({ setFormError(null); try { - await rolesAPIClient.saveRole({ role, spacesEnabled }); + await rolesAPIClient.saveRole({ role, spacesEnabled: spaces.enabled }); } catch (error) { notifications.toasts.addDanger(get(error, 'data.message')); return; @@ -554,7 +559,7 @@ export const EditRolePage: FunctionComponent = ({ backToRoleList(); }; - const description = spacesEnabled ? ( + const description = spaces.enabled ? ( (), + getFeatureUsageService: jest + .fn() + .mockReturnValue(securityFeatureUsageServiceMock.createStartContract()), }; } @@ -1451,6 +1455,9 @@ describe('Authenticator', () => { ); expect(mockSessionStorage.set).not.toHaveBeenCalled(); + expect( + mockOptions.getFeatureUsageService().recordPreAccessAgreementUsage + ).not.toHaveBeenCalled(); }); it('fails if cannot retrieve user session', async () => { @@ -1463,6 +1470,9 @@ describe('Authenticator', () => { ); expect(mockSessionStorage.set).not.toHaveBeenCalled(); + expect( + mockOptions.getFeatureUsageService().recordPreAccessAgreementUsage + ).not.toHaveBeenCalled(); }); it('fails if license doesn allow access agreement acknowledgement', async () => { @@ -1477,6 +1487,9 @@ describe('Authenticator', () => { ); expect(mockSessionStorage.set).not.toHaveBeenCalled(); + expect( + mockOptions.getFeatureUsageService().recordPreAccessAgreementUsage + ).not.toHaveBeenCalled(); }); it('properly acknowledges access agreement for the authenticated user', async () => { @@ -1493,6 +1506,10 @@ describe('Authenticator', () => { type: 'basic', name: 'basic1', }); + + expect( + mockOptions.getFeatureUsageService().recordPreAccessAgreementUsage + ).toHaveBeenCalledTimes(1); }); }); }); diff --git a/x-pack/plugins/security/server/authentication/authenticator.ts b/x-pack/plugins/security/server/authentication/authenticator.ts index 98342a8494e38..ac5c2a72b9667 100644 --- a/x-pack/plugins/security/server/authentication/authenticator.ts +++ b/x-pack/plugins/security/server/authentication/authenticator.ts @@ -38,6 +38,7 @@ import { DeauthenticationResult } from './deauthentication_result'; import { Tokens } from './tokens'; import { canRedirectRequest } from './can_redirect_request'; import { HTTPAuthorizationHeader } from './http_authentication'; +import { SecurityFeatureUsageServiceStart } from '../feature_usage'; /** * The shape of the session that is actually stored in the cookie. @@ -94,6 +95,7 @@ export interface ProviderLoginAttempt { export interface AuthenticatorOptions { auditLogger: SecurityAuditLogger; + getFeatureUsageService: () => SecurityFeatureUsageServiceStart; getCurrentUser: (request: KibanaRequest) => AuthenticatedUser | null; config: Pick; basePath: HttpServiceSetup['basePath']; @@ -502,6 +504,8 @@ export class Authenticator { currentUser.username, existingSession.provider ); + + this.options.getFeatureUsageService().recordPreAccessAgreementUsage(); } /** diff --git a/x-pack/plugins/security/server/authentication/index.test.ts b/x-pack/plugins/security/server/authentication/index.test.ts index 1c1e0ed781f18..c7323509c00d6 100644 --- a/x-pack/plugins/security/server/authentication/index.test.ts +++ b/x-pack/plugins/security/server/authentication/index.test.ts @@ -42,6 +42,8 @@ import { } from './api_keys'; import { SecurityLicense } from '../../common/licensing'; import { SecurityAuditLogger } from '../audit'; +import { SecurityFeatureUsageServiceStart } from '../feature_usage'; +import { securityFeatureUsageServiceMock } from '../feature_usage/index.mock'; describe('setupAuthentication()', () => { let mockSetupAuthenticationParams: { @@ -51,6 +53,7 @@ describe('setupAuthentication()', () => { http: jest.Mocked; clusterClient: jest.Mocked; license: jest.Mocked; + getFeatureUsageService: () => jest.Mocked; }; let mockScopedClusterClient: jest.Mocked>; beforeEach(() => { @@ -69,6 +72,9 @@ describe('setupAuthentication()', () => { clusterClient: elasticsearchServiceMock.createClusterClient(), license: licenseMock.create(), loggers: loggingServiceMock.create(), + getFeatureUsageService: jest + .fn() + .mockReturnValue(securityFeatureUsageServiceMock.createStartContract()), }; mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); diff --git a/x-pack/plugins/security/server/authentication/index.ts b/x-pack/plugins/security/server/authentication/index.ts index 779b852195b02..ec48c727a5739 100644 --- a/x-pack/plugins/security/server/authentication/index.ts +++ b/x-pack/plugins/security/server/authentication/index.ts @@ -17,6 +17,7 @@ import { ConfigType } from '../config'; import { getErrorStatusCode } from '../errors'; import { Authenticator, ProviderSession } from './authenticator'; import { APIKeys, CreateAPIKeyParams, InvalidateAPIKeyParams } from './api_keys'; +import { SecurityFeatureUsageServiceStart } from '../feature_usage'; export { canRedirectRequest } from './can_redirect_request'; export { Authenticator, ProviderLoginAttempt } from './authenticator'; @@ -37,6 +38,7 @@ export { interface SetupAuthenticationParams { auditLogger: SecurityAuditLogger; + getFeatureUsageService: () => SecurityFeatureUsageServiceStart; http: CoreSetup['http']; clusterClient: IClusterClient; config: ConfigType; @@ -48,6 +50,7 @@ export type Authentication = UnwrapPromise { diff --git a/x-pack/plugins/security/server/authorization/app_authorization.ts b/x-pack/plugins/security/server/authorization/app_authorization.ts index aead8cb07897c..1036997ca821d 100644 --- a/x-pack/plugins/security/server/authorization/app_authorization.ts +++ b/x-pack/plugins/security/server/authorization/app_authorization.ts @@ -4,13 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { CoreSetup, Logger } from '../../../../../src/core/server'; -import { FeaturesService } from '../plugin'; -import { Authorization } from '.'; +import { HttpServiceSetup, Logger } from '../../../../../src/core/server'; +import { PluginSetupContract as FeaturesPluginSetup } from '../../../features/server'; +import { AuthorizationServiceSetup } from '.'; class ProtectedApplications { private applications: Set | null = null; - constructor(private readonly featuresService: FeaturesService) {} + constructor(private readonly featuresService: FeaturesPluginSetup) {} public shouldProtect(appId: string) { // Currently, once we get the list of features we essentially "lock" additional @@ -30,14 +30,14 @@ class ProtectedApplications { } export function initAppAuthorization( - http: CoreSetup['http'], + http: HttpServiceSetup, { actions, checkPrivilegesDynamicallyWithRequest, mode, - }: Pick, + }: Pick, logger: Logger, - featuresService: FeaturesService + featuresService: FeaturesPluginSetup ) { const protectedApplications = new ProtectedApplications(featuresService); diff --git a/x-pack/plugins/security/server/authorization/authorization_service.test.ts b/x-pack/plugins/security/server/authorization/authorization_service.test.ts new file mode 100644 index 0000000000000..978c985cfe820 --- /dev/null +++ b/x-pack/plugins/security/server/authorization/authorization_service.test.ts @@ -0,0 +1,263 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + mockAuthorizationModeFactory, + mockCheckPrivilegesDynamicallyWithRequestFactory, + mockCheckPrivilegesWithRequestFactory, + mockCheckSavedObjectsPrivilegesWithRequestFactory, + mockPrivilegesFactory, + mockRegisterPrivilegesWithCluster, +} from './service.test.mocks'; + +import { BehaviorSubject } from 'rxjs'; +import { CoreStatus, ServiceStatusLevels } from '../../../../../src/core/server'; +import { checkPrivilegesWithRequestFactory } from './check_privileges'; +import { checkPrivilegesDynamicallyWithRequestFactory } from './check_privileges_dynamically'; +import { checkSavedObjectsPrivilegesWithRequestFactory } from './check_saved_objects_privileges'; +import { authorizationModeFactory } from './mode'; +import { privilegesFactory } from './privileges'; +import { AuthorizationService } from '.'; + +import { + coreMock, + elasticsearchServiceMock, + loggingServiceMock, +} from '../../../../../src/core/server/mocks'; +import { featuresPluginMock } from '../../../features/server/mocks'; +import { licenseMock } from '../../common/licensing/index.mock'; +import { SecurityLicense, SecurityLicenseFeatures } from '../../common/licensing'; +import { nextTick } from 'test_utils/enzyme_helpers'; + +const kibanaIndexName = '.a-kibana-index'; +const application = `kibana-${kibanaIndexName}`; +const mockCheckPrivilegesWithRequest = Symbol(); +const mockCheckPrivilegesDynamicallyWithRequest = Symbol(); +const mockCheckSavedObjectsPrivilegesWithRequest = Symbol(); +const mockPrivilegesService = Symbol(); +const mockAuthorizationMode = Symbol(); +beforeEach(() => { + mockCheckPrivilegesWithRequestFactory.mockReturnValue(mockCheckPrivilegesWithRequest); + mockCheckPrivilegesDynamicallyWithRequestFactory.mockReturnValue( + mockCheckPrivilegesDynamicallyWithRequest + ); + mockCheckSavedObjectsPrivilegesWithRequestFactory.mockReturnValue( + mockCheckSavedObjectsPrivilegesWithRequest + ); + mockPrivilegesFactory.mockReturnValue(mockPrivilegesService); + mockAuthorizationModeFactory.mockReturnValue(mockAuthorizationMode); +}); + +afterEach(() => { + mockRegisterPrivilegesWithCluster.mockClear(); +}); + +it(`#setup returns exposed services`, () => { + const mockClusterClient = elasticsearchServiceMock.createClusterClient(); + const mockGetSpacesService = jest + .fn() + .mockReturnValue({ getSpaceId: jest.fn(), namespaceToSpaceId: jest.fn() }); + const mockFeaturesSetup = featuresPluginMock.createSetup(); + const mockLicense = licenseMock.create(); + const mockCoreSetup = coreMock.createSetup(); + + const authorizationService = new AuthorizationService(); + const authz = authorizationService.setup({ + http: mockCoreSetup.http, + capabilities: mockCoreSetup.capabilities, + status: mockCoreSetup.status, + clusterClient: mockClusterClient, + license: mockLicense, + loggers: loggingServiceMock.create(), + kibanaIndexName, + packageVersion: 'some-version', + features: mockFeaturesSetup, + getSpacesService: mockGetSpacesService, + }); + + expect(authz.actions.version).toBe('version:some-version'); + expect(authz.applicationName).toBe(application); + + expect(authz.checkPrivilegesWithRequest).toBe(mockCheckPrivilegesWithRequest); + expect(checkPrivilegesWithRequestFactory).toHaveBeenCalledWith( + authz.actions, + mockClusterClient, + authz.applicationName + ); + + expect(authz.checkPrivilegesDynamicallyWithRequest).toBe( + mockCheckPrivilegesDynamicallyWithRequest + ); + expect(checkPrivilegesDynamicallyWithRequestFactory).toHaveBeenCalledWith( + mockCheckPrivilegesWithRequest, + mockGetSpacesService + ); + + expect(authz.checkSavedObjectsPrivilegesWithRequest).toBe( + mockCheckSavedObjectsPrivilegesWithRequest + ); + expect(checkSavedObjectsPrivilegesWithRequestFactory).toHaveBeenCalledWith( + mockCheckPrivilegesWithRequest, + mockGetSpacesService + ); + + expect(authz.privileges).toBe(mockPrivilegesService); + expect(privilegesFactory).toHaveBeenCalledWith(authz.actions, mockFeaturesSetup, mockLicense); + + expect(authz.mode).toBe(mockAuthorizationMode); + expect(authorizationModeFactory).toHaveBeenCalledWith(mockLicense); + + expect(mockCoreSetup.capabilities.registerSwitcher).toHaveBeenCalledTimes(1); + expect(mockCoreSetup.capabilities.registerSwitcher).toHaveBeenCalledWith(expect.any(Function)); +}); + +describe('#start', () => { + let statusSubject: BehaviorSubject; + let licenseSubject: BehaviorSubject; + let mockLicense: jest.Mocked; + beforeEach(() => { + const mockClusterClient = elasticsearchServiceMock.createClusterClient(); + + licenseSubject = new BehaviorSubject(({} as unknown) as SecurityLicenseFeatures); + mockLicense = licenseMock.create(); + mockLicense.isEnabled.mockReturnValue(false); + mockLicense.features$ = licenseSubject; + + statusSubject = new BehaviorSubject({ + elasticsearch: { level: ServiceStatusLevels.unavailable, summary: 'Service is NOT working' }, + savedObjects: { level: ServiceStatusLevels.unavailable, summary: 'Service is NOT working' }, + }); + const mockCoreSetup = coreMock.createSetup(); + mockCoreSetup.status.core$ = statusSubject; + + const authorizationService = new AuthorizationService(); + authorizationService.setup({ + http: mockCoreSetup.http, + capabilities: mockCoreSetup.capabilities, + status: mockCoreSetup.status, + clusterClient: mockClusterClient, + license: mockLicense, + loggers: loggingServiceMock.create(), + kibanaIndexName, + packageVersion: 'some-version', + features: featuresPluginMock.createSetup(), + getSpacesService: jest + .fn() + .mockReturnValue({ getSpaceId: jest.fn(), namespaceToSpaceId: jest.fn() }), + }); + + const featuresStart = featuresPluginMock.createStart(); + featuresStart.getFeatures.mockReturnValue([]); + + authorizationService.start({ clusterClient: mockClusterClient, features: featuresStart }); + + // ES and license aren't available yet. + expect(mockRegisterPrivilegesWithCluster).not.toHaveBeenCalled(); + }); + + it('registers cluster privileges', async () => { + // ES is available now, but not license. + statusSubject.next({ + elasticsearch: { level: ServiceStatusLevels.available, summary: 'Service is working' }, + savedObjects: { level: ServiceStatusLevels.unavailable, summary: 'Service is NOT working' }, + }); + expect(mockRegisterPrivilegesWithCluster).not.toHaveBeenCalled(); + + // Both ES and license are available now. + mockLicense.isEnabled.mockReturnValue(true); + licenseSubject.next(({} as unknown) as SecurityLicenseFeatures); + expect(mockRegisterPrivilegesWithCluster).toHaveBeenCalledTimes(1); + + await nextTick(); + + // New changes still trigger privileges re-registration. + licenseSubject.next(({} as unknown) as SecurityLicenseFeatures); + expect(mockRegisterPrivilegesWithCluster).toHaveBeenCalledTimes(2); + }); + + it('schedules retries if fails to register cluster privileges', async () => { + jest.useFakeTimers(); + + mockRegisterPrivilegesWithCluster.mockRejectedValue(new Error('Some error')); + + // Both ES and license are available. + mockLicense.isEnabled.mockReturnValue(true); + statusSubject.next({ + elasticsearch: { level: ServiceStatusLevels.available, summary: 'Service is working' }, + savedObjects: { level: ServiceStatusLevels.unavailable, summary: 'Service is NOT working' }, + }); + expect(mockRegisterPrivilegesWithCluster).toHaveBeenCalledTimes(1); + + // Next retry isn't performed immediately, retry happens only after a timeout. + await nextTick(); + expect(mockRegisterPrivilegesWithCluster).toHaveBeenCalledTimes(1); + jest.advanceTimersByTime(100); + expect(mockRegisterPrivilegesWithCluster).toHaveBeenCalledTimes(2); + + // Delay between consequent retries is increasing. + await nextTick(); + jest.advanceTimersByTime(100); + expect(mockRegisterPrivilegesWithCluster).toHaveBeenCalledTimes(2); + await nextTick(); + jest.advanceTimersByTime(100); + expect(mockRegisterPrivilegesWithCluster).toHaveBeenCalledTimes(3); + + // When call finally succeeds retries aren't scheduled anymore. + mockRegisterPrivilegesWithCluster.mockResolvedValue(undefined); + await nextTick(); + jest.runAllTimers(); + expect(mockRegisterPrivilegesWithCluster).toHaveBeenCalledTimes(4); + await nextTick(); + jest.runAllTimers(); + expect(mockRegisterPrivilegesWithCluster).toHaveBeenCalledTimes(4); + + // New changes still trigger privileges re-registration. + licenseSubject.next(({} as unknown) as SecurityLicenseFeatures); + expect(mockRegisterPrivilegesWithCluster).toHaveBeenCalledTimes(5); + }); +}); + +it('#stop unsubscribes from license and ES updates.', () => { + const mockClusterClient = elasticsearchServiceMock.createClusterClient(); + + const licenseSubject = new BehaviorSubject(({} as unknown) as SecurityLicenseFeatures); + const mockLicense = licenseMock.create(); + mockLicense.isEnabled.mockReturnValue(false); + mockLicense.features$ = licenseSubject; + + const mockCoreSetup = coreMock.createSetup(); + mockCoreSetup.status.core$ = new BehaviorSubject({ + elasticsearch: { level: ServiceStatusLevels.available, summary: 'Service is working' }, + savedObjects: { level: ServiceStatusLevels.available, summary: 'Service is working' }, + }); + + const authorizationService = new AuthorizationService(); + authorizationService.setup({ + http: mockCoreSetup.http, + capabilities: mockCoreSetup.capabilities, + status: mockCoreSetup.status, + clusterClient: mockClusterClient, + license: mockLicense, + loggers: loggingServiceMock.create(), + kibanaIndexName, + packageVersion: 'some-version', + features: featuresPluginMock.createSetup(), + getSpacesService: jest + .fn() + .mockReturnValue({ getSpaceId: jest.fn(), namespaceToSpaceId: jest.fn() }), + }); + + const featuresStart = featuresPluginMock.createStart(); + featuresStart.getFeatures.mockReturnValue([]); + authorizationService.start({ clusterClient: mockClusterClient, features: featuresStart }); + + authorizationService.stop(); + + // After stop we don't register privileges even if all requirements are met. + mockLicense.isEnabled.mockReturnValue(true); + licenseSubject.next(({} as unknown) as SecurityLicenseFeatures); + expect(mockRegisterPrivilegesWithCluster).not.toHaveBeenCalled(); +}); diff --git a/x-pack/plugins/security/server/authorization/authorization_service.ts b/x-pack/plugins/security/server/authorization/authorization_service.ts new file mode 100644 index 0000000000000..989784a1436d2 --- /dev/null +++ b/x-pack/plugins/security/server/authorization/authorization_service.ts @@ -0,0 +1,221 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { combineLatest, BehaviorSubject, Subscription } from 'rxjs'; +import { distinctUntilChanged, filter } from 'rxjs/operators'; +import { UICapabilities } from 'ui/capabilities'; +import { + LoggerFactory, + KibanaRequest, + IClusterClient, + ServiceStatusLevels, + Logger, + StatusServiceSetup, + HttpServiceSetup, + CapabilitiesSetup, +} from '../../../../../src/core/server'; + +import { + PluginSetupContract as FeaturesPluginSetup, + PluginStartContract as FeaturesPluginStart, +} from '../../../features/server'; + +import { SpacesService } from '../plugin'; +import { Actions } from './actions'; +import { CheckPrivilegesWithRequest, checkPrivilegesWithRequestFactory } from './check_privileges'; +import { + CheckPrivilegesDynamicallyWithRequest, + checkPrivilegesDynamicallyWithRequestFactory, +} from './check_privileges_dynamically'; +import { + CheckSavedObjectsPrivilegesWithRequest, + checkSavedObjectsPrivilegesWithRequestFactory, +} from './check_saved_objects_privileges'; +import { AuthorizationMode, authorizationModeFactory } from './mode'; +import { privilegesFactory, PrivilegesService } from './privileges'; +import { initAppAuthorization } from './app_authorization'; +import { initAPIAuthorization } from './api_authorization'; +import { disableUICapabilitiesFactory } from './disable_ui_capabilities'; +import { validateFeaturePrivileges } from './validate_feature_privileges'; +import { validateReservedPrivileges } from './validate_reserved_privileges'; +import { registerPrivilegesWithCluster } from './register_privileges_with_cluster'; +import { APPLICATION_PREFIX } from '../../common/constants'; +import { SecurityLicense } from '../../common/licensing'; + +export { Actions } from './actions'; +export { CheckSavedObjectsPrivileges } from './check_saved_objects_privileges'; +export { featurePrivilegeIterator } from './privileges'; + +interface AuthorizationServiceSetupParams { + packageVersion: string; + http: HttpServiceSetup; + status: StatusServiceSetup; + capabilities: CapabilitiesSetup; + clusterClient: IClusterClient; + license: SecurityLicense; + loggers: LoggerFactory; + features: FeaturesPluginSetup; + kibanaIndexName: string; + getSpacesService(): SpacesService | undefined; +} + +interface AuthorizationServiceStartParams { + features: FeaturesPluginStart; + clusterClient: IClusterClient; +} + +export interface AuthorizationServiceSetup { + actions: Actions; + checkPrivilegesWithRequest: CheckPrivilegesWithRequest; + checkPrivilegesDynamicallyWithRequest: CheckPrivilegesDynamicallyWithRequest; + checkSavedObjectsPrivilegesWithRequest: CheckSavedObjectsPrivilegesWithRequest; + applicationName: string; + mode: AuthorizationMode; + privileges: PrivilegesService; +} + +export class AuthorizationService { + private logger!: Logger; + private license!: SecurityLicense; + private status!: StatusServiceSetup; + private applicationName!: string; + private privileges!: PrivilegesService; + + private statusSubscription?: Subscription; + + setup({ + http, + capabilities, + status, + packageVersion, + clusterClient, + license, + loggers, + features, + kibanaIndexName, + getSpacesService, + }: AuthorizationServiceSetupParams): AuthorizationServiceSetup { + this.logger = loggers.get('authorization'); + this.license = license; + this.status = status; + this.applicationName = `${APPLICATION_PREFIX}${kibanaIndexName}`; + + const mode = authorizationModeFactory(license); + const actions = new Actions(packageVersion); + this.privileges = privilegesFactory(actions, features, license); + + const checkPrivilegesWithRequest = checkPrivilegesWithRequestFactory( + actions, + clusterClient, + this.applicationName + ); + + const authz = { + actions, + applicationName: this.applicationName, + mode, + privileges: this.privileges, + checkPrivilegesWithRequest, + checkPrivilegesDynamicallyWithRequest: checkPrivilegesDynamicallyWithRequestFactory( + checkPrivilegesWithRequest, + getSpacesService + ), + checkSavedObjectsPrivilegesWithRequest: checkSavedObjectsPrivilegesWithRequestFactory( + checkPrivilegesWithRequest, + getSpacesService + ), + }; + + capabilities.registerSwitcher( + async (request: KibanaRequest, uiCapabilities: UICapabilities) => { + // If we have a license which doesn't enable security, or we're a legacy user we shouldn't + // disable any ui capabilities + if (!mode.useRbacForRequest(request)) { + return uiCapabilities; + } + + const disableUICapabilities = disableUICapabilitiesFactory( + request, + features.getFeatures(), + this.logger, + authz + ); + + if (!request.auth.isAuthenticated) { + return disableUICapabilities.all(uiCapabilities); + } + + return await disableUICapabilities.usingPrivileges(uiCapabilities); + } + ); + + initAPIAuthorization(http, authz, loggers.get('api-authorization')); + initAppAuthorization(http, authz, loggers.get('app-authorization'), features); + + return authz; + } + + start({ clusterClient, features }: AuthorizationServiceStartParams) { + const allFeatures = features.getFeatures(); + validateFeaturePrivileges(allFeatures); + validateReservedPrivileges(allFeatures); + + this.registerPrivileges(clusterClient); + } + + stop() { + if (this.statusSubscription !== undefined) { + this.statusSubscription.unsubscribe(); + this.statusSubscription = undefined; + } + } + + private registerPrivileges(clusterClient: IClusterClient) { + const RETRY_SCALE_DURATION = 100; + const RETRY_TIMEOUT_MAX = 10000; + const retries$ = new BehaviorSubject(0); + let retryTimeout: NodeJS.Timeout; + + // Register cluster privileges once Elasticsearch is available and Security plugin is enabled. + this.statusSubscription = combineLatest([ + this.status.core$, + this.license.features$, + retries$.asObservable().pipe( + // We shouldn't emit new value if retry counter is reset. This comparator isn't called for + // the initial value. + distinctUntilChanged((prev, curr) => prev === curr || curr === 0) + ), + ]) + .pipe( + filter( + ([status]) => + this.license.isEnabled() && status.elasticsearch.level === ServiceStatusLevels.available + ) + ) + .subscribe(async () => { + // If status or license change occurred before retry timeout we should cancel it. + if (retryTimeout) { + clearTimeout(retryTimeout); + } + + try { + await registerPrivilegesWithCluster( + this.logger, + this.privileges, + this.applicationName, + clusterClient + ); + retries$.next(0); + } catch (err) { + const retriesElapsed = retries$.getValue() + 1; + retryTimeout = setTimeout( + () => retries$.next(retriesElapsed), + Math.min(retriesElapsed * RETRY_SCALE_DURATION, RETRY_TIMEOUT_MAX) + ); + } + }); + } +} diff --git a/x-pack/plugins/security/server/authorization/disable_ui_capabilities.ts b/x-pack/plugins/security/server/authorization/disable_ui_capabilities.ts index 72937c15756ac..183ad9169a123 100644 --- a/x-pack/plugins/security/server/authorization/disable_ui_capabilities.ts +++ b/x-pack/plugins/security/server/authorization/disable_ui_capabilities.ts @@ -10,13 +10,13 @@ import { KibanaRequest, Logger } from '../../../../../src/core/server'; import { Feature } from '../../../features/server'; import { CheckPrivilegesResponse } from './check_privileges'; -import { Authorization } from './index'; +import { AuthorizationServiceSetup } from '.'; export function disableUICapabilitiesFactory( request: KibanaRequest, features: Feature[], logger: Logger, - authz: Authorization + authz: AuthorizationServiceSetup ) { const featureNavLinkIds = features .map((feature) => feature.navLinkId) diff --git a/x-pack/plugins/security/server/authorization/index.test.ts b/x-pack/plugins/security/server/authorization/index.test.ts deleted file mode 100644 index 3252053454764..0000000000000 --- a/x-pack/plugins/security/server/authorization/index.test.ts +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { - mockAuthorizationModeFactory, - mockCheckPrivilegesDynamicallyWithRequestFactory, - mockCheckPrivilegesWithRequestFactory, - mockCheckSavedObjectsPrivilegesWithRequestFactory, - mockPrivilegesFactory, -} from './service.test.mocks'; - -import { checkPrivilegesWithRequestFactory } from './check_privileges'; -import { checkPrivilegesDynamicallyWithRequestFactory } from './check_privileges_dynamically'; -import { checkSavedObjectsPrivilegesWithRequestFactory } from './check_saved_objects_privileges'; -import { authorizationModeFactory } from './mode'; -import { privilegesFactory } from './privileges'; -import { setupAuthorization } from '.'; - -import { - coreMock, - elasticsearchServiceMock, - loggingServiceMock, -} from '../../../../../src/core/server/mocks'; -import { licenseMock } from '../../common/licensing/index.mock'; - -test(`returns exposed services`, () => { - const kibanaIndexName = '.a-kibana-index'; - const application = `kibana-${kibanaIndexName}`; - - const mockCheckPrivilegesWithRequest = Symbol(); - mockCheckPrivilegesWithRequestFactory.mockReturnValue(mockCheckPrivilegesWithRequest); - - const mockCheckPrivilegesDynamicallyWithRequest = Symbol(); - mockCheckPrivilegesDynamicallyWithRequestFactory.mockReturnValue( - mockCheckPrivilegesDynamicallyWithRequest - ); - - const mockCheckSavedObjectsPrivilegesWithRequest = Symbol(); - mockCheckSavedObjectsPrivilegesWithRequestFactory.mockReturnValue( - mockCheckSavedObjectsPrivilegesWithRequest - ); - - const mockPrivilegesService = Symbol(); - mockPrivilegesFactory.mockReturnValue(mockPrivilegesService); - const mockAuthorizationMode = Symbol(); - mockAuthorizationModeFactory.mockReturnValue(mockAuthorizationMode); - - const mockClusterClient = elasticsearchServiceMock.createClusterClient(); - const mockGetSpacesService = jest - .fn() - .mockReturnValue({ getSpaceId: jest.fn(), namespaceToSpaceId: jest.fn() }); - const mockFeaturesService = { getFeatures: () => [] }; - const mockLicense = licenseMock.create(); - - const authz = setupAuthorization({ - http: coreMock.createSetup().http, - clusterClient: mockClusterClient, - license: mockLicense, - loggers: loggingServiceMock.create(), - kibanaIndexName, - packageVersion: 'some-version', - featuresService: mockFeaturesService, - getSpacesService: mockGetSpacesService, - }); - - expect(authz.actions.version).toBe('version:some-version'); - expect(authz.applicationName).toBe(application); - - expect(authz.checkPrivilegesWithRequest).toBe(mockCheckPrivilegesWithRequest); - expect(checkPrivilegesWithRequestFactory).toHaveBeenCalledWith( - authz.actions, - mockClusterClient, - authz.applicationName - ); - - expect(authz.checkPrivilegesDynamicallyWithRequest).toBe( - mockCheckPrivilegesDynamicallyWithRequest - ); - expect(checkPrivilegesDynamicallyWithRequestFactory).toHaveBeenCalledWith( - mockCheckPrivilegesWithRequest, - mockGetSpacesService - ); - - expect(authz.checkSavedObjectsPrivilegesWithRequest).toBe( - mockCheckSavedObjectsPrivilegesWithRequest - ); - expect(checkSavedObjectsPrivilegesWithRequestFactory).toHaveBeenCalledWith( - mockCheckPrivilegesWithRequest, - mockGetSpacesService - ); - - expect(authz.privileges).toBe(mockPrivilegesService); - expect(privilegesFactory).toHaveBeenCalledWith(authz.actions, mockFeaturesService, mockLicense); - - expect(authz.mode).toBe(mockAuthorizationMode); - expect(authorizationModeFactory).toHaveBeenCalledWith(mockLicense); -}); diff --git a/x-pack/plugins/security/server/authorization/index.ts b/x-pack/plugins/security/server/authorization/index.ts index cf970a561b93f..d5c1323354f86 100644 --- a/x-pack/plugins/security/server/authorization/index.ts +++ b/x-pack/plugins/security/server/authorization/index.ts @@ -4,134 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UICapabilities } from 'ui/capabilities'; -import { - CoreSetup, - LoggerFactory, - KibanaRequest, - IClusterClient, -} from '../../../../../src/core/server'; - -import { FeaturesService, SpacesService } from '../plugin'; -import { Actions } from './actions'; -import { CheckPrivilegesWithRequest, checkPrivilegesWithRequestFactory } from './check_privileges'; -import { - CheckPrivilegesDynamicallyWithRequest, - checkPrivilegesDynamicallyWithRequestFactory, -} from './check_privileges_dynamically'; -import { - CheckSavedObjectsPrivilegesWithRequest, - checkSavedObjectsPrivilegesWithRequestFactory, -} from './check_saved_objects_privileges'; -import { AuthorizationMode, authorizationModeFactory } from './mode'; -import { privilegesFactory, PrivilegesService } from './privileges'; -import { initAppAuthorization } from './app_authorization'; -import { initAPIAuthorization } from './api_authorization'; -import { disableUICapabilitiesFactory } from './disable_ui_capabilities'; -import { validateFeaturePrivileges } from './validate_feature_privileges'; -import { validateReservedPrivileges } from './validate_reserved_privileges'; -import { registerPrivilegesWithCluster } from './register_privileges_with_cluster'; -import { APPLICATION_PREFIX } from '../../common/constants'; -import { SecurityLicense } from '../../common/licensing'; - export { Actions } from './actions'; +export { AuthorizationService, AuthorizationServiceSetup } from './authorization_service'; export { CheckSavedObjectsPrivileges } from './check_saved_objects_privileges'; export { featurePrivilegeIterator } from './privileges'; - -interface SetupAuthorizationParams { - packageVersion: string; - http: CoreSetup['http']; - clusterClient: IClusterClient; - license: SecurityLicense; - loggers: LoggerFactory; - featuresService: FeaturesService; - kibanaIndexName: string; - getSpacesService(): SpacesService | undefined; -} - -export interface Authorization { - actions: Actions; - checkPrivilegesWithRequest: CheckPrivilegesWithRequest; - checkPrivilegesDynamicallyWithRequest: CheckPrivilegesDynamicallyWithRequest; - checkSavedObjectsPrivilegesWithRequest: CheckSavedObjectsPrivilegesWithRequest; - applicationName: string; - mode: AuthorizationMode; - privileges: PrivilegesService; - disableUnauthorizedCapabilities: ( - request: KibanaRequest, - capabilities: UICapabilities - ) => Promise; - registerPrivilegesWithCluster: () => Promise; -} - -export function setupAuthorization({ - http, - packageVersion, - clusterClient, - license, - loggers, - featuresService, - kibanaIndexName, - getSpacesService, -}: SetupAuthorizationParams): Authorization { - const actions = new Actions(packageVersion); - const mode = authorizationModeFactory(license); - const applicationName = `${APPLICATION_PREFIX}${kibanaIndexName}`; - const checkPrivilegesWithRequest = checkPrivilegesWithRequestFactory( - actions, - clusterClient, - applicationName - ); - const privileges = privilegesFactory(actions, featuresService, license); - const logger = loggers.get('authorization'); - - const authz = { - actions, - applicationName, - checkPrivilegesWithRequest, - checkPrivilegesDynamicallyWithRequest: checkPrivilegesDynamicallyWithRequestFactory( - checkPrivilegesWithRequest, - getSpacesService - ), - checkSavedObjectsPrivilegesWithRequest: checkSavedObjectsPrivilegesWithRequestFactory( - checkPrivilegesWithRequest, - getSpacesService - ), - mode, - privileges, - - async disableUnauthorizedCapabilities(request: KibanaRequest, capabilities: UICapabilities) { - // If we have a license which doesn't enable security, or we're a legacy user we shouldn't - // disable any ui capabilities - if (!mode.useRbacForRequest(request)) { - return capabilities; - } - - const disableUICapabilities = disableUICapabilitiesFactory( - request, - featuresService.getFeatures(), - logger, - authz - ); - - if (!request.auth.isAuthenticated) { - return disableUICapabilities.all(capabilities); - } - - return await disableUICapabilities.usingPrivileges(capabilities); - }, - - registerPrivilegesWithCluster: async () => { - const features = featuresService.getFeatures(); - validateFeaturePrivileges(features); - validateReservedPrivileges(features); - - await registerPrivilegesWithCluster(logger, privileges, applicationName, clusterClient); - }, - }; - - initAPIAuthorization(http, authz, loggers.get('api-authorization')); - initAppAuthorization(http, authz, loggers.get('app-authorization'), featuresService); - - return authz; -} diff --git a/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts b/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts index b023c12d35b79..06f064a379fe6 100644 --- a/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts +++ b/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts @@ -8,6 +8,8 @@ import { Feature } from '../../../../features/server'; import { Actions } from '../actions'; import { privilegesFactory } from './privileges'; +import { featuresPluginMock } from '../../../../features/server/mocks'; + const actions = new Actions('1.0.0-zeta1'); describe('features', () => { @@ -42,7 +44,9 @@ describe('features', () => { }), ]; - const mockFeaturesService = { getFeatures: jest.fn().mockReturnValue(features) }; + const mockFeaturesService = featuresPluginMock.createSetup(); + mockFeaturesService.getFeatures.mockReturnValue(features); + const mockLicenseService = { getFeatures: jest.fn().mockReturnValue({ allowSubFeaturePrivileges: true }), }; diff --git a/x-pack/plugins/security/server/authorization/privileges/privileges.ts b/x-pack/plugins/security/server/authorization/privileges/privileges.ts index f3b2881e79ece..5a15290a7f1a2 100644 --- a/x-pack/plugins/security/server/authorization/privileges/privileges.ts +++ b/x-pack/plugins/security/server/authorization/privileges/privileges.ts @@ -6,11 +6,10 @@ import { uniq } from 'lodash'; import { SecurityLicense } from '../../../common/licensing'; -import { Feature } from '../../../../features/server'; +import { Feature, PluginSetupContract as FeaturesPluginSetup } from '../../../../features/server'; import { RawKibanaPrivileges } from '../../../common/model'; import { Actions } from '../actions'; import { featurePrivilegeBuilderFactory } from './feature_privilege_builder'; -import { FeaturesService } from '../../plugin'; import { featurePrivilegeIterator, subFeaturePrivilegeIterator, @@ -22,7 +21,7 @@ export interface PrivilegesService { export function privilegesFactory( actions: Actions, - featuresService: FeaturesService, + featuresService: FeaturesPluginSetup, licenseService: Pick ) { const featurePrivilegeBuilder = featurePrivilegeBuilderFactory(actions); diff --git a/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.test.ts b/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.test.ts index fff4345c72409..e21203e60b887 100644 --- a/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.test.ts +++ b/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.test.ts @@ -49,7 +49,7 @@ const registerPrivilegesWithClusterTest = ( }); for (const deletedPrivilege of deletedPrivileges) { expect(mockLogger.debug).toHaveBeenCalledWith( - `Deleting Kibana Privilege ${deletedPrivilege} from Elasticearch for ${application}` + `Deleting Kibana Privilege ${deletedPrivilege} from Elasticsearch for ${application}` ); expect(mockClusterClient.callAsInternalUser).toHaveBeenCalledWith( 'shield.deletePrivilege', @@ -82,7 +82,7 @@ const registerPrivilegesWithClusterTest = ( `Registering Kibana Privileges with Elasticsearch for ${application}` ); expect(mockLogger.debug).toHaveBeenCalledWith( - `Kibana Privileges already registered with Elasticearch for ${application}` + `Kibana Privileges already registered with Elasticsearch for ${application}` ); }; }; diff --git a/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts b/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts index 22e7830d20e28..8e54794494a90 100644 --- a/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts +++ b/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts @@ -61,14 +61,14 @@ export async function registerPrivilegesWithCluster( privilege: application, }); if (arePrivilegesEqual(existingPrivileges, expectedPrivileges)) { - logger.debug(`Kibana Privileges already registered with Elasticearch for ${application}`); + logger.debug(`Kibana Privileges already registered with Elasticsearch for ${application}`); return; } const privilegesToDelete = getPrivilegesToDelete(existingPrivileges, expectedPrivileges); for (const privilegeToDelete of privilegesToDelete) { logger.debug( - `Deleting Kibana Privilege ${privilegeToDelete} from Elasticearch for ${application}` + `Deleting Kibana Privilege ${privilegeToDelete} from Elasticsearch for ${application}` ); try { await clusterClient.callAsInternalUser('shield.deletePrivilege', { diff --git a/x-pack/plugins/security/server/authorization/service.test.mocks.ts b/x-pack/plugins/security/server/authorization/service.test.mocks.ts index 5cd2eac20094d..d73adde66a490 100644 --- a/x-pack/plugins/security/server/authorization/service.test.mocks.ts +++ b/x-pack/plugins/security/server/authorization/service.test.mocks.ts @@ -28,3 +28,8 @@ export const mockAuthorizationModeFactory = jest.fn(); jest.mock('./mode', () => ({ authorizationModeFactory: mockAuthorizationModeFactory, })); + +export const mockRegisterPrivilegesWithCluster = jest.fn(); +jest.mock('./register_privileges_with_cluster', () => ({ + registerPrivilegesWithCluster: mockRegisterPrivilegesWithCluster, +})); diff --git a/x-pack/plugins/security/server/feature_usage/feature_usage_service.test.ts b/x-pack/plugins/security/server/feature_usage/feature_usage_service.test.ts new file mode 100644 index 0000000000000..46796fa73ef26 --- /dev/null +++ b/x-pack/plugins/security/server/feature_usage/feature_usage_service.test.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SecurityFeatureUsageService } from './feature_usage_service'; + +describe('#setup', () => { + it('registers all known security features', () => { + const featureUsage = { register: jest.fn() }; + const securityFeatureUsage = new SecurityFeatureUsageService(); + securityFeatureUsage.setup({ featureUsage }); + expect(featureUsage.register).toHaveBeenCalledTimes(2); + expect(featureUsage.register.mock.calls.map((c) => c[0])).toMatchInlineSnapshot(` + Array [ + "Subfeature privileges", + "Pre-access agreement", + ] + `); + }); +}); + +describe('start contract', () => { + it('notifies when sub-feature privileges are in use', () => { + const featureUsage = { notifyUsage: jest.fn(), getLastUsages: jest.fn() }; + const securityFeatureUsage = new SecurityFeatureUsageService(); + const startContract = securityFeatureUsage.start({ featureUsage }); + startContract.recordSubFeaturePrivilegeUsage(); + expect(featureUsage.notifyUsage).toHaveBeenCalledTimes(1); + expect(featureUsage.notifyUsage).toHaveBeenCalledWith('Subfeature privileges'); + }); + + it('notifies when pre-access agreement is used', () => { + const featureUsage = { notifyUsage: jest.fn(), getLastUsages: jest.fn() }; + const securityFeatureUsage = new SecurityFeatureUsageService(); + const startContract = securityFeatureUsage.start({ featureUsage }); + startContract.recordPreAccessAgreementUsage(); + expect(featureUsage.notifyUsage).toHaveBeenCalledTimes(1); + expect(featureUsage.notifyUsage).toHaveBeenCalledWith('Pre-access agreement'); + }); +}); diff --git a/x-pack/plugins/security/server/feature_usage/feature_usage_service.ts b/x-pack/plugins/security/server/feature_usage/feature_usage_service.ts new file mode 100644 index 0000000000000..1bc1e664981bf --- /dev/null +++ b/x-pack/plugins/security/server/feature_usage/feature_usage_service.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { FeatureUsageServiceSetup, FeatureUsageServiceStart } from '../../../licensing/server'; + +interface SetupDeps { + featureUsage: FeatureUsageServiceSetup; +} + +interface StartDeps { + featureUsage: FeatureUsageServiceStart; +} + +export interface SecurityFeatureUsageServiceStart { + recordPreAccessAgreementUsage: () => void; + recordSubFeaturePrivilegeUsage: () => void; +} + +export class SecurityFeatureUsageService { + public setup({ featureUsage }: SetupDeps) { + featureUsage.register('Subfeature privileges', 'gold'); + featureUsage.register('Pre-access agreement', 'gold'); + } + + public start({ featureUsage }: StartDeps): SecurityFeatureUsageServiceStart { + return { + recordPreAccessAgreementUsage() { + featureUsage.notifyUsage('Pre-access agreement'); + }, + recordSubFeaturePrivilegeUsage() { + featureUsage.notifyUsage('Subfeature privileges'); + }, + }; + } +} diff --git a/x-pack/plugins/security/server/feature_usage/index.mock.ts b/x-pack/plugins/security/server/feature_usage/index.mock.ts new file mode 100644 index 0000000000000..6ed42145abd76 --- /dev/null +++ b/x-pack/plugins/security/server/feature_usage/index.mock.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SecurityFeatureUsageServiceStart } from './feature_usage_service'; + +export const securityFeatureUsageServiceMock = { + createStartContract() { + return { + recordPreAccessAgreementUsage: jest.fn(), + recordSubFeaturePrivilegeUsage: jest.fn(), + } as jest.Mocked; + }, +}; diff --git a/x-pack/plugins/security/server/feature_usage/index.ts b/x-pack/plugins/security/server/feature_usage/index.ts new file mode 100644 index 0000000000000..a3e1f35ee3824 --- /dev/null +++ b/x-pack/plugins/security/server/feature_usage/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { + SecurityFeatureUsageService, + SecurityFeatureUsageServiceStart, +} from './feature_usage_service'; diff --git a/x-pack/plugins/security/server/mocks.ts b/x-pack/plugins/security/server/mocks.ts index 72a946d6c5155..c2d99433b0346 100644 --- a/x-pack/plugins/security/server/mocks.ts +++ b/x-pack/plugins/security/server/mocks.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SecurityPluginSetup } from './plugin'; - import { authenticationMock } from './authentication/index.mock'; import { authorizationMock } from './authorization/index.mock'; import { licenseMock } from '../common/licensing/index.mock'; @@ -23,7 +21,6 @@ function createSetupMock() { }, registerSpacesService: jest.fn(), license: licenseMock.create(), - __legacyCompat: {} as SecurityPluginSetup['__legacyCompat'], }; } diff --git a/x-pack/plugins/security/server/plugin.test.ts b/x-pack/plugins/security/server/plugin.test.ts index 3e30ff9447f3e..e01c608e5f306 100644 --- a/x-pack/plugins/security/server/plugin.test.ts +++ b/x-pack/plugins/security/server/plugin.test.ts @@ -41,16 +41,15 @@ describe('Security Plugin', () => { mockClusterClient = elasticsearchServiceMock.createCustomClusterClient(); mockCoreSetup.elasticsearch.legacy.createClient.mockReturnValue(mockClusterClient); - mockDependencies = { licensing: { license$: of({}) } } as PluginSetupDependencies; + mockDependencies = ({ + licensing: { license$: of({}), featureUsage: { register: jest.fn() } }, + } as unknown) as PluginSetupDependencies; }); describe('setup()', () => { it('exposes proper contract', async () => { await expect(plugin.setup(mockCoreSetup, mockDependencies)).resolves.toMatchInlineSnapshot(` Object { - "__legacyCompat": Object { - "registerPrivilegesWithCluster": [Function], - }, "audit": Object { "getLogger": [Function], }, diff --git a/x-pack/plugins/security/server/plugin.ts b/x-pack/plugins/security/server/plugin.ts index bdda0be9b15a7..c8f47aaae7b5d 100644 --- a/x-pack/plugins/security/server/plugin.ts +++ b/x-pack/plugins/security/server/plugin.ts @@ -8,32 +8,35 @@ import { combineLatest } from 'rxjs'; import { first, map } from 'rxjs/operators'; import { TypeOf } from '@kbn/config-schema'; import { + deepFreeze, ICustomClusterClient, CoreSetup, + CoreStart, Logger, PluginInitializerContext, } from '../../../../src/core/server'; -import { deepFreeze } from '../../../../src/core/server'; import { SpacesPluginSetup } from '../../spaces/server'; -import { PluginSetupContract as FeaturesSetupContract } from '../../features/server'; -import { LicensingPluginSetup } from '../../licensing/server'; +import { + PluginSetupContract as FeaturesPluginSetup, + PluginStartContract as FeaturesPluginStart, +} from '../../features/server'; +import { LicensingPluginSetup, LicensingPluginStart } from '../../licensing/server'; import { Authentication, setupAuthentication } from './authentication'; -import { Authorization, setupAuthorization } from './authorization'; +import { AuthorizationService, AuthorizationServiceSetup } from './authorization'; import { ConfigSchema, createConfig } from './config'; import { defineRoutes } from './routes'; import { SecurityLicenseService, SecurityLicense } from '../common/licensing'; import { setupSavedObjects } from './saved_objects'; import { AuditService, SecurityAuditLogger, AuditServiceSetup } from './audit'; import { elasticsearchClientPlugin } from './elasticsearch_client_plugin'; +import { SecurityFeatureUsageService, SecurityFeatureUsageServiceStart } from './feature_usage'; export type SpacesService = Pick< SpacesPluginSetup['spacesService'], 'getSpaceId' | 'namespaceToSpaceId' >; -export type FeaturesService = Pick; - /** * Describes public Security plugin contract returned at the `setup` stage. */ @@ -48,7 +51,7 @@ export interface SecurityPluginSetup { | 'grantAPIKeyAsInternalUser' | 'invalidateAPIKeyAsInternalUser' >; - authz: Pick; + authz: Pick; license: SecurityLicense; audit: Pick; @@ -61,17 +64,18 @@ export interface SecurityPluginSetup { * @param service Spaces service exposed by the Spaces plugin. */ registerSpacesService: (service: SpacesService) => void; - - __legacyCompat: { - registerPrivilegesWithCluster: () => void; - }; } export interface PluginSetupDependencies { - features: FeaturesService; + features: FeaturesPluginSetup; licensing: LicensingPluginSetup; } +export interface PluginStartDependencies { + features: FeaturesPluginStart; + licensing: LicensingPluginStart; +} + /** * Represents Security Plugin instance that will be managed by the Kibana plugin system. */ @@ -80,7 +84,18 @@ export class Plugin { private clusterClient?: ICustomClusterClient; private spacesService?: SpacesService | symbol = Symbol('not accessed'); private securityLicenseService?: SecurityLicenseService; + + private readonly featureUsageService = new SecurityFeatureUsageService(); + private featureUsageServiceStart?: SecurityFeatureUsageServiceStart; + private readonly getFeatureUsageService = () => { + if (!this.featureUsageServiceStart) { + throw new Error(`featureUsageServiceStart is not registered!`); + } + return this.featureUsageServiceStart; + }; + private readonly auditService = new AuditService(this.initializerContext.logger.get('audit')); + private readonly authorizationService = new AuthorizationService(); private readonly getSpacesService = () => { // Changing property value from Symbol to undefined denotes the fact that property was accessed. @@ -95,7 +110,10 @@ export class Plugin { this.logger = this.initializerContext.logger.get(); } - public async setup(core: CoreSetup, { features, licensing }: PluginSetupDependencies) { + public async setup( + core: CoreSetup, + { features, licensing }: PluginSetupDependencies + ) { const [config, legacyConfig] = await combineLatest([ this.initializerContext.config.create>().pipe( map((rawConfig) => @@ -118,11 +136,14 @@ export class Plugin { license$: licensing.license$, }); + this.featureUsageService.setup({ featureUsage: licensing.featureUsage }); + const audit = this.auditService.setup({ license, config: config.audit }); const auditLogger = new SecurityAuditLogger(audit.getLogger()); const authc = await setupAuthentication({ auditLogger, + getFeatureUsageService: this.getFeatureUsageService, http: core.http, clusterClient: this.clusterClient, config, @@ -130,15 +151,17 @@ export class Plugin { loggers: this.initializerContext.logger, }); - const authz = await setupAuthorization({ + const authz = this.authorizationService.setup({ http: core.http, + capabilities: core.capabilities, + status: core.status, clusterClient: this.clusterClient, license, loggers: this.initializerContext.logger, kibanaIndexName: legacyConfig.kibana.index, packageVersion: this.initializerContext.env.packageInfo.version, getSpacesService: this.getSpacesService, - featuresService: features, + features, }); setupSavedObjects({ @@ -148,8 +171,6 @@ export class Plugin { getSpacesService: this.getSpacesService, }); - core.capabilities.registerSwitcher(authz.disableUnauthorizedCapabilities); - defineRoutes({ router: core.http.createRouter(), basePath: core.http.basePath, @@ -160,6 +181,11 @@ export class Plugin { authc, authz, license, + getFeatures: () => + core + .getStartServices() + .then(([, { features: featuresStart }]) => featuresStart.getFeatures()), + getFeatureUsageService: this.getFeatureUsageService, }); return deepFreeze({ @@ -192,15 +218,15 @@ export class Plugin { this.spacesService = service; }, - - __legacyCompat: { - registerPrivilegesWithCluster: async () => await authz.registerPrivilegesWithCluster(), - }, }); } - public start() { + public start(core: CoreStart, { features, licensing }: PluginStartDependencies) { this.logger.debug('Starting plugin'); + this.featureUsageServiceStart = this.featureUsageService.start({ + featureUsage: licensing.featureUsage, + }); + this.authorizationService.start({ features, clusterClient: this.clusterClient! }); } public stop() { @@ -216,7 +242,11 @@ export class Plugin { this.securityLicenseService = undefined; } + if (this.featureUsageServiceStart) { + this.featureUsageServiceStart = undefined; + } this.auditService.stop(); + this.authorizationService.stop(); } private wasSpacesServiceAccessed() { diff --git a/x-pack/plugins/security/server/routes/authorization/roles/put.test.ts b/x-pack/plugins/security/server/routes/authorization/roles/put.test.ts index d7710bf669ce1..bec60fa149bcf 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/put.test.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/put.test.ts @@ -15,6 +15,8 @@ import { httpServerMock, } from '../../../../../../../src/core/server/mocks'; import { routeDefinitionParamsMock } from '../../index.mock'; +import { Feature } from '../../../../../features/server'; +import { securityFeatureUsageServiceMock } from '../../../feature_usage/index.mock'; const application = 'kibana-.kibana'; const privilegeMap = { @@ -47,7 +49,12 @@ interface TestOptions { licenseCheckResult?: LicenseCheck; apiResponses?: Array<() => Promise>; payload?: Record; - asserts: { statusCode: number; result?: Record; apiArguments?: unknown[][] }; + asserts: { + statusCode: number; + result?: Record; + apiArguments?: unknown[][]; + recordSubFeaturePrivilegeUsage?: boolean; + }; } const putRoleTest = ( @@ -71,6 +78,47 @@ const putRoleTest = ( mockScopedClusterClient.callAsCurrentUser.mockImplementationOnce(apiResponse); } + mockRouteDefinitionParams.getFeatureUsageService.mockReturnValue( + securityFeatureUsageServiceMock.createStartContract() + ); + + mockRouteDefinitionParams.getFeatures.mockResolvedValue([ + new Feature({ + id: 'feature_1', + name: 'feature 1', + app: [], + privileges: { + all: { + ui: [], + savedObject: { all: [], read: [] }, + }, + read: { + ui: [], + savedObject: { all: [], read: [] }, + }, + }, + subFeatures: [ + { + name: 'sub feature 1', + privilegeGroups: [ + { + groupType: 'independent', + privileges: [ + { + id: 'sub_feature_privilege_1', + name: 'first sub-feature privilege', + includeIn: 'none', + ui: [], + savedObject: { all: [], read: [] }, + }, + ], + }, + ], + }, + ], + }), + ]); + definePutRolesRoutes(mockRouteDefinitionParams); const [[{ validate }, handler]] = mockRouteDefinitionParams.router.put.mock.calls; @@ -99,6 +147,16 @@ const putRoleTest = ( expect(mockScopedClusterClient.callAsCurrentUser).not.toHaveBeenCalled(); } expect(mockContext.licensing.license.check).toHaveBeenCalledWith('security', 'basic'); + + if (asserts.recordSubFeaturePrivilegeUsage) { + expect( + mockRouteDefinitionParams.getFeatureUsageService().recordSubFeaturePrivilegeUsage + ).toHaveBeenCalledTimes(1); + } else { + expect( + mockRouteDefinitionParams.getFeatureUsageService().recordSubFeaturePrivilegeUsage + ).not.toHaveBeenCalled(); + } }); }; @@ -598,5 +656,131 @@ describe('PUT role', () => { result: undefined, }, }); + + putRoleTest(`notifies when sub-feature privileges are included`, { + name: 'foo-role', + payload: { + kibana: [ + { + spaces: ['*'], + feature: { + feature_1: ['sub_feature_privilege_1'], + }, + }, + ], + }, + apiResponses: [async () => ({}), async () => {}], + asserts: { + recordSubFeaturePrivilegeUsage: true, + apiArguments: [ + ['shield.getRole', { name: 'foo-role', ignore: [404] }], + [ + 'shield.putRole', + { + name: 'foo-role', + body: { + cluster: [], + indices: [], + run_as: [], + applications: [ + { + application: 'kibana-.kibana', + privileges: ['feature_feature_1.sub_feature_privilege_1'], + resources: ['*'], + }, + ], + metadata: undefined, + }, + }, + ], + ], + statusCode: 204, + result: undefined, + }, + }); + + putRoleTest(`does not record sub-feature privilege usage for unknown privileges`, { + name: 'foo-role', + payload: { + kibana: [ + { + spaces: ['*'], + feature: { + feature_1: ['unknown_sub_feature_privilege_1'], + }, + }, + ], + }, + apiResponses: [async () => ({}), async () => {}], + asserts: { + recordSubFeaturePrivilegeUsage: false, + apiArguments: [ + ['shield.getRole', { name: 'foo-role', ignore: [404] }], + [ + 'shield.putRole', + { + name: 'foo-role', + body: { + cluster: [], + indices: [], + run_as: [], + applications: [ + { + application: 'kibana-.kibana', + privileges: ['feature_feature_1.unknown_sub_feature_privilege_1'], + resources: ['*'], + }, + ], + metadata: undefined, + }, + }, + ], + ], + statusCode: 204, + result: undefined, + }, + }); + + putRoleTest(`does not record sub-feature privilege usage for unknown features`, { + name: 'foo-role', + payload: { + kibana: [ + { + spaces: ['*'], + feature: { + unknown_feature: ['sub_feature_privilege_1'], + }, + }, + ], + }, + apiResponses: [async () => ({}), async () => {}], + asserts: { + recordSubFeaturePrivilegeUsage: false, + apiArguments: [ + ['shield.getRole', { name: 'foo-role', ignore: [404] }], + [ + 'shield.putRole', + { + name: 'foo-role', + body: { + cluster: [], + indices: [], + run_as: [], + applications: [ + { + application: 'kibana-.kibana', + privileges: ['feature_unknown_feature.sub_feature_privilege_1'], + resources: ['*'], + }, + ], + metadata: undefined, + }, + }, + ], + ], + statusCode: 204, + result: undefined, + }, + }); }); }); diff --git a/x-pack/plugins/security/server/routes/authorization/roles/put.ts b/x-pack/plugins/security/server/routes/authorization/roles/put.ts index 5db83375afa96..d83cf92bcaa0d 100644 --- a/x-pack/plugins/security/server/routes/authorization/roles/put.ts +++ b/x-pack/plugins/security/server/routes/authorization/roles/put.ts @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { schema } from '@kbn/config-schema'; +import { schema, TypeOf } from '@kbn/config-schema'; +import { Feature } from '../../../../../features/common'; import { RouteDefinitionParams } from '../../index'; import { createLicensedRouteHandler } from '../../licensed_route_handler'; import { wrapIntoCustomErrorResponse } from '../../../errors'; @@ -14,7 +15,37 @@ import { transformPutPayloadToElasticsearchRole, } from './model'; -export function definePutRolesRoutes({ router, authz, clusterClient }: RouteDefinitionParams) { +const roleGrantsSubFeaturePrivileges = ( + features: Feature[], + role: TypeOf> +) => { + if (!role.kibana) { + return false; + } + + const subFeaturePrivileges = new Map( + features.map((feature) => [ + feature.id, + feature.subFeatures.map((sf) => sf.privilegeGroups.map((pg) => pg.privileges)).flat(2), + ]) + ); + + const hasAnySubFeaturePrivileges = role.kibana.some((kibanaPrivilege) => + Object.entries(kibanaPrivilege.feature ?? {}).some(([featureId, privileges]) => { + return !!subFeaturePrivileges.get(featureId)?.some(({ id }) => privileges.includes(id)); + }) + ); + + return hasAnySubFeaturePrivileges; +}; + +export function definePutRolesRoutes({ + router, + authz, + clusterClient, + getFeatures, + getFeatureUsageService, +}: RouteDefinitionParams) { router.put( { path: '/api/security/role/{name}', @@ -46,9 +77,16 @@ export function definePutRolesRoutes({ router, authz, clusterClient }: RouteDefi rawRoles[name] ? rawRoles[name].applications : [] ); - await clusterClient - .asScoped(request) - .callAsCurrentUser('shield.putRole', { name: request.params.name, body }); + const [features] = await Promise.all([ + getFeatures(), + clusterClient + .asScoped(request) + .callAsCurrentUser('shield.putRole', { name: request.params.name, body }), + ]); + + if (roleGrantsSubFeaturePrivileges(features, request.body)) { + getFeatureUsageService().recordSubFeaturePrivilegeUsage(); + } return response.noContent(); } catch (error) { diff --git a/x-pack/plugins/security/server/routes/index.mock.ts b/x-pack/plugins/security/server/routes/index.mock.ts index b0c74b98ee19b..1a93d6701e257 100644 --- a/x-pack/plugins/security/server/routes/index.mock.ts +++ b/x-pack/plugins/security/server/routes/index.mock.ts @@ -29,5 +29,7 @@ export const routeDefinitionParamsMock = { authz: authorizationMock.create(), license: licenseMock.create(), httpResources: httpResourcesMock.createRegistrar(), + getFeatures: jest.fn(), + getFeatureUsageService: jest.fn(), }), }; diff --git a/x-pack/plugins/security/server/routes/index.ts b/x-pack/plugins/security/server/routes/index.ts index e43072b95c906..5721a2699d15c 100644 --- a/x-pack/plugins/security/server/routes/index.ts +++ b/x-pack/plugins/security/server/routes/index.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Feature } from '../../../features/server'; import { CoreSetup, HttpResources, @@ -13,7 +14,7 @@ import { } from '../../../../../src/core/server'; import { SecurityLicense } from '../../common/licensing'; import { Authentication } from '../authentication'; -import { Authorization } from '../authorization'; +import { AuthorizationServiceSetup } from '../authorization'; import { ConfigType } from '../config'; import { defineAuthenticationRoutes } from './authentication'; @@ -23,6 +24,7 @@ import { defineIndicesRoutes } from './indices'; import { defineUsersRoutes } from './users'; import { defineRoleMappingRoutes } from './role_mapping'; import { defineViewRoutes } from './views'; +import { SecurityFeatureUsageServiceStart } from '../feature_usage'; /** * Describes parameters used to define HTTP routes. @@ -35,8 +37,10 @@ export interface RouteDefinitionParams { clusterClient: IClusterClient; config: ConfigType; authc: Authentication; - authz: Authorization; + authz: AuthorizationServiceSetup; license: SecurityLicense; + getFeatures: () => Promise; + getFeatureUsageService: () => SecurityFeatureUsageServiceStart; } export function defineRoutes(params: RouteDefinitionParams) { diff --git a/x-pack/plugins/security/server/saved_objects/index.ts b/x-pack/plugins/security/server/saved_objects/index.ts index 29fbe3af21b95..6acfd06a0309b 100644 --- a/x-pack/plugins/security/server/saved_objects/index.ts +++ b/x-pack/plugins/security/server/saved_objects/index.ts @@ -11,13 +11,16 @@ import { SavedObjectsClient, } from '../../../../../src/core/server'; import { SecureSavedObjectsClientWrapper } from './secure_saved_objects_client_wrapper'; -import { Authorization } from '../authorization'; +import { AuthorizationServiceSetup } from '../authorization'; import { SecurityAuditLogger } from '../audit'; import { SpacesService } from '../plugin'; interface SetupSavedObjectsParams { auditLogger: SecurityAuditLogger; - authz: Pick; + authz: Pick< + AuthorizationServiceSetup, + 'mode' | 'actions' | 'checkSavedObjectsPrivilegesWithRequest' + >; savedObjects: CoreSetup['savedObjects']; getSpacesService(): SpacesService | undefined; } diff --git a/x-pack/plugins/security_solution/.gitattributes b/x-pack/plugins/security_solution/.gitattributes new file mode 100644 index 0000000000000..431f25be5e78e --- /dev/null +++ b/x-pack/plugins/security_solution/.gitattributes @@ -0,0 +1,6 @@ +# Auto-collapse generated files in GitHub +# https://help.github.com/en/articles/customizing-how-changed-files-appear-on-github +x-pack/plugins/security_solution/server/graphql/types.ts linguist-generated=true +x-pack/plugins/security_solution/public/graphql/types.ts linguist-generated=true +x-pack/plugins/security_solution/public/graphql/introspection.json linguist-generated=true + diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts new file mode 100644 index 0000000000000..7a2b531346ac3 --- /dev/null +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -0,0 +1,151 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const APP_ID = 'securitySolution'; +export const APP_NAME = 'Security'; +export const APP_ICON = 'securityAnalyticsApp'; +export const APP_PATH = `/app/security`; +export const ADD_DATA_PATH = `/app/home#/tutorial_directory/security`; +export const DEFAULT_BYTES_FORMAT = 'format:bytes:defaultPattern'; +export const DEFAULT_DATE_FORMAT = 'dateFormat'; +export const DEFAULT_DATE_FORMAT_TZ = 'dateFormat:tz'; +export const DEFAULT_DARK_MODE = 'theme:darkMode'; +export const DEFAULT_INDEX_KEY = 'securitySolution:defaultIndex'; +export const DEFAULT_NUMBER_FORMAT = 'format:number:defaultPattern'; +export const DEFAULT_TIME_RANGE = 'timepicker:timeDefaults'; +export const DEFAULT_REFRESH_RATE_INTERVAL = 'timepicker:refreshIntervalDefaults'; +export const DEFAULT_APP_TIME_RANGE = 'securitySolution:timeDefaults'; +export const DEFAULT_APP_REFRESH_INTERVAL = 'securitySolution:refreshIntervalDefaults'; +export const DEFAULT_SIGNALS_INDEX = '.siem-signals'; +export const DEFAULT_MAX_SIGNALS = 100; +export const DEFAULT_SEARCH_AFTER_PAGE_SIZE = 100; +export const DEFAULT_ANOMALY_SCORE = 'securitySolution:defaultAnomalyScore'; +export const DEFAULT_MAX_TABLE_QUERY_SIZE = 10000; +export const DEFAULT_SCALE_DATE_FORMAT = 'dateFormat:scaled'; +export const DEFAULT_FROM = 'now-24h'; +export const DEFAULT_TO = 'now'; +export const DEFAULT_INTERVAL_PAUSE = true; +export const DEFAULT_INTERVAL_TYPE = 'manual'; +export const DEFAULT_INTERVAL_VALUE = 300000; // ms +export const DEFAULT_TIMEPICKER_QUICK_RANGES = 'timepicker:quickRanges'; +export const NO_ALERT_INDEX = 'no-alert-index-049FC71A-4C2C-446F-9901-37XMC5024C51'; + +/** The comma-delimited list of Elasticsearch indices from which the SIEM app collects events */ +export const DEFAULT_INDEX_PATTERN = [ + 'apm-*-transaction*', + 'auditbeat-*', + 'endgame-*', + 'filebeat-*', + 'packetbeat-*', + 'winlogbeat-*', +]; + +/** This Kibana Advanced Setting enables the `Security news` feed widget */ +export const ENABLE_NEWS_FEED_SETTING = 'securitySolution:enableNewsFeed'; + +/** This Kibana Advanced Setting specifies the URL of the News feed widget */ +export const NEWS_FEED_URL_SETTING = 'securitySolution:newsFeedUrl'; + +/** The default value for News feed widget */ +export const NEWS_FEED_URL_SETTING_DEFAULT = 'https://feeds.elastic.co/security-solution'; + +/** This Kibana Advanced Setting specifies the URLs of `IP Reputation Links`*/ +export const IP_REPUTATION_LINKS_SETTING = 'securitySolution:ipReputationLinks'; + +/** The default value for `IP Reputation Links` */ +export const IP_REPUTATION_LINKS_SETTING_DEFAULT = `[ + { "name": "virustotal.com", "url_template": "https://www.virustotal.com/gui/search/{{ip}}" }, + { "name": "talosIntelligence.com", "url_template": "https://talosintelligence.com/reputation_center/lookup?search={{ip}}" } +]`; + +/** + * Id for the signals alerting type + */ +export const SIGNALS_ID = `siem.signals`; + +/** + * Id for the notifications alerting type + */ +export const NOTIFICATIONS_ID = `siem.notifications`; + +/** + * Special internal structure for tags for signals. This is used + * to filter out tags that have internal structures within them. + */ +export const INTERNAL_IDENTIFIER = '__internal'; +export const INTERNAL_RULE_ID_KEY = `${INTERNAL_IDENTIFIER}_rule_id`; +export const INTERNAL_RULE_ALERT_ID_KEY = `${INTERNAL_IDENTIFIER}_rule_alert_id`; +export const INTERNAL_IMMUTABLE_KEY = `${INTERNAL_IDENTIFIER}_immutable`; + +/** + * Detection engine routes + */ +export const DETECTION_ENGINE_URL = '/api/detection_engine'; +export const DETECTION_ENGINE_RULES_URL = `${DETECTION_ENGINE_URL}/rules`; +export const DETECTION_ENGINE_PREPACKAGED_URL = `${DETECTION_ENGINE_RULES_URL}/prepackaged`; +export const DETECTION_ENGINE_PRIVILEGES_URL = `${DETECTION_ENGINE_URL}/privileges`; +export const DETECTION_ENGINE_INDEX_URL = `${DETECTION_ENGINE_URL}/index`; +export const DETECTION_ENGINE_TAGS_URL = `${DETECTION_ENGINE_URL}/tags`; +export const DETECTION_ENGINE_RULES_STATUS_URL = `${DETECTION_ENGINE_RULES_URL}/_find_statuses`; +export const DETECTION_ENGINE_PREPACKAGED_RULES_STATUS_URL = `${DETECTION_ENGINE_RULES_URL}/prepackaged/_status`; + +export const TIMELINE_URL = '/api/timeline'; +export const TIMELINE_DRAFT_URL = `${TIMELINE_URL}/_draft`; +export const TIMELINE_EXPORT_URL = `${TIMELINE_URL}/_export`; +export const TIMELINE_IMPORT_URL = `${TIMELINE_URL}/_import`; + +/** + * Default signals index key for kibana.dev.yml + */ +export const SIGNALS_INDEX_KEY = 'signalsIndex'; +export const DETECTION_ENGINE_SIGNALS_URL = `${DETECTION_ENGINE_URL}/signals`; +export const DETECTION_ENGINE_SIGNALS_STATUS_URL = `${DETECTION_ENGINE_SIGNALS_URL}/status`; +export const DETECTION_ENGINE_QUERY_SIGNALS_URL = `${DETECTION_ENGINE_SIGNALS_URL}/search`; + +/** + * Common naming convention for an unauthenticated user + */ +export const UNAUTHENTICATED_USER = 'Unauthenticated'; + +/* + Licensing requirements + */ +export const MINIMUM_ML_LICENSE = 'platinum'; + +/* + Rule notifications options +*/ +export const NOTIFICATION_SUPPORTED_ACTION_TYPES_IDS = [ + '.email', + '.slack', + '.pagerduty', + '.webhook', +]; +export const NOTIFICATION_THROTTLE_NO_ACTIONS = 'no_actions'; +export const NOTIFICATION_THROTTLE_RULE = 'rule'; + +/** + * Histograms for fields named in this list should be displayed with an + * "All others" bucket, to count events that don't specify a value for + * the field being counted + */ +export const showAllOthersBucket: string[] = [ + 'destination.ip', + 'event.action', + 'event.category', + 'event.dataset', + 'event.module', + 'signal.rule.threat.tactic.name', + 'source.ip', + 'destination.ip', + 'user.name', +]; + +/** + * CreateTemplateTimelineBtn + * Remove the comment here to enable template timeline + */ +export const disableTemplate = true; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts new file mode 100644 index 0000000000000..7db8e57421d02 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts @@ -0,0 +1,367 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/* eslint-disable @typescript-eslint/camelcase */ + +import * as t from 'io-ts'; +import { RiskScore } from '../types/risk_score'; +import { UUID } from '../types/uuid'; +import { IsoDateString } from '../types/iso_date_string'; +import { PositiveIntegerGreaterThanZero } from '../types/positive_integer_greater_than_zero'; +import { PositiveInteger } from '../types/positive_integer'; + +export const description = t.string; +export type Description = t.TypeOf; + +export const descriptionOrUndefined = t.union([description, t.undefined]); +export type DescriptionOrUndefined = t.TypeOf; + +export const enabled = t.boolean; +export type Enabled = t.TypeOf; + +export const enabledOrUndefined = t.union([enabled, t.undefined]); +export type EnabledOrUndefined = t.TypeOf; + +export const false_positives = t.array(t.string); +export type FalsePositives = t.TypeOf; + +export const falsePositivesOrUndefined = t.union([false_positives, t.undefined]); +export type FalsePositivesOrUndefined = t.TypeOf; + +export const file_name = t.string; +export type FileName = t.TypeOf; + +export const exclude_export_details = t.boolean; +export type ExcludeExportDetails = t.TypeOf; + +/** + * TODO: Right now the filters is an "unknown", when it could more than likely + * become the actual ESFilter as a type. + */ +export const filters = t.array(t.unknown); // Filters are not easily type-able yet +export type Filters = t.TypeOf; // Filters are not easily type-able yet + +/** + * Params is an "object", since it is a type of AlertActionParams which is action templates. + * @see x-pack/plugins/alerts/common/alert.ts + */ +export const action_group = t.string; +export const action_id = t.string; +export const action_action_type_id = t.string; +export const action_params = t.object; +export const action = t.exact( + t.type({ + group: action_group, + id: action_id, + action_type_id: action_action_type_id, + params: action_params, + }) +); + +export const actions = t.array(action); +export type Actions = t.TypeOf; + +// TODO: Create a regular expression type or custom date math part type here +export const from = t.string; +export type From = t.TypeOf; + +export const fromOrUndefined = t.union([from, t.undefined]); +export type FromOrUndefined = t.TypeOf; + +export const immutable = t.boolean; +export type Immutable = t.TypeOf; + +// Note: Never make this a strict uuid, we allow the rule_id to be any string at the moment +// in case we encounter 3rd party rule systems which might be using auto incrementing numbers +// or other different things. +export const rule_id = t.string; +export type RuleId = t.TypeOf; + +export const ruleIdOrUndefined = t.union([rule_id, t.undefined]); +export type RuleIdOrUndefined = t.TypeOf; + +export const id = UUID; +export const idOrUndefined = t.union([id, t.undefined]); +export type IdOrUndefined = t.TypeOf; + +export const index = t.array(t.string); +export type Index = t.TypeOf; + +export const indexOrUndefined = t.union([index, t.undefined]); +export type IndexOrUndefined = t.TypeOf; + +export const interval = t.string; +export type Interval = t.TypeOf; + +export const intervalOrUndefined = t.union([interval, t.undefined]); +export type IntervalOrUndefined = t.TypeOf; + +export const query = t.string; +export type Query = t.TypeOf; + +export const queryOrUndefined = t.union([query, t.undefined]); +export type QueryOrUndefined = t.TypeOf; + +export const language = t.keyof({ kuery: null, lucene: null }); +export type Language = t.TypeOf; + +export const languageOrUndefined = t.union([language, t.undefined]); +export type LanguageOrUndefined = t.TypeOf; + +export const objects = t.array(t.type({ rule_id })); + +export const output_index = t.string; +export type OutputIndex = t.TypeOf; + +export const outputIndexOrUndefined = t.union([output_index, t.undefined]); +export type OutputIndexOrUndefined = t.TypeOf; + +export const saved_id = t.string; +export type SavedId = t.TypeOf; + +export const savedIdOrUndefined = t.union([saved_id, t.undefined]); +export type SavedIdOrUndefined = t.TypeOf; + +export const timeline_id = t.string; +export type TimelineId = t.TypeOf; + +export const timelineIdOrUndefined = t.union([timeline_id, t.undefined]); +export type TimelineIdOrUndefined = t.TypeOf; + +export const timeline_title = t.string; +export type TimelineTitle = t.TypeOf; + +export const timelineTitleOrUndefined = t.union([timeline_title, t.undefined]); +export type TimelineTitleOrUndefined = t.TypeOf; + +export const throttle = t.string; +export type Throttle = t.TypeOf; + +export const throttleOrNull = t.union([throttle, t.null]); +export type ThrottleOrNull = t.TypeOf; + +export const anomaly_threshold = PositiveInteger; +export type AnomalyThreshold = t.TypeOf; + +export const anomalyThresholdOrUndefined = t.union([anomaly_threshold, t.undefined]); +export type AnomalyThresholdOrUndefined = t.TypeOf; + +export const machine_learning_job_id = t.string; +export type MachineLearningJobId = t.TypeOf; + +export const machineLearningJobIdOrUndefined = t.union([machine_learning_job_id, t.undefined]); +export type MachineLearningJobIdOrUndefined = t.TypeOf; + +/** + * Note that this is a plain unknown object because we allow the UI + * to send us extra additional information as "meta" which can be anything. + * + * TODO: Strip away extra information and possibly even "freeze" this object + * so we have tighter control over 3rd party data structures. + */ +export const meta = t.object; +export type Meta = t.TypeOf; +export const metaOrUndefined = t.union([meta, t.undefined]); +export type MetaOrUndefined = t.TypeOf; + +export const max_signals = PositiveIntegerGreaterThanZero; +export type MaxSignals = t.TypeOf; + +export const maxSignalsOrUndefined = t.union([max_signals, t.undefined]); +export type MaxSignalsOrUndefined = t.TypeOf; + +export const name = t.string; +export type Name = t.TypeOf; + +export const nameOrUndefined = t.union([name, t.undefined]); +export type NameOrUndefined = t.TypeOf; + +export const risk_score = RiskScore; +export type RiskScore = t.TypeOf; + +export const riskScoreOrUndefined = t.union([risk_score, t.undefined]); +export type RiskScoreOrUndefined = t.TypeOf; + +export const severity = t.keyof({ low: null, medium: null, high: null, critical: null }); +export type Severity = t.TypeOf; + +export const severityOrUndefined = t.union([severity, t.undefined]); +export type SeverityOrUndefined = t.TypeOf; + +export const status = t.keyof({ open: null, closed: null }); + +export const job_status = t.keyof({ succeeded: null, failed: null, 'going to run': null }); + +// TODO: Create a regular expression type or custom date math part type here +export const to = t.string; +export type To = t.TypeOf; + +export const toOrUndefined = t.union([to, t.undefined]); +export type ToOrUndefined = t.TypeOf; + +export const type = t.keyof({ machine_learning: null, query: null, saved_query: null }); +export type Type = t.TypeOf; + +export const typeOrUndefined = t.union([type, t.undefined]); +export type TypeOrUndefined = t.TypeOf; + +export const queryFilter = t.string; +export type QueryFilter = t.TypeOf; + +export const queryFilterOrUndefined = t.union([queryFilter, t.undefined]); +export type QueryFilterOrUndefined = t.TypeOf; + +export const references = t.array(t.string); +export type References = t.TypeOf; + +export const referencesOrUndefined = t.union([references, t.undefined]); +export type ReferencesOrUndefined = t.TypeOf; + +export const per_page = PositiveInteger; +export type PerPage = t.TypeOf; + +export const perPageOrUndefined = t.union([per_page, t.undefined]); +export type PerPageOrUndefined = t.TypeOf; + +export const page = PositiveIntegerGreaterThanZero; +export type Page = t.TypeOf; + +export const pageOrUndefined = t.union([page, t.undefined]); +export type PageOrUndefined = t.TypeOf; + +export const signal_ids = t.array(t.string); + +// TODO: Can this be more strict or is this is the set of all Elastic Queries? +export const signal_status_query = t.object; + +export const sort_field = t.string; +export type SortField = t.TypeOf; + +export const sortFieldOrUndefined = t.union([sort_field, t.undefined]); +export type SortFieldOrUndefined = t.TypeOf; + +export const sort_order = t.keyof({ asc: null, desc: null }); +export type sortOrder = t.TypeOf; + +export const sortOrderOrUndefined = t.union([sort_order, t.undefined]); +export type SortOrderOrUndefined = t.TypeOf; + +export const tags = t.array(t.string); +export type Tags = t.TypeOf; + +export const tagsOrUndefined = t.union([tags, t.undefined]); +export type TagsOrUndefined = t.TypeOf; + +export const fields = t.array(t.string); +export type Fields = t.TypeOf; +export const fieldsOrUndefined = t.union([fields, t.undefined]); +export type FieldsOrUndefined = t.TypeOf; + +export const threat_framework = t.string; +export const threat_tactic_id = t.string; +export const threat_tactic_name = t.string; +export const threat_tactic_reference = t.string; +export const threat_tactic = t.type({ + id: threat_tactic_id, + name: threat_tactic_name, + reference: threat_tactic_reference, +}); +export const threat_technique_id = t.string; +export const threat_technique_name = t.string; +export const threat_technique_reference = t.string; +export const threat_technique = t.exact( + t.type({ + id: threat_technique_id, + name: threat_technique_name, + reference: threat_technique_reference, + }) +); +export const threat_techniques = t.array(threat_technique); +export const threat = t.array( + t.exact( + t.type({ + framework: threat_framework, + tactic: threat_tactic, + technique: threat_techniques, + }) + ) +); + +export type Threat = t.TypeOf; + +export const threatOrUndefined = t.union([threat, t.undefined]); +export type ThreatOrUndefined = t.TypeOf; + +export const created_at = IsoDateString; +export const updated_at = IsoDateString; +export const updated_by = t.string; +export const created_by = t.string; + +export const version = PositiveIntegerGreaterThanZero; +export type Version = t.TypeOf; + +export const versionOrUndefined = t.union([version, t.undefined]); +export type VersionOrUndefined = t.TypeOf; + +export const last_success_at = IsoDateString; +export const last_success_message = t.string; +export const last_failure_at = IsoDateString; +export const last_failure_message = t.string; +export const status_date = IsoDateString; +export const rules_installed = PositiveInteger; +export const rules_updated = PositiveInteger; +export const status_code = PositiveInteger; +export const message = t.string; +export const perPage = PositiveInteger; +export const total = PositiveInteger; +export const success = t.boolean; +export const success_count = PositiveInteger; +export const rules_custom_installed = PositiveInteger; +export const rules_not_installed = PositiveInteger; +export const rules_not_updated = PositiveInteger; + +export const note = t.string; +export type Note = t.TypeOf; + +export const noteOrUndefined = t.union([note, t.undefined]); +export type NoteOrUndefined = t.TypeOf; + +// NOTE: Experimental list support not being shipped currently and behind a feature flag +// TODO: Remove this comment once we lists have passed testing and is ready for the release +export const list_field = t.string; +export const list_values_operator = t.keyof({ included: null, excluded: null }); +export const list_values_type = t.keyof({ match: null, match_all: null, list: null, exists: null }); +export const list_values = t.exact( + t.intersection([ + t.type({ + name: t.string, + }), + t.partial({ + id: t.string, + description: t.string, + created_at, + }), + ]) +); +export const list = t.exact( + t.intersection([ + t.type({ + field: t.string, + values_operator: list_values_operator, + values_type: list_values_type, + }), + t.partial({ values: t.array(list_values) }), + ]) +); +export const list_and = t.intersection([ + list, + t.partial({ + and: t.array(list), + }), +]); + +export const listAndOrUndefined = t.union([t.array(list_and), t.undefined]); +export type ListAndOrUndefined = t.TypeOf; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_schema.mock.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_schema.mock.ts new file mode 100644 index 0000000000000..52a210f3a01aa --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_schema.mock.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + AddPrepackagedRulesSchema, + AddPrepackagedRulesSchemaDecoded, +} from './add_prepackaged_rules_schema'; +import { DEFAULT_MAX_SIGNALS } from '../../../constants'; + +export const getAddPrepackagedRulesSchemaMock = (): AddPrepackagedRulesSchema => ({ + description: 'some description', + name: 'Query with a rule id', + query: 'user.name: root or user.name: admin', + severity: 'high', + type: 'query', + risk_score: 55, + language: 'kuery', + rule_id: 'rule-1', + version: 1, +}); + +export const getAddPrepackagedRulesSchemaDecodedMock = (): AddPrepackagedRulesSchemaDecoded => ({ + description: 'some description', + name: 'Query with a rule id', + query: 'user.name: root or user.name: admin', + severity: 'high', + type: 'query', + risk_score: 55, + language: 'kuery', + references: [], + actions: [], + enabled: false, + false_positives: [], + from: 'now-6m', + interval: '5m', + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + to: 'now', + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + rule_id: 'rule-1', +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_schema.ts new file mode 100644 index 0000000000000..3e7e7e5409c9c --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_schema.ts @@ -0,0 +1,134 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; + +/* eslint-disable @typescript-eslint/camelcase */ +import { + description, + anomaly_threshold, + filters, + index, + saved_id, + timeline_id, + timeline_title, + meta, + machine_learning_job_id, + risk_score, + MaxSignals, + name, + severity, + Tags, + To, + type, + Threat, + ThrottleOrNull, + note, + References, + Actions, + Enabled, + FalsePositives, + From, + Interval, + language, + query, + rule_id, + version, +} from '../common/schemas'; +/* eslint-enable @typescript-eslint/camelcase */ + +import { DefaultStringArray } from '../types/default_string_array'; +import { DefaultActionsArray } from '../types/default_actions_array'; +import { DefaultBooleanFalse } from '../types/default_boolean_false'; +import { DefaultFromString } from '../types/default_from_string'; +import { DefaultIntervalString } from '../types/default_interval_string'; +import { DefaultMaxSignalsNumber } from '../types/default_max_signals_number'; +import { DefaultToString } from '../types/default_to_string'; +import { DefaultThreatArray } from '../types/default_threat_array'; +import { DefaultThrottleNull } from '../types/default_throttle_null'; +import { ListsDefaultArray, ListsDefaultArraySchema } from '../types/lists_default_array'; + +/** + * Big differences between this schema and the createRulesSchema + * - rule_id is required here + * - output_index is not allowed (and instead the space index must be used) + * - immutable is forbidden but defaults to true instead of to false and it can only ever be true (This is forced directly in the route and not here) + * - enabled defaults to false instead of true + * - version is a required field that must exist + * - index is a required field that must exist if type !== machine_learning (Checked within the runtime type dependent system) + */ +export const addPrepackagedRulesSchema = t.intersection([ + t.exact( + t.type({ + description, + risk_score, + name, + severity, + type, + rule_id, + version, + }) + ), + t.exact( + t.partial({ + actions: DefaultActionsArray, // defaults to empty actions array if not set during decode + anomaly_threshold, // defaults to undefined if not set during decode + enabled: DefaultBooleanFalse, // defaults to false if not set during decode + false_positives: DefaultStringArray, // defaults to empty string array if not set during decode + filters, // defaults to undefined if not set during decode + from: DefaultFromString, // defaults to "now-6m" if not set during decode + index, // defaults to undefined if not set during decode + interval: DefaultIntervalString, // defaults to "5m" if not set during decode + query, // defaults to undefined if not set during decode + language, // defaults to undefined if not set during decode + saved_id, // defaults to "undefined" if not set during decode + timeline_id, // defaults to "undefined" if not set during decode + timeline_title, // defaults to "undefined" if not set during decode + meta, // defaults to "undefined" if not set during decode + machine_learning_job_id, // defaults to "undefined" if not set during decode + max_signals: DefaultMaxSignalsNumber, // defaults to DEFAULT_MAX_SIGNALS (100) if not set during decode + tags: DefaultStringArray, // defaults to empty string array if not set during decode + to: DefaultToString, // defaults to "now" if not set during decode + threat: DefaultThreatArray, // defaults to empty array if not set during decode + throttle: DefaultThrottleNull, // defaults to "null" if not set during decode + references: DefaultStringArray, // defaults to empty array of strings if not set during decode + note, // defaults to "undefined" if not set during decode + exceptions_list: ListsDefaultArray, // defaults to empty array if not set during decode + }) + ), +]); + +export type AddPrepackagedRulesSchema = t.TypeOf; + +// This type is used after a decode since some things are defaults after a decode. +export type AddPrepackagedRulesSchemaDecoded = Omit< + AddPrepackagedRulesSchema, + | 'references' + | 'actions' + | 'enabled' + | 'false_positives' + | 'from' + | 'interval' + | 'max_signals' + | 'tags' + | 'to' + | 'threat' + | 'throttle' + | 'exceptions_list' +> & { + references: References; + actions: Actions; + enabled: Enabled; + false_positives: FalsePositives; + from: From; + interval: Interval; + max_signals: MaxSignals; + tags: Tags; + to: To; + threat: Threat; + throttle: ThrottleOrNull; + exceptions_list: ListsDefaultArraySchema; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_type_dependents.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_type_dependents.test.ts new file mode 100644 index 0000000000000..793d4b04ed0e5 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_type_dependents.test.ts @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { AddPrepackagedRulesSchema } from './add_prepackaged_rules_schema'; +import { addPrepackagedRuleValidateTypeDependents } from './add_prepackaged_rules_type_dependents'; +import { getAddPrepackagedRulesSchemaMock } from './add_prepackaged_rules_schema.mock'; + +describe('create_rules_type_dependents', () => { + test('saved_id is required when type is saved_query and will not validate without out', () => { + const schema: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + type: 'saved_query', + }; + delete schema.saved_id; + const errors = addPrepackagedRuleValidateTypeDependents(schema); + expect(errors).toEqual(['when "type" is "saved_query", "saved_id" is required']); + }); + + test('saved_id is required when type is saved_query and validates with it', () => { + const schema: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + type: 'saved_query', + saved_id: '123', + }; + const errors = addPrepackagedRuleValidateTypeDependents(schema); + expect(errors).toEqual([]); + }); + + test('You cannot omit timeline_title when timeline_id is present', () => { + const schema: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + timeline_id: '123', + }; + delete schema.timeline_title; + const errors = addPrepackagedRuleValidateTypeDependents(schema); + expect(errors).toEqual(['when "timeline_id" exists, "timeline_title" must also exist']); + }); + + test('You cannot have empty string for timeline_title when timeline_id is present', () => { + const schema: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + timeline_id: '123', + timeline_title: '', + }; + const errors = addPrepackagedRuleValidateTypeDependents(schema); + expect(errors).toEqual(['"timeline_title" cannot be an empty string']); + }); + + test('You cannot have timeline_title with an empty timeline_id', () => { + const schema: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + timeline_id: '', + timeline_title: 'some-title', + }; + const errors = addPrepackagedRuleValidateTypeDependents(schema); + expect(errors).toEqual(['"timeline_id" cannot be an empty string']); + }); + + test('You cannot have timeline_title without timeline_id', () => { + const schema: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + timeline_title: 'some-title', + }; + delete schema.timeline_id; + const errors = addPrepackagedRuleValidateTypeDependents(schema); + expect(errors).toEqual(['when "timeline_title" exists, "timeline_id" must also exist']); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_type_dependents.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_type_dependents.ts new file mode 100644 index 0000000000000..2788c331154d2 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_type_dependents.ts @@ -0,0 +1,107 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { AddPrepackagedRulesSchema } from './add_prepackaged_rules_schema'; + +export const validateAnomalyThreshold = (rule: AddPrepackagedRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.anomaly_threshold == null) { + return ['when "type" is "machine_learning" anomaly_threshold is required']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateQuery = (rule: AddPrepackagedRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.query != null) { + return ['when "type" is "machine_learning", "query" cannot be set']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateLanguage = (rule: AddPrepackagedRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.language != null) { + return ['when "type" is "machine_learning", "language" cannot be set']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateSavedId = (rule: AddPrepackagedRulesSchema): string[] => { + if (rule.type === 'saved_query') { + if (rule.saved_id == null) { + return ['when "type" is "saved_query", "saved_id" is required']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateMachineLearningJobId = (rule: AddPrepackagedRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.machine_learning_job_id == null) { + return ['when "type" is "machine_learning", "machine_learning_job_id" is required']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateTimelineId = (rule: AddPrepackagedRulesSchema): string[] => { + if (rule.timeline_id != null) { + if (rule.timeline_title == null) { + return ['when "timeline_id" exists, "timeline_title" must also exist']; + } else if (rule.timeline_id === '') { + return ['"timeline_id" cannot be an empty string']; + } else { + return []; + } + } + return []; +}; + +export const validateTimelineTitle = (rule: AddPrepackagedRulesSchema): string[] => { + if (rule.timeline_title != null) { + if (rule.timeline_id == null) { + return ['when "timeline_title" exists, "timeline_id" must also exist']; + } else if (rule.timeline_title === '') { + return ['"timeline_title" cannot be an empty string']; + } else { + return []; + } + } + return []; +}; + +export const addPrepackagedRuleValidateTypeDependents = ( + schema: AddPrepackagedRulesSchema +): string[] => { + return [ + ...validateAnomalyThreshold(schema), + ...validateQuery(schema), + ...validateLanguage(schema), + ...validateSavedId(schema), + ...validateMachineLearningJobId(schema), + ...validateTimelineId(schema), + ...validateTimelineTitle(schema), + ]; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackged_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackged_rules_schema.test.ts new file mode 100644 index 0000000000000..5d170f5a78645 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackged_rules_schema.test.ts @@ -0,0 +1,1389 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + addPrepackagedRulesSchema, + AddPrepackagedRulesSchemaDecoded, + AddPrepackagedRulesSchema, +} from './add_prepackaged_rules_schema'; + +import { exactCheck } from '../../../exact_check'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { left } from 'fp-ts/lib/Either'; +import { + getAddPrepackagedRulesSchemaMock, + getAddPrepackagedRulesSchemaDecodedMock, +} from './add_prepackaged_rules_schema.mock'; +import { DEFAULT_MAX_SIGNALS } from '../../../constants'; + +describe('add prepackaged rules schema', () => { + test('empty objects do not validate', () => { + const payload: Partial = {}; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "description"', + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + 'Invalid value "undefined" supplied to "rule_id"', + 'Invalid value "undefined" supplied to "version"', + ]); + expect(message.schema).toEqual({}); + }); + + test('made up values do not validate', () => { + const payload: AddPrepackagedRulesSchema & { madeUp: string } = { + ...getAddPrepackagedRulesSchemaMock(), + madeUp: 'hi', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['invalid keys "madeUp"']); + expect(message.schema).toEqual({}); + }); + + test('[rule_id] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "description"', + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + 'Invalid value "undefined" supplied to "version"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + 'Invalid value "undefined" supplied to "version"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + 'Invalid value "undefined" supplied to "version"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + 'Invalid value "undefined" supplied to "version"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + 'Invalid value "undefined" supplied to "version"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "type"', + 'Invalid value "undefined" supplied to "version"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "version"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type, interval] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "version"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type, interval, index] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + interval: '5m', + index: ['index-1'], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "version"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type, query, index, interval, version] does validate', () => { + const payload: AddPrepackagedRulesSchema = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + query: 'some query', + index: ['index-1'], + interval: '5m', + version: 1, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + query: 'some query', + index: ['index-1'], + interval: '5m', + references: [], + actions: [], + enabled: false, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, query, language] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + risk_score: 50, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "version"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, version] does validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + risk_score: 50, + version: 1, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + references: [], + actions: [], + enabled: false, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score, output_index] does not validate', () => { + const payload: Partial & { output_index: string } = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "version"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score, output_index, version] does not validate because output_index is not allowed', () => { + const payload: Partial & { output_index: string } = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + version: 1, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['invalid keys "output_index"']); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, version] does validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + version: 1, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + version: 1, + actions: [], + enabled: false, + exceptions_list: [], + false_positives: [], + max_signals: 100, + references: [], + tags: [], + threat: [], + throttle: null, + }; + expect(message.schema).toEqual(expected); + }); + + test('You can send in an empty array to threat', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + threat: [], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...getAddPrepackagedRulesSchemaDecodedMock(), + threat: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index, threat] does validate', () => { + const payload: AddPrepackagedRulesSchema = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + threat: [ + { + framework: 'someFramework', + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + version: 1, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + threat: [ + { + framework: 'someFramework', + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + references: [], + actions: [], + enabled: false, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + throttle: null, + version: 1, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('allows references to be sent as valid', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + references: ['index-1'], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...getAddPrepackagedRulesSchemaDecodedMock(), + references: ['index-1'], + }; + expect(message.schema).toEqual(expected); + }); + + test('defaults references to an array if it is not sent in', () => { + const { references, ...noReferences } = getAddPrepackagedRulesSchemaMock(); + const decoded = addPrepackagedRulesSchema.decode(noReferences); + const checked = exactCheck(noReferences, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...getAddPrepackagedRulesSchemaDecodedMock(), + references: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('immutable cannot be set in a pre-packaged rule', () => { + const payload: AddPrepackagedRulesSchema & { immutable: boolean } = { + ...getAddPrepackagedRulesSchemaMock(), + immutable: true, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['invalid keys "immutable"']); + expect(message.schema).toEqual({}); + }); + + test('defaults enabled to false', () => { + const payload: AddPrepackagedRulesSchema = getAddPrepackagedRulesSchemaMock(); + delete payload.enabled; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(((message.schema as unknown) as AddPrepackagedRulesSchemaDecoded).enabled).toEqual( + false + ); + }); + + test('rule_id is required', () => { + const payload: AddPrepackagedRulesSchema = getAddPrepackagedRulesSchemaMock(); + delete payload.rule_id; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "rule_id"', + ]); + expect(message.schema).toEqual({}); + }); + + test('references cannot be numbers', () => { + const payload: Omit & { references: number[] } = { + ...getAddPrepackagedRulesSchemaMock(), + references: [5], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('indexes cannot be numbers', () => { + const payload: Omit & { index: number[] } = { + ...getAddPrepackagedRulesSchemaMock(), + index: [5], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "index"']); + expect(message.schema).toEqual({}); + }); + + test('defaults interval to 5 min', () => { + const { interval, ...noInterval } = getAddPrepackagedRulesSchemaMock(); + const payload: AddPrepackagedRulesSchema = { + ...noInterval, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { + interval: expectedInterval, + ...expectedNoInterval + } = getAddPrepackagedRulesSchemaDecodedMock(); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...expectedNoInterval, + interval: '5m', + }; + expect(message.schema).toEqual(expected); + }); + + test('defaults max signals to 100', () => { + const { max_signals, ...noMaxSignals } = getAddPrepackagedRulesSchemaMock(); + const payload: AddPrepackagedRulesSchema = { + ...noMaxSignals, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { + max_signals: expectedMaxSignals, + ...expectedNoMaxSignals + } = getAddPrepackagedRulesSchemaDecodedMock(); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...expectedNoMaxSignals, + max_signals: 100, + }; + expect(message.schema).toEqual(expected); + }); + + test('saved_query type can have filters with it', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + filters: [], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...getAddPrepackagedRulesSchemaDecodedMock(), + filters: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('filters cannot be a string', () => { + const payload: Omit & { filters: string } = { + ...getAddPrepackagedRulesSchemaMock(), + filters: 'some string', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "some string" supplied to "filters"', + ]); + expect(message.schema).toEqual({}); + }); + + test('language validates with kuery', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + language: 'kuery', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...getAddPrepackagedRulesSchemaDecodedMock(), + language: 'kuery', + }; + expect(message.schema).toEqual(expected); + }); + + test('language validates with lucene', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + language: 'lucene', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...getAddPrepackagedRulesSchemaDecodedMock(), + language: 'lucene', + }; + expect(message.schema).toEqual(expected); + }); + + test('language does not validate with something made up', () => { + const payload: Omit & { language: string } = { + ...getAddPrepackagedRulesSchemaMock(), + language: 'something-made-up', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "something-made-up" supplied to "language"', + ]); + expect(message.schema).toEqual({}); + }); + + test('max_signals cannot be negative', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + max_signals: -1, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('max_signals cannot be zero', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + max_signals: 0, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('max_signals can be 1', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + max_signals: 1, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...getAddPrepackagedRulesSchemaDecodedMock(), + max_signals: 1, + }; + expect(message.schema).toEqual(expected); + }); + + test('You can optionally send in an array of tags', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + tags: ['tag_1', 'tag_2'], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...getAddPrepackagedRulesSchemaDecodedMock(), + tags: ['tag_1', 'tag_2'], + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot send in an array of tags that are numbers', () => { + const payload: Omit & { tags: number[] } = { + ...getAddPrepackagedRulesSchemaMock(), + tags: [0, 1, 2], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "0" supplied to ""', + 'Invalid value "1" supplied to ""', + 'Invalid value "2" supplied to ""', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of threat that are missing "framework"', () => { + const payload: Omit & { + threat: Array>>; + } = { + ...getAddPrepackagedRulesSchemaMock(), + threat: [ + { + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "framework"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of threat that are missing "tactic"', () => { + const payload: Omit & { + threat: Array>>; + } = { + ...getAddPrepackagedRulesSchemaMock(), + threat: [ + { + framework: 'fake', + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "tactic"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of threat that are missing "technique"', () => { + const payload: Omit & { + threat: Array>>; + } = { + ...getAddPrepackagedRulesSchemaMock(), + threat: [ + { + framework: 'fake', + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + }, + ], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "technique"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You can optionally send in an array of false positives', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + false_positives: ['false_1', 'false_2'], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...getAddPrepackagedRulesSchemaDecodedMock(), + false_positives: ['false_1', 'false_2'], + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot send in an array of false positives that are numbers', () => { + const payload: Omit & { + false_positives: number[]; + } = { + ...getAddPrepackagedRulesSchemaMock(), + false_positives: [5, 4], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to ""', + 'Invalid value "4" supplied to ""', + ]); + expect(message.schema).toEqual({}); + }); + test('You cannot set the risk_score to 101', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + risk_score: 101, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "101" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot set the risk_score to -1', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + risk_score: -1, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to "risk_score"']); + expect(message.schema).toEqual({}); + }); + + test('You can set the risk_score to 0', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + risk_score: 0, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...getAddPrepackagedRulesSchemaDecodedMock(), + risk_score: 0, + }; + expect(message.schema).toEqual(expected); + }); + + test('You can set the risk_score to 100', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + risk_score: 100, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...getAddPrepackagedRulesSchemaDecodedMock(), + risk_score: 100, + }; + expect(message.schema).toEqual(expected); + }); + + test('You can set meta to any object you want', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + meta: { + somethingMadeUp: { somethingElse: true }, + }, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...getAddPrepackagedRulesSchemaDecodedMock(), + meta: { + somethingMadeUp: { somethingElse: true }, + }, + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot create meta as a string', () => { + const payload: Omit & { meta: string } = { + ...getAddPrepackagedRulesSchemaMock(), + meta: 'should not work', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "should not work" supplied to "meta"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You can omit the query string when filters are present', () => { + const { query, ...noQuery } = getAddPrepackagedRulesSchemaMock(); + const payload: AddPrepackagedRulesSchema = { + ...noQuery, + filters: [], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { query: expectedQuery, ...expectedNoQuery } = getAddPrepackagedRulesSchemaDecodedMock(); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...expectedNoQuery, + filters: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('validates with timeline_id and timeline_title', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + timeline_id: 'timeline-id', + timeline_title: 'timeline-title', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...getAddPrepackagedRulesSchemaDecodedMock(), + timeline_id: 'timeline-id', + timeline_title: 'timeline-title', + }; + expect(message.schema).toEqual(expected); + }); + + test('The default for "from" will be "now-6m"', () => { + const { from, ...noFrom } = getAddPrepackagedRulesSchemaMock(); + const payload: AddPrepackagedRulesSchema = { + ...noFrom, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { from: expectedFrom, ...expectedNoFrom } = getAddPrepackagedRulesSchemaDecodedMock(); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...expectedNoFrom, + from: 'now-6m', + }; + expect(message.schema).toEqual(expected); + }); + + test('The default for "to" will be "now"', () => { + const { to, ...noTo } = getAddPrepackagedRulesSchemaMock(); + const payload: AddPrepackagedRulesSchema = { + ...noTo, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { to: expectedTo, ...expectedNoTo } = getAddPrepackagedRulesSchemaDecodedMock(); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...expectedNoTo, + to: 'now', + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot set the severity to a value other than low, medium, high, or critical', () => { + const payload: Omit & { severity: string } = { + ...getAddPrepackagedRulesSchemaMock(), + severity: 'junk', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "junk" supplied to "severity"']); + expect(message.schema).toEqual({}); + }); + + test('The default for "actions" will be an empty array', () => { + const { actions, ...noActions } = getAddPrepackagedRulesSchemaMock(); + const payload: AddPrepackagedRulesSchema = { + ...noActions, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { + actions: expectedActions, + ...expectedNoActions + } = getAddPrepackagedRulesSchemaDecodedMock(); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...expectedNoActions, + actions: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot send in an array of actions that are missing "group"', () => { + const payload: Omit = { + ...getAddPrepackagedRulesSchemaMock(), + actions: [{ id: 'id', action_type_id: 'action_type_id', params: {} }], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "group"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are missing "id"', () => { + const payload: Omit = { + ...getAddPrepackagedRulesSchemaMock(), + actions: [{ group: 'group', action_type_id: 'action_type_id', params: {} }], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "undefined" supplied to "id"']); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are missing "action_type_id"', () => { + const payload: Omit = { + ...getAddPrepackagedRulesSchemaMock(), + actions: [{ group: 'group', id: 'id', params: {} }], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "action_type_id"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are missing "params"', () => { + const payload: Omit = { + ...getAddPrepackagedRulesSchemaMock(), + actions: [{ group: 'group', id: 'id', action_type_id: 'action_type_id' }], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "params"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are including "actionTypeId"', () => { + const payload: Omit = { + ...getAddPrepackagedRulesSchemaMock(), + actions: [ + { + group: 'group', + id: 'id', + actionTypeId: 'actionTypeId', + params: {}, + }, + ], + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "action_type_id"', + ]); + expect(message.schema).toEqual({}); + }); + + test('The default for "throttle" will be null', () => { + const { throttle, ...noThrottle } = getAddPrepackagedRulesSchemaMock(); + const payload: AddPrepackagedRulesSchema = { + ...noThrottle, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { + throttle: expectedThrottle, + ...expectedNoThrottle + } = getAddPrepackagedRulesSchemaDecodedMock(); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...expectedNoThrottle, + throttle: null, + }; + expect(message.schema).toEqual(expected); + }); + + describe('note', () => { + test('You can set note to a string', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + note: '# documentation markdown here', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + ...getAddPrepackagedRulesSchemaDecodedMock(), + note: '# documentation markdown here', + }; + expect(message.schema).toEqual(expected); + }); + + test('You can set note to an empty string', () => { + const payload: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaMock(), + note: '', + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchema = { + ...getAddPrepackagedRulesSchemaDecodedMock(), + note: '', + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot create note as an object', () => { + const payload: Omit & { note: {} } = { + ...getAddPrepackagedRulesSchemaMock(), + note: { + somethingHere: 'something else', + }, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + // TODO: Fix/Change the formatErrors to be better able to handle objects + 'Invalid value "[object Object]" supplied to "note"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note] does validate', () => { + const payload: AddPrepackagedRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + note: '# some markdown', + version: 1, + }; + + const decoded = addPrepackagedRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: AddPrepackagedRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + note: '# some markdown', + references: [], + actions: [], + enabled: false, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + }); + + // TODO: The exception_list tests are skipped and empty until we re-integrate it from the lists plugin + describe.skip('exception_list', () => { + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and exceptions_list] does validate', () => {}); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and empty exceptions_list] does validate', () => {}); + + test('rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and invalid exceptions_list] does NOT validate', () => {}); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and non-existent exceptions_list] does validate with empty exceptions_list', () => {}); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.test.ts new file mode 100644 index 0000000000000..e79dde41752a3 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.test.ts @@ -0,0 +1,281 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + createRulesBulkSchema, + CreateRulesBulkSchema, + CreateRulesBulkSchemaDecoded, +} from './create_rules_bulk_schema'; +import { exactCheck } from '../../../exact_check'; +import { foldLeftRight } from '../../../test_utils'; +import { + getCreateRulesSchemaMock, + getCreateRulesSchemaDecodedMock, +} from './create_rules_schema.mock'; +import { formatErrors } from '../../../format_errors'; +import { CreateRulesSchema } from './create_rules_schema'; + +// only the basics of testing are here. +// see: create_rules_schema.test.ts for the bulk of the validation tests +// this just wraps createRulesSchema in an array +describe('create_rules_bulk_schema', () => { + test('can take an empty array and validate it', () => { + const payload: CreateRulesBulkSchema = []; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(output.errors).toEqual([]); + expect(output.schema).toEqual([]); + }); + + test('made up values do not validate for a single element', () => { + const payload: Array<{ madeUp: string }> = [{ madeUp: 'hi' }]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([ + 'Invalid value "undefined" supplied to "description"', + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(output.schema).toEqual({}); + }); + + test('single array element does validate', () => { + const payload: CreateRulesBulkSchema = [getCreateRulesSchemaMock()]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual([getCreateRulesSchemaDecodedMock()]); + }); + + test('two array elements do validate', () => { + const payload: CreateRulesBulkSchema = [getCreateRulesSchemaMock(), getCreateRulesSchemaMock()]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual([ + getCreateRulesSchemaDecodedMock(), + getCreateRulesSchemaDecodedMock(), + ]); + }); + + test('single array element with a missing value (risk_score) will not validate', () => { + const singleItem = getCreateRulesSchemaMock(); + delete singleItem.risk_score; + const payload: CreateRulesBulkSchema = [singleItem]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(output.schema).toEqual({}); + }); + + test('two array elements where the first is valid but the second is invalid (risk_score) will not validate', () => { + const singleItem = getCreateRulesSchemaMock(); + const secondItem = getCreateRulesSchemaMock(); + delete secondItem.risk_score; + const payload: CreateRulesBulkSchema = [singleItem, secondItem]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(output.schema).toEqual({}); + }); + + test('two array elements where the first is invalid (risk_score) but the second is valid will not validate', () => { + const singleItem = getCreateRulesSchemaMock(); + const secondItem = getCreateRulesSchemaMock(); + delete singleItem.risk_score; + const payload: CreateRulesBulkSchema = [singleItem, secondItem]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(output.schema).toEqual({}); + }); + + test('two array elements where both are invalid (risk_score) will not validate', () => { + const singleItem = getCreateRulesSchemaMock(); + const secondItem = getCreateRulesSchemaMock(); + delete singleItem.risk_score; + delete secondItem.risk_score; + const payload: CreateRulesBulkSchema = [singleItem, secondItem]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(output.schema).toEqual({}); + }); + + test('two array elements where the first is invalid (extra key and value) but the second is valid will not validate', () => { + const singleItem: CreateRulesSchema & { madeUpValue: string } = { + ...getCreateRulesSchemaMock(), + madeUpValue: 'something', + }; + const secondItem = getCreateRulesSchemaMock(); + const payload: CreateRulesBulkSchema = [singleItem, secondItem]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual(['invalid keys "madeUpValue"']); + expect(output.schema).toEqual({}); + }); + + test('two array elements where the second is invalid (extra key and value) but the first is valid will not validate', () => { + const singleItem: CreateRulesSchema = getCreateRulesSchemaMock(); + const secondItem: CreateRulesSchema & { madeUpValue: string } = { + ...getCreateRulesSchemaMock(), + madeUpValue: 'something', + }; + const payload: CreateRulesBulkSchema = [singleItem, secondItem]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual(['invalid keys "madeUpValue"']); + expect(output.schema).toEqual({}); + }); + + test('two array elements where both are invalid (extra key and value) will not validate', () => { + const singleItem: CreateRulesSchema & { madeUpValue: string } = { + ...getCreateRulesSchemaMock(), + madeUpValue: 'something', + }; + const secondItem: CreateRulesSchema & { madeUpValue: string } = { + ...getCreateRulesSchemaMock(), + madeUpValue: 'something', + }; + const payload: CreateRulesBulkSchema = [singleItem, secondItem]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual(['invalid keys "madeUpValue,madeUpValue"']); + expect(output.schema).toEqual({}); + }); + + test('The default for "from" will be "now-6m"', () => { + const { from, ...withoutFrom } = getCreateRulesSchemaMock(); + const payload: CreateRulesBulkSchema = [withoutFrom]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect((output.schema as CreateRulesBulkSchemaDecoded)[0].from).toEqual('now-6m'); + }); + + test('The default for "to" will be "now"', () => { + const { to, ...withoutTo } = getCreateRulesSchemaMock(); + const payload: CreateRulesBulkSchema = [withoutTo]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect((output.schema as CreateRulesBulkSchemaDecoded)[0].to).toEqual('now'); + }); + + test('You cannot set the severity to a value other than low, medium, high, or critical', () => { + const badSeverity = { ...getCreateRulesSchemaMock(), severity: 'madeup' }; + const payload = [badSeverity]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual(['Invalid value "madeup" supplied to "severity"']); + expect(output.schema).toEqual({}); + }); + + test('You can set "note" to a string', () => { + const payload: CreateRulesBulkSchema = [ + { ...getCreateRulesSchemaMock(), note: '# test markdown' }, + ]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual([ + { ...getCreateRulesSchemaDecodedMock(), note: '# test markdown' }, + ]); + }); + + test('You can set "note" to an empty string', () => { + const payload: CreateRulesBulkSchema = [{ ...getCreateRulesSchemaMock(), note: '' }]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual([{ ...getCreateRulesSchemaDecodedMock(), note: '' }]); + }); + + test('You can set "note" to anything other than string', () => { + const payload = [ + { + ...getCreateRulesSchemaMock(), + note: { + something: 'some object', + }, + }, + ]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + // TODO: We should change the formatter used to better print objects + expect(formatErrors(output.errors)).toEqual([ + 'Invalid value "[object Object]" supplied to "note"', + ]); + expect(output.schema).toEqual({}); + }); + + test('The default for "actions" will be an empty array', () => { + const { actions, ...withoutActions } = getCreateRulesSchemaMock(); + const payload: CreateRulesBulkSchema = [withoutActions]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect((output.schema as CreateRulesBulkSchemaDecoded)[0].actions).toEqual([]); + }); + + test('The default for "throttle" will be null', () => { + const { throttle, ...withoutThrottle } = getCreateRulesSchemaMock(); + const payload: CreateRulesBulkSchema = [withoutThrottle]; + + const decoded = createRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect((output.schema as CreateRulesBulkSchemaDecoded)[0].throttle).toEqual(null); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.ts new file mode 100644 index 0000000000000..c6233cc63fa9f --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; + +import { createRulesSchema, CreateRulesSchemaDecoded } from './create_rules_schema'; + +export const createRulesBulkSchema = t.array(createRulesSchema); +export type CreateRulesBulkSchema = t.TypeOf; + +export type CreateRulesBulkSchemaDecoded = CreateRulesSchemaDecoded[]; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.mock.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.mock.ts new file mode 100644 index 0000000000000..a9ab6f8959e24 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.mock.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { CreateRulesSchema, CreateRulesSchemaDecoded } from './create_rules_schema'; +import { DEFAULT_MAX_SIGNALS } from '../../../constants'; + +export const getCreateRulesSchemaMock = (): CreateRulesSchema => ({ + description: 'some description', + name: 'Query with a rule id', + query: 'user.name: root or user.name: admin', + severity: 'high', + type: 'query', + risk_score: 55, + language: 'kuery', + rule_id: 'rule-1', +}); + +export const getCreateRulesSchemaDecodedMock = (): CreateRulesSchemaDecoded => ({ + description: 'some description', + name: 'Query with a rule id', + query: 'user.name: root or user.name: admin', + severity: 'high', + type: 'query', + risk_score: 55, + language: 'kuery', + references: [], + actions: [], + enabled: true, + false_positives: [], + from: 'now-6m', + interval: '5m', + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + to: 'now', + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + rule_id: 'rule-1', +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.test.ts new file mode 100644 index 0000000000000..d672d38028902 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.test.ts @@ -0,0 +1,1445 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + createRulesSchema, + CreateRulesSchema, + CreateRulesSchemaDecoded, +} from './create_rules_schema'; +import { exactCheck } from '../../../exact_check'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { left } from 'fp-ts/lib/Either'; +import { + getCreateRulesSchemaMock, + getCreateRulesSchemaDecodedMock, +} from './create_rules_schema.mock'; +import { DEFAULT_MAX_SIGNALS } from '../../../constants'; + +describe('create rules schema', () => { + test('empty objects do not validate', () => { + const payload: Partial = {}; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "description"', + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('made up values do not validate', () => { + const payload: CreateRulesSchema & { madeUp: string } = { + ...getCreateRulesSchemaMock(), + madeUp: 'hi', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['invalid keys "madeUp"']); + expect(message.schema).toEqual({}); + }); + + test('[rule_id] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "description"', + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type, interval] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type, interval, index] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + interval: '5m', + index: ['index-1'], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type, query, index, interval] does validate', () => { + const payload: CreateRulesSchema = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + query: 'some query', + index: ['index-1'], + interval: '5m', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + query: 'some query', + index: ['index-1'], + interval: '5m', + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, query, language] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score] does validate', () => { + const payload: CreateRulesSchema = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score, output_index] does validate', () => { + const payload: CreateRulesSchema = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score] does validate', () => { + const payload: CreateRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index] does validate', () => { + const payload: CreateRulesSchema = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('You can send in an empty array to threat', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + threat: [], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + ...getCreateRulesSchemaDecodedMock(), + threat: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index, threat] does validate', () => { + const payload: CreateRulesSchema = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + threat: [ + { + framework: 'someFramework', + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + threat: [ + { + framework: 'someFramework', + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + throttle: null, + version: 1, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('allows references to be sent as valid', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + references: ['index-1'], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + ...getCreateRulesSchemaDecodedMock(), + references: ['index-1'], + }; + expect(message.schema).toEqual(expected); + }); + + test('defaults references to an array if it is not sent in', () => { + const { references, ...noReferences } = getCreateRulesSchemaMock(); + const decoded = createRulesSchema.decode(noReferences); + const checked = exactCheck(noReferences, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + ...getCreateRulesSchemaDecodedMock(), + references: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('references cannot be numbers', () => { + const payload: Omit & { references: number[] } = { + ...getCreateRulesSchemaMock(), + references: [5], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('indexes cannot be numbers', () => { + const payload: Omit & { index: number[] } = { + ...getCreateRulesSchemaMock(), + index: [5], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "index"']); + expect(message.schema).toEqual({}); + }); + + test('saved_query type can have filters with it', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + filters: [], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + ...getCreateRulesSchemaDecodedMock(), + filters: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('filters cannot be a string', () => { + const payload: Omit & { filters: string } = { + ...getCreateRulesSchemaMock(), + filters: 'some string', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "some string" supplied to "filters"', + ]); + expect(message.schema).toEqual({}); + }); + + test('language validates with kuery', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + language: 'kuery', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + ...getCreateRulesSchemaDecodedMock(), + language: 'kuery', + }; + expect(message.schema).toEqual(expected); + }); + + test('language validates with lucene', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + language: 'lucene', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + ...getCreateRulesSchemaDecodedMock(), + language: 'lucene', + }; + expect(message.schema).toEqual(expected); + }); + + test('language does not validate with something made up', () => { + const payload: Omit & { language: string } = { + ...getCreateRulesSchemaMock(), + language: 'something-made-up', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "something-made-up" supplied to "language"', + ]); + expect(message.schema).toEqual({}); + }); + + test('max_signals cannot be negative', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + max_signals: -1, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('max_signals cannot be zero', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + max_signals: 0, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('max_signals can be 1', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + max_signals: 1, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + ...getCreateRulesSchemaDecodedMock(), + max_signals: 1, + }; + expect(message.schema).toEqual(expected); + }); + + test('You can optionally send in an array of tags', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + tags: ['tag_1', 'tag_2'], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + ...getCreateRulesSchemaDecodedMock(), + tags: ['tag_1', 'tag_2'], + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot send in an array of tags that are numbers', () => { + const payload: Omit & { tags: number[] } = { + ...getCreateRulesSchemaMock(), + tags: [0, 1, 2], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "0" supplied to ""', + 'Invalid value "1" supplied to ""', + 'Invalid value "2" supplied to ""', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of threat that are missing "framework"', () => { + const payload: Omit & { + threat: Array>>; + } = { + ...getCreateRulesSchemaMock(), + threat: [ + { + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "framework"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of threat that are missing "tactic"', () => { + const payload: Omit & { + threat: Array>>; + } = { + ...getCreateRulesSchemaMock(), + threat: [ + { + framework: 'fake', + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "tactic"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of threat that are missing "technique"', () => { + const payload: Omit & { + threat: Array>>; + } = { + ...getCreateRulesSchemaMock(), + threat: [ + { + framework: 'fake', + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + }, + ], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "technique"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You can optionally send in an array of false positives', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + false_positives: ['false_1', 'false_2'], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + ...getCreateRulesSchemaDecodedMock(), + false_positives: ['false_1', 'false_2'], + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot send in an array of false positives that are numbers', () => { + const payload: Omit & { false_positives: number[] } = { + ...getCreateRulesSchemaMock(), + false_positives: [5, 4], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to ""', + 'Invalid value "4" supplied to ""', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot set the immutable to a number when trying to create a rule', () => { + const payload: Omit & { immutable: number } = { + ...getCreateRulesSchemaMock(), + immutable: 5, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['invalid keys "immutable"']); + expect(message.schema).toEqual({}); + }); + + test('You cannot set the risk_score to 101', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + risk_score: 101, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "101" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot set the risk_score to -1', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + risk_score: -1, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to "risk_score"']); + expect(message.schema).toEqual({}); + }); + + test('You can set the risk_score to 0', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + risk_score: 0, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + ...getCreateRulesSchemaDecodedMock(), + risk_score: 0, + }; + expect(message.schema).toEqual(expected); + }); + + test('You can set the risk_score to 100', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + risk_score: 100, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + ...getCreateRulesSchemaDecodedMock(), + risk_score: 100, + }; + expect(message.schema).toEqual(expected); + }); + + test('You can set meta to any object you want', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + meta: { + somethingMadeUp: { somethingElse: true }, + }, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + ...getCreateRulesSchemaDecodedMock(), + meta: { + somethingMadeUp: { somethingElse: true }, + }, + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot create meta as a string', () => { + const payload: Omit & { meta: string } = { + ...getCreateRulesSchemaMock(), + meta: 'should not work', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "should not work" supplied to "meta"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You can omit the query string when filters are present', () => { + const { query, ...noQuery } = getCreateRulesSchemaMock(); + const payload: CreateRulesSchema = { + ...noQuery, + filters: [], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { query: expectedQuery, ...expectedNoQuery } = getCreateRulesSchemaDecodedMock(); + const expected: CreateRulesSchemaDecoded = { + ...expectedNoQuery, + filters: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('validates with timeline_id and timeline_title', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + timeline_id: 'timeline-id', + timeline_title: 'timeline-title', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + ...getCreateRulesSchemaDecodedMock(), + timeline_id: 'timeline-id', + timeline_title: 'timeline-title', + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot set the severity to a value other than low, medium, high, or critical', () => { + const payload: Omit & { severity: string } = { + ...getCreateRulesSchemaMock(), + severity: 'junk', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "junk" supplied to "severity"']); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are missing "group"', () => { + const payload: Omit = { + ...getCreateRulesSchemaMock(), + actions: [{ id: 'id', action_type_id: 'action_type_id', params: {} }], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "group"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are missing "id"', () => { + const payload: Omit = { + ...getCreateRulesSchemaMock(), + actions: [{ group: 'group', action_type_id: 'action_type_id', params: {} }], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "undefined" supplied to "id"']); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are missing "action_type_id"', () => { + const payload: Omit = { + ...getCreateRulesSchemaMock(), + actions: [{ group: 'group', id: 'id', params: {} }], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "action_type_id"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are missing "params"', () => { + const payload: Omit = { + ...getCreateRulesSchemaMock(), + actions: [{ group: 'group', id: 'id', action_type_id: 'action_type_id' }], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "params"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are including "actionTypeId"', () => { + const payload: Omit = { + ...getCreateRulesSchemaMock(), + actions: [ + { + group: 'group', + id: 'id', + actionTypeId: 'actionTypeId', + params: {}, + }, + ], + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "action_type_id"', + ]); + expect(message.schema).toEqual({}); + }); + + describe('note', () => { + test('You can set note to a string', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + note: '# documentation markdown here', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + ...getCreateRulesSchemaDecodedMock(), + note: '# documentation markdown here', + }; + expect(message.schema).toEqual(expected); + }); + + test('You can set note to an empty string', () => { + const payload: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + note: '', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + ...getCreateRulesSchemaDecodedMock(), + note: '', + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot create note as an object', () => { + const payload: Omit & { note: {} } = { + ...getCreateRulesSchemaMock(), + note: { + somethingHere: 'something else', + }, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + // TODO: Fix/Change the formatErrors to be better able to handle objects + 'Invalid value "[object Object]" supplied to "note"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note] does validate', () => { + const payload: CreateRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + note: '# some markdown', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + note: '# some markdown', + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + }); + + test('defaults interval to 5 min', () => { + const { interval, ...noInterval } = getCreateRulesSchemaMock(); + const payload: CreateRulesSchema = { + ...noInterval, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { interval: expectedInterval, ...expectedNoInterval } = getCreateRulesSchemaDecodedMock(); + const expected: CreateRulesSchemaDecoded = { + ...expectedNoInterval, + interval: '5m', + }; + expect(message.schema).toEqual(expected); + }); + + test('defaults max signals to 100', () => { + const { max_signals, ...noMaxSignals } = getCreateRulesSchemaMock(); + const payload: CreateRulesSchema = { + ...noMaxSignals, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { + max_signals: expectedMaxSignals, + ...expectedNoMaxSignals + } = getCreateRulesSchemaDecodedMock(); + const expected: CreateRulesSchemaDecoded = { + ...expectedNoMaxSignals, + max_signals: 100, + }; + expect(message.schema).toEqual(expected); + }); + + test('The default for "from" will be "now-6m"', () => { + const { from, ...noFrom } = getCreateRulesSchemaMock(); + const payload: CreateRulesSchema = { + ...noFrom, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { from: expectedFrom, ...expectedNoFrom } = getCreateRulesSchemaDecodedMock(); + const expected: CreateRulesSchemaDecoded = { + ...expectedNoFrom, + from: 'now-6m', + }; + expect(message.schema).toEqual(expected); + }); + + test('The default for "to" will be "now"', () => { + const { to, ...noTo } = getCreateRulesSchemaMock(); + const payload: CreateRulesSchema = { + ...noTo, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { to: expectedTo, ...expectedNoTo } = getCreateRulesSchemaDecodedMock(); + const expected: CreateRulesSchemaDecoded = { + ...expectedNoTo, + to: 'now', + }; + expect(message.schema).toEqual(expected); + }); + + test('The default for "actions" will be an empty array', () => { + const { actions, ...noActions } = getCreateRulesSchemaMock(); + const payload: CreateRulesSchema = { + ...noActions, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { actions: expectedActions, ...expectedNoActions } = getCreateRulesSchemaDecodedMock(); + const expected: CreateRulesSchemaDecoded = { + ...expectedNoActions, + actions: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('The default for "throttle" will be null', () => { + const { throttle, ...noThrottle } = getCreateRulesSchemaMock(); + const payload: CreateRulesSchema = { + ...noThrottle, + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { throttle: expectedThrottle, ...expectedNoThrottle } = getCreateRulesSchemaDecodedMock(); + const expected: CreateRulesSchemaDecoded = { + ...expectedNoThrottle, + throttle: null, + }; + expect(message.schema).toEqual(expected); + }); + + test('machine_learning type does validate', () => { + const payload: CreateRulesSchema = { + type: 'machine_learning', + anomaly_threshold: 50, + machine_learning_job_id: 'linux_anomalous_network_activity_ecs', + false_positives: [], + references: [], + risk_score: 50, + threat: [], + name: 'ss', + description: 'ss', + severity: 'low', + tags: [], + interval: '5m', + from: 'now-360s', + to: 'now', + meta: { from: '1m' }, + actions: [], + enabled: true, + throttle: 'no_actions', + rule_id: 'rule-1', + }; + + const decoded = createRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: CreateRulesSchemaDecoded = { + type: 'machine_learning', + anomaly_threshold: 50, + machine_learning_job_id: 'linux_anomalous_network_activity_ecs', + false_positives: [], + references: [], + risk_score: 50, + threat: [], + name: 'ss', + description: 'ss', + severity: 'low', + tags: [], + interval: '5m', + from: 'now-360s', + to: 'now', + meta: { from: '1m' }, + actions: [], + enabled: true, + throttle: 'no_actions', + exceptions_list: [], + max_signals: DEFAULT_MAX_SIGNALS, + version: 1, + rule_id: 'rule-1', + }; + expect(message.schema).toEqual(expected); + }); + + test('it generates a uuid v4 whenever you omit the rule_id', () => { + const { rule_id, ...noRuleId } = getCreateRulesSchemaMock(); + const decoded = createRulesSchema.decode(noRuleId); + const checked = exactCheck(noRuleId, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect((message.schema as CreateRulesSchemaDecoded).rule_id).toMatch( + /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i + ); + }); + + // TODO: The exception_list tests are skipped and empty until we re-integrate it from the lists plugin + describe.skip('exception_list', () => { + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and exceptions_list] does validate', () => {}); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and empty exceptions_list] does validate', () => {}); + + test('rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and invalid exceptions_list] does NOT validate', () => {}); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and non-existent exceptions_list] does validate with empty exceptions_list', () => {}); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.ts new file mode 100644 index 0000000000000..4e60201b8030e --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.ts @@ -0,0 +1,134 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; + +/* eslint-disable @typescript-eslint/camelcase */ +import { + description, + anomaly_threshold, + filters, + RuleId, + index, + output_index, + saved_id, + timeline_id, + timeline_title, + meta, + machine_learning_job_id, + risk_score, + MaxSignals, + name, + severity, + Tags, + To, + type, + Threat, + ThrottleOrNull, + note, + Version, + References, + Actions, + Enabled, + FalsePositives, + From, + Interval, + language, + query, +} from '../common/schemas'; +/* eslint-enable @typescript-eslint/camelcase */ + +import { DefaultStringArray } from '../types/default_string_array'; +import { DefaultActionsArray } from '../types/default_actions_array'; +import { DefaultBooleanTrue } from '../types/default_boolean_true'; +import { DefaultFromString } from '../types/default_from_string'; +import { DefaultIntervalString } from '../types/default_interval_string'; +import { DefaultMaxSignalsNumber } from '../types/default_max_signals_number'; +import { DefaultToString } from '../types/default_to_string'; +import { DefaultThreatArray } from '../types/default_threat_array'; +import { DefaultThrottleNull } from '../types/default_throttle_null'; +import { DefaultVersionNumber } from '../types/default_version_number'; +import { ListsDefaultArray, ListsDefaultArraySchema } from '../types/lists_default_array'; +import { DefaultUuid } from '../types/default_uuid'; + +export const createRulesSchema = t.intersection([ + t.exact( + t.type({ + description, + risk_score, + name, + severity, + type, + }) + ), + t.exact( + t.partial({ + actions: DefaultActionsArray, // defaults to empty actions array if not set during decode + anomaly_threshold, // defaults to undefined if not set during decode + enabled: DefaultBooleanTrue, // defaults to true if not set during decode + false_positives: DefaultStringArray, // defaults to empty string array if not set during decode + filters, // defaults to undefined if not set during decode + from: DefaultFromString, // defaults to "now-6m" if not set during decode + rule_id: DefaultUuid, + index, // defaults to undefined if not set during decode + interval: DefaultIntervalString, // defaults to "5m" if not set during decode + query, // defaults to undefined if not set during decode + language, // defaults to undefined if not set during decode + // TODO: output_index: This should be removed eventually + output_index, // defaults to "undefined" if not set during decode + saved_id, // defaults to "undefined" if not set during decode + timeline_id, // defaults to "undefined" if not set during decode + timeline_title, // defaults to "undefined" if not set during decode + meta, // defaults to "undefined" if not set during decode + machine_learning_job_id, // defaults to "undefined" if not set during decode + max_signals: DefaultMaxSignalsNumber, // defaults to DEFAULT_MAX_SIGNALS (100) if not set during decode + tags: DefaultStringArray, // defaults to empty string array if not set during decode + to: DefaultToString, // defaults to "now" if not set during decode + threat: DefaultThreatArray, // defaults to empty array if not set during decode + throttle: DefaultThrottleNull, // defaults to "null" if not set during decode + references: DefaultStringArray, // defaults to empty array of strings if not set during decode + note, // defaults to "undefined" if not set during decode + version: DefaultVersionNumber, // defaults to 1 if not set during decode + exceptions_list: ListsDefaultArray, // defaults to empty array if not set during decode + }) + ), +]); + +export type CreateRulesSchema = t.TypeOf; + +// This type is used after a decode since some things are defaults after a decode. +export type CreateRulesSchemaDecoded = Omit< + CreateRulesSchema, + | 'references' + | 'actions' + | 'enabled' + | 'false_positives' + | 'from' + | 'interval' + | 'max_signals' + | 'tags' + | 'to' + | 'threat' + | 'throttle' + | 'version' + | 'exceptions_list' + | 'rule_id' +> & { + references: References; + actions: Actions; + enabled: Enabled; + false_positives: FalsePositives; + from: From; + interval: Interval; + max_signals: MaxSignals; + tags: Tags; + to: To; + threat: Threat; + throttle: ThrottleOrNull; + version: Version; + exceptions_list: ListsDefaultArraySchema; + rule_id: RuleId; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_type_dependents.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_type_dependents.test.ts new file mode 100644 index 0000000000000..ebf0b2e591ca9 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_type_dependents.test.ts @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getCreateRulesSchemaMock } from './create_rules_schema.mock'; +import { CreateRulesSchema } from './create_rules_schema'; +import { createRuleValidateTypeDependents } from './create_rules_type_dependents'; + +describe('create_rules_type_dependents', () => { + test('saved_id is required when type is saved_query and will not validate without out', () => { + const schema: CreateRulesSchema = { ...getCreateRulesSchemaMock(), type: 'saved_query' }; + delete schema.saved_id; + const errors = createRuleValidateTypeDependents(schema); + expect(errors).toEqual(['when "type" is "saved_query", "saved_id" is required']); + }); + + test('saved_id is required when type is saved_query and validates with it', () => { + const schema: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + type: 'saved_query', + saved_id: '123', + }; + const errors = createRuleValidateTypeDependents(schema); + expect(errors).toEqual([]); + }); + + test('You cannot omit timeline_title when timeline_id is present', () => { + const schema: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + timeline_id: '123', + }; + delete schema.timeline_title; + const errors = createRuleValidateTypeDependents(schema); + expect(errors).toEqual(['when "timeline_id" exists, "timeline_title" must also exist']); + }); + + test('You cannot have empty string for timeline_title when timeline_id is present', () => { + const schema: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + timeline_id: '123', + timeline_title: '', + }; + const errors = createRuleValidateTypeDependents(schema); + expect(errors).toEqual(['"timeline_title" cannot be an empty string']); + }); + + test('You cannot have timeline_title with an empty timeline_id', () => { + const schema: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + timeline_id: '', + timeline_title: 'some-title', + }; + const errors = createRuleValidateTypeDependents(schema); + expect(errors).toEqual(['"timeline_id" cannot be an empty string']); + }); + + test('You cannot have timeline_title without timeline_id', () => { + const schema: CreateRulesSchema = { + ...getCreateRulesSchemaMock(), + timeline_title: 'some-title', + }; + delete schema.timeline_id; + const errors = createRuleValidateTypeDependents(schema); + expect(errors).toEqual(['when "timeline_title" exists, "timeline_id" must also exist']); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_type_dependents.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_type_dependents.ts new file mode 100644 index 0000000000000..aad2a2c4a9206 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_type_dependents.ts @@ -0,0 +1,105 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { CreateRulesSchema } from './create_rules_schema'; + +export const validateAnomalyThreshold = (rule: CreateRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.anomaly_threshold == null) { + return ['when "type" is "machine_learning" anomaly_threshold is required']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateQuery = (rule: CreateRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.query != null) { + return ['when "type" is "machine_learning", "query" cannot be set']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateLanguage = (rule: CreateRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.language != null) { + return ['when "type" is "machine_learning", "language" cannot be set']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateSavedId = (rule: CreateRulesSchema): string[] => { + if (rule.type === 'saved_query') { + if (rule.saved_id == null) { + return ['when "type" is "saved_query", "saved_id" is required']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateMachineLearningJobId = (rule: CreateRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.machine_learning_job_id == null) { + return ['when "type" is "machine_learning", "machine_learning_job_id" is required']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateTimelineId = (rule: CreateRulesSchema): string[] => { + if (rule.timeline_id != null) { + if (rule.timeline_title == null) { + return ['when "timeline_id" exists, "timeline_title" must also exist']; + } else if (rule.timeline_id === '') { + return ['"timeline_id" cannot be an empty string']; + } else { + return []; + } + } + return []; +}; + +export const validateTimelineTitle = (rule: CreateRulesSchema): string[] => { + if (rule.timeline_title != null) { + if (rule.timeline_id == null) { + return ['when "timeline_title" exists, "timeline_id" must also exist']; + } else if (rule.timeline_title === '') { + return ['"timeline_title" cannot be an empty string']; + } else { + return []; + } + } + return []; +}; + +export const createRuleValidateTypeDependents = (schema: CreateRulesSchema): string[] => { + return [ + ...validateAnomalyThreshold(schema), + ...validateQuery(schema), + ...validateLanguage(schema), + ...validateSavedId(schema), + ...validateMachineLearningJobId(schema), + ...validateTimelineId(schema), + ...validateTimelineTitle(schema), + ]; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.test.ts new file mode 100644 index 0000000000000..3e9799a5ad2f9 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.test.ts @@ -0,0 +1,159 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + exportRulesQuerySchema, + exportRulesSchema, + ExportRulesSchema, + ExportRulesQuerySchema, + ExportRulesQuerySchemaDecoded, +} from './export_rules_schema'; +import { exactCheck } from '../../../exact_check'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { left } from 'fp-ts/lib/Either'; + +describe('create rules schema', () => { + describe('exportRulesSchema', () => { + test('null value or absent values validate', () => { + const payload: Partial = null; + + const decoded = exportRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('empty object does not validate', () => { + const payload = {}; + + const decoded = exportRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + // TODO: Change formatter to display a better value than [object Object] + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "objects"', + 'Invalid value "[object Object]" supplied to ""', + ]); + expect(message.schema).toEqual(payload); + }); + + test('empty object array does validate', () => { + const payload: ExportRulesSchema = { objects: [] }; + + const decoded = exportRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('array with rule_id validates', () => { + const payload: ExportRulesSchema = { objects: [{ rule_id: 'test-1' }] }; + + const decoded = exportRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('array with id does not validate as we do not allow that on purpose since we export rule_id', () => { + const payload: Omit & { objects: [{ id: string }] } = { + objects: [{ id: '4a7ff83d-3055-4bb2-ba68-587b9c6c15a4' }], + }; + + const decoded = exportRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + // TODO: Change formatter to display a better value than [object Object] + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "objects,rule_id"', + 'Invalid value "[object Object]" supplied to ""', + ]); + expect(message.schema).toEqual({}); + }); + }); + + describe('exportRulesQuerySchema', () => { + test('default value for file_name is export.ndjson and default for exclude_export_details is false', () => { + const payload: Partial = {}; + + const decoded = exportRulesQuerySchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ExportRulesQuerySchemaDecoded = { + file_name: 'export.ndjson', + exclude_export_details: false, + }; + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(expected); + }); + + test('file_name validates', () => { + const payload: ExportRulesQuerySchema = { + file_name: 'test.ndjson', + }; + + const decoded = exportRulesQuerySchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ExportRulesQuerySchemaDecoded = { + file_name: 'test.ndjson', + exclude_export_details: false, + }; + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(expected); + }); + + test('file_name does not validate with a number', () => { + const payload: Omit & { file_name: number } = { + file_name: 10, + }; + + const decoded = exportRulesQuerySchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "10" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('exclude_export_details validates with a boolean true', () => { + const payload: ExportRulesQuerySchema = { + exclude_export_details: true, + }; + + const decoded = exportRulesQuerySchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ExportRulesQuerySchemaDecoded = { + exclude_export_details: true, + file_name: 'export.ndjson', + }; + expect(message.schema).toEqual(expected); + }); + + test('exclude_export_details does not validate with a string', () => { + const payload: Omit & { + exclude_export_details: string; + } = { + exclude_export_details: 'invalid string', + }; + + const decoded = exportRulesQuerySchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "invalid string" supplied to ""', + ]); + expect(message.schema).toEqual({}); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.ts new file mode 100644 index 0000000000000..75fa2da92b787 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; + +/* eslint-disable @typescript-eslint/camelcase */ +import { rule_id, FileName, ExcludeExportDetails } from '../common/schemas'; +/* eslint-enable @typescript-eslint/camelcase */ + +import { DefaultExportFileName } from '../types/default_export_file_name'; +import { DefaultStringBooleanFalse } from '../types/default_string_boolean_false'; + +const objects = t.array(t.exact(t.type({ rule_id }))); +export const exportRulesSchema = t.union([t.exact(t.type({ objects })), t.null]); +export type ExportRulesSchema = t.TypeOf; +export type ExportRulesSchemaDecoded = ExportRulesSchema; + +export const exportRulesQuerySchema = t.exact( + t.partial({ file_name: DefaultExportFileName, exclude_export_details: DefaultStringBooleanFalse }) +); + +export type ExportRulesQuerySchema = t.TypeOf; + +export type ExportRulesQuerySchemaDecoded = Omit< + ExportRulesQuerySchema, + 'file_name' | 'exclude_export_details' +> & { + file_name: FileName; + exclude_export_details: ExcludeExportDetails; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rule_statuses_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rule_statuses_schema.ts new file mode 100644 index 0000000000000..1969d9d798d23 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rule_statuses_schema.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; + +export const findRulesStatusesSchema = t.exact( + t.type({ + ids: t.array(t.string), + }) +); + +export type FindRulesStatusesSchema = t.TypeOf; + +export type FindRulesStatusesSchemaDecoded = FindRulesStatusesSchema; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rule_type_dependents.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rule_type_dependents.test.ts new file mode 100644 index 0000000000000..e86e67e47e460 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rule_type_dependents.test.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { FindRulesSchema } from './find_rules_schema'; +import { findRuleValidateTypeDependents } from './find_rules_type_dependents'; + +describe('find_rules_type_dependents', () => { + test('You can have an empty sort_field and empty sort_order', () => { + const schema: FindRulesSchema = {}; + const errors = findRuleValidateTypeDependents(schema); + expect(errors).toEqual([]); + }); + + test('You can have both a sort_field and and a sort_order', () => { + const schema: FindRulesSchema = { + sort_field: 'some field', + sort_order: 'asc', + }; + const errors = findRuleValidateTypeDependents(schema); + expect(errors).toEqual([]); + }); + + test('You cannot have sort_field without sort_order', () => { + const schema: FindRulesSchema = { + sort_field: 'some field', + }; + const errors = findRuleValidateTypeDependents(schema); + expect(errors).toEqual([ + 'when "sort_order" and "sort_field" must exist together or not at all', + ]); + }); + + test('You cannot have sort_order without sort_field', () => { + const schema: FindRulesSchema = { + sort_order: 'asc', + }; + const errors = findRuleValidateTypeDependents(schema); + expect(errors).toEqual([ + 'when "sort_order" and "sort_field" must exist together or not at all', + ]); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.test.ts new file mode 100644 index 0000000000000..46e6ee82055a5 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.test.ts @@ -0,0 +1,198 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { exactCheck } from '../../../exact_check'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { left } from 'fp-ts/lib/Either'; +import { FindRulesSchema, findRulesSchema } from './find_rules_schema'; + +describe('find_rules_schema', () => { + test('empty objects do validate', () => { + const payload: FindRulesSchema = {}; + + const decoded = findRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual({ + page: 1, + per_page: 20, + }); + }); + + test('all values validate', () => { + const payload: FindRulesSchema = { + per_page: 5, + page: 1, + sort_field: 'some field', + fields: ['field 1', 'field 2'], + filter: 'some filter', + sort_order: 'asc', + }; + + const decoded = findRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('made up parameters do not validate', () => { + const payload: Partial & { madeUp: string } = { madeUp: 'invalid value' }; + + const decoded = findRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['invalid keys "madeUp"']); + expect(message.schema).toEqual({}); + }); + + test('per_page validates', () => { + const payload: FindRulesSchema = { + per_page: 5, + }; + + const decoded = findRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect((message.schema as FindRulesSchema).per_page).toEqual(payload.per_page); + }); + + test('page validates', () => { + const payload: FindRulesSchema = { + page: 5, + }; + + const decoded = findRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect((message.schema as FindRulesSchema).page).toEqual(payload.page); + }); + + test('sort_field validates', () => { + const payload: FindRulesSchema = { + sort_field: 'value', + }; + + const decoded = findRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect((message.schema as FindRulesSchema).sort_field).toEqual('value'); + }); + + test('fields validates with a string', () => { + const payload: FindRulesSchema = { + fields: ['some value'], + }; + + const decoded = findRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect((message.schema as FindRulesSchema).fields).toEqual(payload.fields); + }); + + test('fields validates with multiple strings', () => { + const payload: FindRulesSchema = { + fields: ['some value 1', 'some value 2'], + }; + + const decoded = findRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect((message.schema as FindRulesSchema).fields).toEqual(payload.fields); + }); + + test('fields does not validate with a number', () => { + const payload: Omit & { fields: number } = { + fields: 5, + }; + + const decoded = findRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "fields"']); + expect(message.schema).toEqual({}); + }); + + test('per_page has a default of 20', () => { + const payload: FindRulesSchema = {}; + + const decoded = findRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect((message.schema as FindRulesSchema).per_page).toEqual(20); + }); + + test('page has a default of 1', () => { + const payload: FindRulesSchema = {}; + + const decoded = findRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect((message.schema as FindRulesSchema).page).toEqual(1); + }); + + test('filter works with a string', () => { + const payload: FindRulesSchema = { + filter: 'some value 1', + }; + + const decoded = findRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect((message.schema as FindRulesSchema).filter).toEqual(payload.filter); + }); + + test('filter does not work with a number', () => { + const payload: Omit & { filter: number } = { + filter: 5, + }; + + const decoded = findRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "filter"']); + expect(message.schema).toEqual({}); + }); + + test('sort_order validates with desc and sort_field', () => { + const payload: FindRulesSchema = { + sort_order: 'desc', + sort_field: 'some field', + }; + + const decoded = findRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect((message.schema as FindRulesSchema).sort_order).toEqual(payload.sort_order); + expect((message.schema as FindRulesSchema).sort_field).toEqual(payload.sort_field); + }); + + test('sort_order does not validate with a string other than asc and desc', () => { + const payload: Omit & { sort_order: string } = { + sort_order: 'some other string', + sort_field: 'some field', + }; + + const decoded = findRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "some other string" supplied to "sort_order"', + ]); + expect(message.schema).toEqual({}); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.ts new file mode 100644 index 0000000000000..87076803c9582 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; + +/* eslint-disable @typescript-eslint/camelcase */ +import { queryFilter, fields, sort_field, sort_order, PerPage, Page } from '../common/schemas'; +import { DefaultPerPage } from '../types/default_per_page'; +import { DefaultPage } from '../types/default_page'; +/* eslint-enable @typescript-eslint/camelcase */ + +export const findRulesSchema = t.exact( + t.partial({ + fields, + filter: queryFilter, + per_page: DefaultPerPage, // defaults to "20" if not sent in during decode + page: DefaultPage, // defaults to "1" if not sent in during decode + sort_field, + sort_order, + }) +); + +export type FindRulesSchema = t.TypeOf; +export type FindRulesSchemaDecoded = Omit & { + per_page: PerPage; + page: Page; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_type_dependents.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_type_dependents.ts new file mode 100644 index 0000000000000..6916f102e4f57 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_type_dependents.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { FindRulesSchema } from './find_rules_schema'; + +export const validateSortOrder = (find: FindRulesSchema): string[] => { + if (find.sort_order != null || find.sort_field != null) { + if (find.sort_order == null || find.sort_field == null) { + return ['when "sort_order" and "sort_field" must exist together or not at all']; + } else { + return []; + } + } else { + return []; + } +}; + +export const findRuleValidateTypeDependents = (schema: FindRulesSchema): string[] => { + return [...validateSortOrder(schema)]; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.mock.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.mock.ts new file mode 100644 index 0000000000000..92fab202c9ddc --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.mock.ts @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ImportRulesSchema, ImportRulesSchemaDecoded } from './import_rules_schema'; +import { DEFAULT_MAX_SIGNALS } from '../../../constants'; + +export const getImportRulesSchemaMock = (): ImportRulesSchema => ({ + description: 'some description', + name: 'Query with a rule id', + query: 'user.name: root or user.name: admin', + severity: 'high', + type: 'query', + risk_score: 55, + language: 'kuery', + rule_id: 'rule-1', +}); + +export const getImportRulesSchemaDecodedMock = (): ImportRulesSchemaDecoded => ({ + description: 'some description', + name: 'Query with a rule id', + query: 'user.name: root or user.name: admin', + severity: 'high', + type: 'query', + risk_score: 55, + language: 'kuery', + references: [], + actions: [], + enabled: true, + false_positives: [], + from: 'now-6m', + interval: '5m', + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + to: 'now', + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + rule_id: 'rule-1', + immutable: false, +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts new file mode 100644 index 0000000000000..be2c3e046fe91 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts @@ -0,0 +1,1579 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { exactCheck } from '../../../exact_check'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { left } from 'fp-ts/lib/Either'; +import { + ImportRulesSchema, + importRulesSchema, + ImportRulesSchemaDecoded, + importRulesQuerySchema, + ImportRulesQuerySchema, + importRulesPayloadSchema, + ImportRulesPayloadSchema, +} from './import_rules_schema'; +import { + getImportRulesSchemaMock, + getImportRulesSchemaDecodedMock, +} from './import_rules_schema.mock'; +import { DEFAULT_MAX_SIGNALS } from '../../../constants'; + +describe('import rules schema', () => { + test('empty objects do not validate', () => { + const payload: Partial = {}; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "description"', + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + 'Invalid value "undefined" supplied to "rule_id"', + ]); + expect(message.schema).toEqual({}); + }); + + test('made up values do not validate', () => { + const payload: ImportRulesSchema & { madeUp: string } = { + ...getImportRulesSchemaMock(), + madeUp: 'hi', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['invalid keys "madeUp"']); + expect(message.schema).toEqual({}); + }); + + test('[rule_id] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "description"', + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type, interval] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type, interval, index] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + interval: '5m', + index: ['index-1'], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type, query, index, interval] does validate', () => { + const payload: ImportRulesSchema = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + query: 'some query', + index: ['index-1'], + interval: '5m', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + query: 'some query', + index: ['index-1'], + interval: '5m', + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + immutable: false, + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, query, language] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score] does validate', () => { + const payload: ImportRulesSchema = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + immutable: false, + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score, output_index] does validate', () => { + const payload: ImportRulesSchema = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + immutable: false, + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score] does validate', () => { + const payload: ImportRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + immutable: false, + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index] does validate', () => { + const payload: ImportRulesSchema = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + immutable: false, + }; + expect(message.schema).toEqual(expected); + }); + + test('You can send in an empty array to threat', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + threat: [], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + threat: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index, threat] does validate', () => { + const payload: ImportRulesSchema = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + threat: [ + { + framework: 'someFramework', + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + immutable: false, + threat: [ + { + framework: 'someFramework', + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + throttle: null, + version: 1, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('allows references to be sent as valid', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + references: ['index-1'], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + references: ['index-1'], + }; + expect(message.schema).toEqual(expected); + }); + + test('defaults references to an array if it is not sent in', () => { + const { references, ...noReferences } = getImportRulesSchemaMock(); + const decoded = importRulesSchema.decode(noReferences); + const checked = exactCheck(noReferences, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + references: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('references cannot be numbers', () => { + const payload: Omit & { references: number[] } = { + ...getImportRulesSchemaMock(), + references: [5], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('indexes cannot be numbers', () => { + const payload: Omit & { index: number[] } = { + ...getImportRulesSchemaMock(), + index: [5], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "index"']); + expect(message.schema).toEqual({}); + }); + + test('defaults interval to 5 min', () => { + const { interval, ...noInterval } = getImportRulesSchemaMock(); + const payload: ImportRulesSchema = { + ...noInterval, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { interval: expectedInterval, ...expectedNoInterval } = getImportRulesSchemaDecodedMock(); + const expected: ImportRulesSchemaDecoded = { + ...expectedNoInterval, + interval: '5m', + }; + expect(message.schema).toEqual(expected); + }); + + test('defaults max signals to 100', () => { + const { max_signals, ...noMaxSignals } = getImportRulesSchemaMock(); + const payload: ImportRulesSchema = { + ...noMaxSignals, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { + max_signals: expectedMaxSignals, + ...expectedNoMaxSignals + } = getImportRulesSchemaDecodedMock(); + const expected: ImportRulesSchemaDecoded = { + ...expectedNoMaxSignals, + max_signals: 100, + }; + expect(message.schema).toEqual(expected); + }); + + test('saved_query type can have filters with it', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + filters: [], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + filters: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('filters cannot be a string', () => { + const payload: Omit & { filters: string } = { + ...getImportRulesSchemaMock(), + filters: 'some string', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "some string" supplied to "filters"', + ]); + expect(message.schema).toEqual({}); + }); + + test('language validates with kuery', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + language: 'kuery', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + language: 'kuery', + }; + expect(message.schema).toEqual(expected); + }); + + test('language validates with lucene', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + language: 'lucene', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + language: 'lucene', + }; + expect(message.schema).toEqual(expected); + }); + + test('language does not validate with something made up', () => { + const payload: Omit & { language: string } = { + ...getImportRulesSchemaMock(), + language: 'something-made-up', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "something-made-up" supplied to "language"', + ]); + expect(message.schema).toEqual({}); + }); + + test('max_signals cannot be negative', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + max_signals: -1, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('max_signals cannot be zero', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + max_signals: 0, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('max_signals can be 1', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + max_signals: 1, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + max_signals: 1, + }; + expect(message.schema).toEqual(expected); + }); + + test('You can optionally send in an array of tags', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + tags: ['tag_1', 'tag_2'], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + tags: ['tag_1', 'tag_2'], + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot send in an array of tags that are numbers', () => { + const payload: Omit & { tags: number[] } = { + ...getImportRulesSchemaMock(), + tags: [0, 1, 2], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "0" supplied to ""', + 'Invalid value "1" supplied to ""', + 'Invalid value "2" supplied to ""', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of threat that are missing "framework"', () => { + const payload: Omit & { + threat: Array>>; + } = { + ...getImportRulesSchemaMock(), + threat: [ + { + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "framework"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of threat that are missing "tactic"', () => { + const payload: Omit & { + threat: Array>>; + } = { + ...getImportRulesSchemaMock(), + threat: [ + { + framework: 'fake', + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "tactic"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of threat that are missing "technique"', () => { + const payload: Omit & { + threat: Array>>; + } = { + ...getImportRulesSchemaMock(), + threat: [ + { + framework: 'fake', + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + }, + ], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "technique"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You can optionally send in an array of false positives', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + false_positives: ['false_1', 'false_2'], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + false_positives: ['false_1', 'false_2'], + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot send in an array of false positives that are numbers', () => { + const payload: Omit & { false_positives: number[] } = { + ...getImportRulesSchemaMock(), + false_positives: [5, 4], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to ""', + 'Invalid value "4" supplied to ""', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot set the immutable to a number when trying to create a rule', () => { + const payload: Omit & { immutable: number } = { + ...getImportRulesSchemaMock(), + immutable: 5, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "immutable"']); + expect(message.schema).toEqual({}); + }); + + test('You can optionally set the immutable to be false', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + immutable: false, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(getImportRulesSchemaDecodedMock()); + }); + + test('You cannot set the immutable to be true', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + immutable: true, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "true" supplied to "immutable"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot set the immutable to be a number', () => { + const payload: Omit & { immutable: number } = { + ...getImportRulesSchemaMock(), + immutable: 5, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "immutable"']); + expect(message.schema).toEqual({}); + }); + + test('You cannot set the risk_score to 101', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + risk_score: 101, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "101" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot set the risk_score to -1', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + risk_score: -1, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to "risk_score"']); + expect(message.schema).toEqual({}); + }); + + test('You can set the risk_score to 0', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + risk_score: 0, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + risk_score: 0, + }; + expect(message.schema).toEqual(expected); + }); + + test('You can set the risk_score to 100', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + risk_score: 100, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + risk_score: 100, + }; + expect(message.schema).toEqual(expected); + }); + + test('You can set meta to any object you want', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + meta: { + somethingMadeUp: { somethingElse: true }, + }, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + meta: { + somethingMadeUp: { somethingElse: true }, + }, + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot create meta as a string', () => { + const payload: Omit & { meta: string } = { + ...getImportRulesSchemaMock(), + meta: 'should not work', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "should not work" supplied to "meta"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You can omit the query string when filters are present', () => { + const { query, ...noQuery } = getImportRulesSchemaMock(); + const payload: ImportRulesSchema = { + ...noQuery, + filters: [], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { query: expectedQuery, ...expectedNoQuery } = getImportRulesSchemaDecodedMock(); + const expected: ImportRulesSchemaDecoded = { + ...expectedNoQuery, + filters: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('validates with timeline_id and timeline_title', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + timeline_id: 'timeline-id', + timeline_title: 'timeline-title', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + timeline_id: 'timeline-id', + timeline_title: 'timeline-title', + }; + expect(message.schema).toEqual(expected); + }); + + test('rule_id is required and you cannot get by with just id', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612', + }; + delete payload.rule_id; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "rule_id"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it validates with created_at, updated_at, created_by, updated_by values', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + created_at: '2020-01-09T06:15:24.749Z', + updated_at: '2020-01-09T06:15:24.749Z', + created_by: 'Braden Hassanabad', + updated_by: 'Evan Hassanabad', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + created_at: '2020-01-09T06:15:24.749Z', + updated_at: '2020-01-09T06:15:24.749Z', + created_by: 'Braden Hassanabad', + updated_by: 'Evan Hassanabad', + }; + expect(message.schema).toEqual(expected); + }); + + test('it does not validate with epoch strings for created_at', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + created_at: '1578550728650', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "1578550728650" supplied to "created_at"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it does not validate with epoch strings for updated_at', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + updated_at: '1578550728650', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "1578550728650" supplied to "updated_at"', + ]); + expect(message.schema).toEqual({}); + }); + + describe('importRulesQuerySchema', () => { + test('overwrite gets a default value of false', () => { + const payload: ImportRulesQuerySchema = {}; + + const decoded = importRulesQuerySchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual({ + overwrite: false, + }); + }); + + test('overwrite validates with a boolean true', () => { + const payload: ImportRulesQuerySchema = { overwrite: true }; + + const decoded = importRulesQuerySchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual({ + overwrite: true, + }); + }); + + test('overwrite does not validate with a weird string', () => { + const payload: Omit & { overwrite: string } = { + overwrite: 'invalid-string', + }; + + const decoded = importRulesQuerySchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "invalid-string" supplied to ""', + ]); + expect(message.schema).toEqual({}); + }); + }); + + describe('importRulesPayloadSchema', () => { + test('does not validate with an empty object', () => { + const payload = {}; + + const decoded = importRulesPayloadSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "file"', + ]); + expect(message.schema).toEqual({}); + }); + + test('does not validate with a made string', () => { + const payload: Omit & { madeUpKey: string } = { + madeUpKey: 'madeupstring', + }; + + const decoded = importRulesPayloadSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "file"', + ]); + expect(message.schema).toEqual({}); + }); + + test('does validate with a file object', () => { + const payload: ImportRulesPayloadSchema = { file: {} }; + + const decoded = importRulesPayloadSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + }); + + test('The default for "from" will be "now-6m"', () => { + const { from, ...noFrom } = getImportRulesSchemaMock(); + const payload: ImportRulesSchema = { + ...noFrom, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { from: expectedFrom, ...expectedNoFrom } = getImportRulesSchemaDecodedMock(); + const expected: ImportRulesSchemaDecoded = { + ...expectedNoFrom, + from: 'now-6m', + }; + expect(message.schema).toEqual(expected); + }); + + test('The default for "to" will be "now"', () => { + const { to, ...noTo } = getImportRulesSchemaMock(); + const payload: ImportRulesSchema = { + ...noTo, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { to: expectedTo, ...expectedNoTo } = getImportRulesSchemaDecodedMock(); + const expected: ImportRulesSchemaDecoded = { + ...expectedNoTo, + to: 'now', + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot set the severity to a value other than low, medium, high, or critical', () => { + const payload: Omit & { severity: string } = { + ...getImportRulesSchemaMock(), + severity: 'junk', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "junk" supplied to "severity"']); + expect(message.schema).toEqual({}); + }); + + test('The default for "actions" will be an empty array', () => { + const { actions, ...noActions } = getImportRulesSchemaMock(); + const payload: ImportRulesSchema = { + ...noActions, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { actions: expectedActions, ...expectedNoActions } = getImportRulesSchemaDecodedMock(); + const expected: ImportRulesSchemaDecoded = { + ...expectedNoActions, + actions: [], + }; + expect(message.schema).toEqual(expected); + }); + test('You cannot send in an array of actions that are missing "group"', () => { + const payload: Omit = { + ...getImportRulesSchemaMock(), + actions: [{ id: 'id', action_type_id: 'action_type_id', params: {} }], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "group"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are missing "id"', () => { + const payload: Omit = { + ...getImportRulesSchemaMock(), + actions: [{ group: 'group', action_type_id: 'action_type_id', params: {} }], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "undefined" supplied to "id"']); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are missing "action_type_id"', () => { + const payload: Omit = { + ...getImportRulesSchemaMock(), + actions: [{ group: 'group', id: 'id', params: {} }], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "action_type_id"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are missing "params"', () => { + const payload: Omit = { + ...getImportRulesSchemaMock(), + actions: [{ group: 'group', id: 'id', action_type_id: 'action_type_id' }], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "params"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are including "actionTypeId"', () => { + const payload: Omit = { + ...getImportRulesSchemaMock(), + actions: [ + { + group: 'group', + id: 'id', + actionTypeId: 'actionTypeId', + params: {}, + }, + ], + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "action_type_id"', + ]); + expect(message.schema).toEqual({}); + }); + + test('The default for "throttle" will be null', () => { + const { throttle, ...noThrottle } = getImportRulesSchemaMock(); + const payload: ImportRulesSchema = { + ...noThrottle, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { throttle: expectedThrottle, ...expectedNoThrottle } = getImportRulesSchemaDecodedMock(); + const expected: ImportRulesSchemaDecoded = { + ...expectedNoThrottle, + throttle: null, + }; + expect(message.schema).toEqual(expected); + }); + + describe('note', () => { + test('You can set note to a string', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + note: '# documentation markdown here', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + note: '# documentation markdown here', + }; + expect(message.schema).toEqual(expected); + }); + + test('You can set note to an empty string', () => { + const payload: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + note: '', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + ...getImportRulesSchemaDecodedMock(), + note: '', + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot create note as an object', () => { + const payload: Omit & { note: {} } = { + ...getImportRulesSchemaMock(), + note: { + somethingHere: 'something else', + }, + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + // TODO: Fix/Change the formatErrors to be better able to handle objects + 'Invalid value "[object Object]" supplied to "note"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note] does validate', () => { + const payload: ImportRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + note: '# some markdown', + }; + + const decoded = importRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: ImportRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + note: '# some markdown', + references: [], + actions: [], + enabled: true, + false_positives: [], + immutable: false, + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + version: 1, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + }); + + // TODO: The exception_list tests are skipped and empty until we re-integrate it from the lists plugin + describe.skip('exception_list', () => { + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and exceptions_list] does validate', () => {}); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and empty exceptions_list] does validate', () => {}); + + test('rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and invalid exceptions_list] does NOT validate', () => {}); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and non-existent exceptions_list] does validate with empty exceptions_list', () => {}); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.ts new file mode 100644 index 0000000000000..a2110263e8e51 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.ts @@ -0,0 +1,180 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; + +/* eslint-disable @typescript-eslint/camelcase */ +import { + description, + anomaly_threshold, + filters, + RuleId, + index, + output_index, + saved_id, + timeline_id, + timeline_title, + meta, + machine_learning_job_id, + risk_score, + MaxSignals, + name, + severity, + Tags, + To, + type, + Threat, + ThrottleOrNull, + note, + Version, + References, + Actions, + Enabled, + FalsePositives, + From, + Interval, + language, + query, + rule_id, + id, + created_at, + updated_at, + created_by, + updated_by, +} from '../common/schemas'; +/* eslint-enable @typescript-eslint/camelcase */ + +import { DefaultStringArray } from '../types/default_string_array'; +import { DefaultActionsArray } from '../types/default_actions_array'; +import { DefaultBooleanTrue } from '../types/default_boolean_true'; +import { DefaultFromString } from '../types/default_from_string'; +import { DefaultIntervalString } from '../types/default_interval_string'; +import { DefaultMaxSignalsNumber } from '../types/default_max_signals_number'; +import { DefaultToString } from '../types/default_to_string'; +import { DefaultThreatArray } from '../types/default_threat_array'; +import { DefaultThrottleNull } from '../types/default_throttle_null'; +import { DefaultVersionNumber } from '../types/default_version_number'; +import { ListsDefaultArray, ListsDefaultArraySchema } from '../types/lists_default_array'; +import { OnlyFalseAllowed } from '../types/only_false_allowed'; +import { DefaultStringBooleanFalse } from '../types/default_string_boolean_false'; + +/** + * Differences from this and the createRulesSchema are + * - rule_id is required + * - id is optional (but ignored in the import code - rule_id is exclusively used for imports) + * - immutable is optional but if it is any value other than false it will be rejected + * - created_at is optional (but ignored in the import code) + * - updated_at is optional (but ignored in the import code) + * - created_by is optional (but ignored in the import code) + * - updated_by is optional (but ignored in the import code) + */ +export const importRulesSchema = t.intersection([ + t.exact( + t.type({ + description, + risk_score, + name, + severity, + type, + rule_id, + }) + ), + t.exact( + t.partial({ + id, // defaults to undefined if not set during decode + actions: DefaultActionsArray, // defaults to empty actions array if not set during decode + anomaly_threshold, // defaults to undefined if not set during decode + enabled: DefaultBooleanTrue, // defaults to true if not set during decode + false_positives: DefaultStringArray, // defaults to empty string array if not set during decode + filters, // defaults to undefined if not set during decode + from: DefaultFromString, // defaults to "now-6m" if not set during decode + index, // defaults to undefined if not set during decode + immutable: OnlyFalseAllowed, // defaults to "false" if not set during decode + interval: DefaultIntervalString, // defaults to "5m" if not set during decode + query, // defaults to undefined if not set during decode + language, // defaults to undefined if not set during decode + // TODO: output_index: This should be removed eventually + output_index, // defaults to "undefined" if not set during decode + saved_id, // defaults to "undefined" if not set during decode + timeline_id, // defaults to "undefined" if not set during decode + timeline_title, // defaults to "undefined" if not set during decode + meta, // defaults to "undefined" if not set during decode + machine_learning_job_id, // defaults to "undefined" if not set during decode + max_signals: DefaultMaxSignalsNumber, // defaults to DEFAULT_MAX_SIGNALS (100) if not set during decode + tags: DefaultStringArray, // defaults to empty string array if not set during decode + to: DefaultToString, // defaults to "now" if not set during decode + threat: DefaultThreatArray, // defaults to empty array if not set during decode + throttle: DefaultThrottleNull, // defaults to "null" if not set during decode + references: DefaultStringArray, // defaults to empty array of strings if not set during decode + note, // defaults to "undefined" if not set during decode + version: DefaultVersionNumber, // defaults to 1 if not set during decode + exceptions_list: ListsDefaultArray, // defaults to empty array if not set during decode + created_at, // defaults "undefined" if not set during decode + updated_at, // defaults "undefined" if not set during decode + created_by, // defaults "undefined" if not set during decode + updated_by, // defaults "undefined" if not set during decode + }) + ), +]); + +export type ImportRulesSchema = t.TypeOf; + +// This type is used after a decode since some things are defaults after a decode. +export type ImportRulesSchemaDecoded = Omit< + ImportRulesSchema, + | 'references' + | 'actions' + | 'enabled' + | 'false_positives' + | 'from' + | 'interval' + | 'max_signals' + | 'tags' + | 'to' + | 'threat' + | 'throttle' + | 'version' + | 'exceptions_list' + | 'rule_id' + | 'immutable' +> & { + references: References; + actions: Actions; + enabled: Enabled; + false_positives: FalsePositives; + from: From; + interval: Interval; + max_signals: MaxSignals; + tags: Tags; + to: To; + threat: Threat; + throttle: ThrottleOrNull; + version: Version; + exceptions_list: ListsDefaultArraySchema; + rule_id: RuleId; + immutable: false; +}; + +export const importRulesQuerySchema = t.exact( + t.partial({ + overwrite: DefaultStringBooleanFalse, + }) +); + +export type ImportRulesQuerySchema = t.TypeOf; +export type ImportRulesQuerySchemaDecoded = Omit & { + overwrite: boolean; +}; + +export const importRulesPayloadSchema = t.exact( + t.type({ + file: t.object, + }) +); + +export type ImportRulesPayloadSchema = t.TypeOf; + +export type ImportRulesPayloadSchemaDecoded = ImportRulesPayloadSchema; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_type_dependents.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_type_dependents.test.ts new file mode 100644 index 0000000000000..f9b989c81e533 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_type_dependents.test.ts @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getImportRulesSchemaMock } from './import_rules_schema.mock'; +import { ImportRulesSchema } from './import_rules_schema'; +import { importRuleValidateTypeDependents } from './import_rules_type_dependents'; + +describe('import_rules_type_dependents', () => { + test('saved_id is required when type is saved_query and will not validate without out', () => { + const schema: ImportRulesSchema = { ...getImportRulesSchemaMock(), type: 'saved_query' }; + delete schema.saved_id; + const errors = importRuleValidateTypeDependents(schema); + expect(errors).toEqual(['when "type" is "saved_query", "saved_id" is required']); + }); + + test('saved_id is required when type is saved_query and validates with it', () => { + const schema: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + type: 'saved_query', + saved_id: '123', + }; + const errors = importRuleValidateTypeDependents(schema); + expect(errors).toEqual([]); + }); + + test('You cannot omit timeline_title when timeline_id is present', () => { + const schema: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + timeline_id: '123', + }; + delete schema.timeline_title; + const errors = importRuleValidateTypeDependents(schema); + expect(errors).toEqual(['when "timeline_id" exists, "timeline_title" must also exist']); + }); + + test('You cannot have empty string for timeline_title when timeline_id is present', () => { + const schema: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + timeline_id: '123', + timeline_title: '', + }; + const errors = importRuleValidateTypeDependents(schema); + expect(errors).toEqual(['"timeline_title" cannot be an empty string']); + }); + + test('You cannot have timeline_title with an empty timeline_id', () => { + const schema: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + timeline_id: '', + timeline_title: 'some-title', + }; + const errors = importRuleValidateTypeDependents(schema); + expect(errors).toEqual(['"timeline_id" cannot be an empty string']); + }); + + test('You cannot have timeline_title without timeline_id', () => { + const schema: ImportRulesSchema = { + ...getImportRulesSchemaMock(), + timeline_title: 'some-title', + }; + delete schema.timeline_id; + const errors = importRuleValidateTypeDependents(schema); + expect(errors).toEqual(['when "timeline_title" exists, "timeline_id" must also exist']); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_type_dependents.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_type_dependents.ts new file mode 100644 index 0000000000000..59191a4fe3121 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_type_dependents.ts @@ -0,0 +1,105 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ImportRulesSchema } from './import_rules_schema'; + +export const validateAnomalyThreshold = (rule: ImportRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.anomaly_threshold == null) { + return ['when "type" is "machine_learning" anomaly_threshold is required']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateQuery = (rule: ImportRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.query != null) { + return ['when "type" is "machine_learning", "query" cannot be set']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateLanguage = (rule: ImportRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.language != null) { + return ['when "type" is "machine_learning", "language" cannot be set']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateSavedId = (rule: ImportRulesSchema): string[] => { + if (rule.type === 'saved_query') { + if (rule.saved_id == null) { + return ['when "type" is "saved_query", "saved_id" is required']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateMachineLearningJobId = (rule: ImportRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.machine_learning_job_id == null) { + return ['when "type" is "machine_learning", "machine_learning_job_id" is required']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateTimelineId = (rule: ImportRulesSchema): string[] => { + if (rule.timeline_id != null) { + if (rule.timeline_title == null) { + return ['when "timeline_id" exists, "timeline_title" must also exist']; + } else if (rule.timeline_id === '') { + return ['"timeline_id" cannot be an empty string']; + } else { + return []; + } + } + return []; +}; + +export const validateTimelineTitle = (rule: ImportRulesSchema): string[] => { + if (rule.timeline_title != null) { + if (rule.timeline_id == null) { + return ['when "timeline_title" exists, "timeline_id" must also exist']; + } else if (rule.timeline_title === '') { + return ['"timeline_title" cannot be an empty string']; + } else { + return []; + } + } + return []; +}; + +export const importRuleValidateTypeDependents = (schema: ImportRulesSchema): string[] => { + return [ + ...validateAnomalyThreshold(schema), + ...validateQuery(schema), + ...validateLanguage(schema), + ...validateSavedId(schema), + ...validateMachineLearningJobId(schema), + ...validateTimelineId(schema), + ...validateTimelineTitle(schema), + ]; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rule_type_dependents.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rule_type_dependents.test.ts new file mode 100644 index 0000000000000..a388e69332072 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rule_type_dependents.test.ts @@ -0,0 +1,81 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getPatchRulesSchemaMock } from './patch_rules_schema.mock'; +import { PatchRulesSchema } from './patch_rules_schema'; +import { patchRuleValidateTypeDependents } from './patch_rules_type_dependents'; + +describe('patch_rules_type_dependents', () => { + test('saved_id is required when type is saved_query and validates with it', () => { + const schema: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + type: 'saved_query', + saved_id: '123', + }; + const errors = patchRuleValidateTypeDependents(schema); + expect(errors).toEqual([]); + }); + + test('You cannot omit timeline_title when timeline_id is present', () => { + const schema: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + timeline_id: '123', + }; + delete schema.timeline_title; + const errors = patchRuleValidateTypeDependents(schema); + expect(errors).toEqual(['when "timeline_id" exists, "timeline_title" must also exist']); + }); + + test('You cannot have empty string for timeline_title when timeline_id is present', () => { + const schema: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + timeline_id: '123', + timeline_title: '', + }; + const errors = patchRuleValidateTypeDependents(schema); + expect(errors).toEqual(['"timeline_title" cannot be an empty string']); + }); + + test('You cannot have timeline_title with an empty timeline_id', () => { + const schema: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + timeline_id: '', + timeline_title: 'some-title', + }; + const errors = patchRuleValidateTypeDependents(schema); + expect(errors).toEqual(['"timeline_id" cannot be an empty string']); + }); + + test('You cannot have timeline_title without timeline_id', () => { + const schema: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + timeline_title: 'some-title', + }; + delete schema.timeline_id; + const errors = patchRuleValidateTypeDependents(schema); + expect(errors).toEqual(['when "timeline_title" exists, "timeline_id" must also exist']); + }); + + test('You cannot have both an id and a rule_id', () => { + const schema: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + id: 'some-id', + rule_id: 'some-rule-id', + }; + const errors = patchRuleValidateTypeDependents(schema); + expect(errors).toEqual(['both "id" and "rule_id" cannot exist, choose one or the other']); + }); + + test('You must set either an id or a rule_id', () => { + const schema: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + }; + delete schema.id; + delete schema.rule_id; + const errors = patchRuleValidateTypeDependents(schema); + expect(errors).toEqual(['either "id" or "rule_id" must be set']); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.test.ts new file mode 100644 index 0000000000000..7b86c02e5c475 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.test.ts @@ -0,0 +1,101 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { patchRulesBulkSchema, PatchRulesBulkSchema } from './patch_rules_bulk_schema'; +import { exactCheck } from '../../../exact_check'; +import { foldLeftRight } from '../../../test_utils'; +import { formatErrors } from '../../../format_errors'; +import { PatchRulesSchema } from './patch_rules_schema'; + +// only the basics of testing are here. +// see: patch_rules_schema.test.ts for the bulk of the validation tests +// this just wraps patchRulesSchema in an array +describe('patch_rules_bulk_schema', () => { + test('can take an empty array and validate it', () => { + const payload: PatchRulesBulkSchema = []; + + const decoded = patchRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(output.errors).toEqual([]); + expect(output.schema).toEqual([]); + }); + + test('made up values do not validate for a single element', () => { + const payload: Array<{ madeUp: string }> = [{ madeUp: 'hi' }]; + + const decoded = patchRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual(['invalid keys "madeUp"']); + expect(output.schema).toEqual({}); + }); + + test('single array of [id] does validate', () => { + const payload: PatchRulesBulkSchema = [{ id: '4125761e-51da-4de9-a0c8-42824f532ddb' }]; + + const decoded = patchRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual(payload); + }); + + test('two arrays of [id] validate', () => { + const payload: PatchRulesBulkSchema = [ + { id: '4125761e-51da-4de9-a0c8-42824f532ddb' }, + { id: '192f403d-b285-4251-9e8b-785fcfcf22e8' }, + ]; + + const decoded = patchRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual(payload); + }); + + test('can set "note" to be a string', () => { + const payload: PatchRulesBulkSchema = [ + { id: '4125761e-51da-4de9-a0c8-42824f532ddb' }, + { note: 'hi' }, + ]; + + const decoded = patchRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual(payload); + }); + + test('can set "note" to be an empty string', () => { + const payload: PatchRulesBulkSchema = [ + { id: '4125761e-51da-4de9-a0c8-42824f532ddb' }, + { note: '' }, + ]; + + const decoded = patchRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual(payload); + }); + + test('cannot set "note" to be anything other than a string', () => { + const payload: Array & { note?: object }> = [ + { id: '4125761e-51da-4de9-a0c8-42824f532ddb' }, + { note: { someprop: 'some value here' } }, + ]; + + const decoded = patchRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + // TODO: Fix the formatter to give something better than [object Object] + expect(formatErrors(output.errors)).toEqual([ + 'Invalid value "[object Object]" supplied to "note"', + ]); + expect(output.schema).toEqual({}); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.ts new file mode 100644 index 0000000000000..272e36751e37b --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; + +import { patchRulesSchema, PatchRulesSchemaDecoded } from './patch_rules_schema'; + +export const patchRulesBulkSchema = t.array(patchRulesSchema); +export type PatchRulesBulkSchema = t.TypeOf; + +export type PatchRulesBulkSchemaDecoded = PatchRulesSchemaDecoded[]; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.mock.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.mock.ts new file mode 100644 index 0000000000000..7b4f632cdebf0 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.mock.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { PatchRulesSchema, PatchRulesSchemaDecoded } from './patch_rules_schema'; + +export const getPatchRulesSchemaMock = (): PatchRulesSchema => ({ + description: 'some description', + name: 'Query with a rule id', + query: 'user.name: root or user.name: admin', + severity: 'high', + type: 'query', + risk_score: 55, + language: 'kuery', + rule_id: 'rule-1', +}); + +export const getPatchRulesSchemaDecodedMock = (): PatchRulesSchemaDecoded => + getPatchRulesSchemaMock(); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.test.ts new file mode 100644 index 0000000000000..921e07a29609c --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.test.ts @@ -0,0 +1,1153 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { patchRulesSchema, PatchRulesSchema, PatchRulesSchemaDecoded } from './patch_rules_schema'; +import { getPatchRulesSchemaMock, getPatchRulesSchemaDecodedMock } from './patch_rules_schema.mock'; +import { exactCheck } from '../../../exact_check'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { left } from 'fp-ts/lib/Either'; + +describe('patch_rules_schema', () => { + test('made up values do not validate', () => { + const payload: PatchRulesSchema & { madeUp: string } = { + ...getPatchRulesSchemaMock(), + madeUp: 'hi', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['invalid keys "madeUp"']); + expect(message.schema).toEqual({}); + }); + + test('[id] does validate', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id] does validate', () => { + const payload: PatchRulesSchema = { + rule_id: 'rule-1', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + rule_id: 'rule-1', + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description] does validate', () => { + const payload: PatchRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + }; + expect(message.schema).toEqual(expected); + }); + + test('[id, description] does validate', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + }; + expect(message.schema).toEqual(expected); + }); + + test('[id, risk_score] does validate', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + risk_score: 10, + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + risk_score: 10, + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from] does validate', () => { + const payload: PatchRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to] does validate', () => { + const payload: PatchRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + }; + expect(message.schema).toEqual(expected); + }); + + test('[id, description, from, to] does validate', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, name] does validate', () => { + const payload: PatchRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + }; + expect(message.schema).toEqual(expected); + }); + + test('[id, description, from, to, name] does validate', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, name, severity] does validate', () => { + const payload: PatchRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + }; + expect(message.schema).toEqual(expected); + }); + + test('[id, description, from, to, name, severity] does validate', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, name, severity, type] does validate', () => { + const payload: PatchRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + }; + expect(message.schema).toEqual(expected); + }); + + test('[id, description, from, to, name, severity, type] does validate', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, name, severity, type, interval] does validate', () => { + const payload: PatchRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + }; + expect(message.schema).toEqual(expected); + }); + + test('[id, description, from, to, name, severity, type, interval] does validate', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, query] does validate', () => { + const payload: PatchRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + }; + expect(message.schema).toEqual(expected); + }); + + test('[id, description, from, to, index, name, severity, interval, type, query, language] does validate', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, query, language] does validate', () => { + const payload: PatchRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + }; + expect(message.schema).toEqual(expected); + }); + + test('[id, description, from, to, index, name, severity, type, filters] does validate', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + filters: [], + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + filters: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, type, filters] does validate', () => { + const payload: PatchRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + filters: [], + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + filters: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('allows references to be sent as a valid value to patch with', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + references: ['index-1'], + query: 'some query', + language: 'kuery', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + references: ['index-1'], + query: 'some query', + language: 'kuery', + }; + expect(message.schema).toEqual(expected); + }); + + test('does not default references to an array', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect((message.schema as PatchRulesSchemaDecoded).references).toEqual(undefined); + }); + + test('does not default interval', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect((message.schema as PatchRulesSchemaDecoded).interval).toEqual(undefined); + }); + + test('does not default max_signals', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect((message.schema as PatchRulesSchemaDecoded).max_signals).toEqual(undefined); + }); + + test('references cannot be numbers', () => { + const payload: Omit & { references: number[] } = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + references: [5], + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "references"']); + expect(message.schema).toEqual({}); + }); + + test('indexes cannot be numbers', () => { + const payload: Omit & { index: number[] } = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + index: [5], + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "index"']); + expect(message.schema).toEqual({}); + }); + + test('saved_id is not required when type is saved_query and will validate without it', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + type: 'saved_query', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + type: 'saved_query', + }; + expect(message.schema).toEqual(expected); + }); + + test('saved_id validates with type:saved_query', () => { + const payload: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + type: 'saved_query', + saved_id: 'some id', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + ...getPatchRulesSchemaDecodedMock(), + type: 'saved_query', + saved_id: 'some id', + }; + expect(message.schema).toEqual(expected); + }); + + test('saved_query type can have filters with it', () => { + const payload: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + saved_id: 'some id', + filters: [], + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + ...getPatchRulesSchemaDecodedMock(), + saved_id: 'some id', + filters: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('language validates with kuery', () => { + const payload: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + query: 'some query', + language: 'kuery', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + ...getPatchRulesSchemaDecodedMock(), + query: 'some query', + language: 'kuery', + }; + expect(message.schema).toEqual(expected); + }); + + test('language validates with lucene', () => { + const payload: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + query: 'some query', + language: 'lucene', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const expected: PatchRulesSchemaDecoded = { + ...getPatchRulesSchemaDecodedMock(), + query: 'some query', + language: 'lucene', + }; + expect(message.schema).toEqual(expected); + }); + + test('language does not validate with something made up', () => { + const payload: Omit & { language: string } = { + ...getPatchRulesSchemaMock(), + query: 'some query', + language: 'something-made-up', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "something-made-up" supplied to "language"', + ]); + expect(message.schema).toEqual({}); + }); + + test('max_signals cannot be negative', () => { + const payload: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + query: 'some query', + max_signals: -1, + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "-1" supplied to "max_signals"', + ]); + expect(message.schema).toEqual({}); + }); + + test('max_signals cannot be zero', () => { + const payload: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + query: 'some query', + max_signals: 0, + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to "max_signals"']); + expect(message.schema).toEqual({}); + }); + + test('max_signals can be 1', () => { + const payload: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + query: 'some query', + max_signals: 1, + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + ...getPatchRulesSchemaDecodedMock(), + query: 'some query', + max_signals: 1, + }; + expect(message.schema).toEqual(expected); + }); + + test('meta can be patched', () => { + const payload: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + meta: { whateverYouWant: 'anything_at_all' }, + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + ...getPatchRulesSchemaDecodedMock(), + meta: { whateverYouWant: 'anything_at_all' }, + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot patch meta as a string', () => { + const payload: Omit & { meta: string } = { + ...getPatchRulesSchemaMock(), + meta: 'should not work', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "should not work" supplied to "meta"', + ]); + expect(message.schema).toEqual({}); + }); + + test('filters cannot be a string', () => { + const payload: Omit & { filters: string } = { + ...getPatchRulesSchemaMock(), + filters: 'should not work', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "should not work" supplied to "filters"', + ]); + expect(message.schema).toEqual({}); + }); + + test('threat is not defaulted to empty array on patch', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect((message.schema as PatchRulesSchemaDecoded).threat).toEqual(undefined); + }); + + test('threat is not defaulted to undefined on patch with empty array', () => { + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + threat: [], + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect((message.schema as PatchRulesSchemaDecoded).threat).toEqual([]); + }); + + test('threat is valid when updated with all sub-objects', () => { + const threat: PatchRulesSchema['threat'] = [ + { + framework: 'fake', + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ]; + const payload: PatchRulesSchema = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + threat, + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('threat is invalid when updated with missing property framework', () => { + const threat: Omit = [ + { + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ]; + const payload: Omit = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + threat, + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "threat,framework"', + ]); + expect(message.schema).toEqual({}); + }); + + test('threat is invalid when updated with missing tactic sub-object', () => { + const threat: Omit = [ + { + framework: 'fake', + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ]; + + const payload: Omit = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + threat, + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "threat,tactic"', + ]); + expect(message.schema).toEqual({}); + }); + + test('threat is invalid when updated with missing technique', () => { + const threat: Omit = [ + { + framework: 'fake', + tactic: { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + }, + ]; + + const payload: Omit = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + threat, + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "threat,technique"', + ]); + expect(message.schema).toEqual({}); + }); + + test('validates with timeline_id and timeline_title', () => { + const payload: PatchRulesSchema = { + ...getPatchRulesSchemaMock(), + timeline_id: 'some-id', + timeline_title: 'some-title', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + ...getPatchRulesSchemaDecodedMock(), + timeline_id: 'some-id', + timeline_title: 'some-title', + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot set the severity to a value other than low, medium, high, or critical', () => { + const payload: Omit & { severity: string } = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + severity: 'junk', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "junk" supplied to "severity"']); + expect(message.schema).toEqual({}); + }); + + describe('note', () => { + test('[rule_id, description, from, to, index, name, severity, interval, type, note] does validate', () => { + const payload: PatchRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + note: '# some documentation markdown', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + note: '# some documentation markdown', + }; + expect(message.schema).toEqual(expected); + }); + + test('note can be patched', () => { + const payload: PatchRulesSchema = { + rule_id: 'rule-1', + note: '# new documentation markdown', + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: PatchRulesSchemaDecoded = { + rule_id: 'rule-1', + note: '# new documentation markdown', + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot patch note as an object', () => { + const payload: Omit & { note: object } = { + id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', + note: { + someProperty: 'something else here', + }, + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + // TODO: Change the formatter to output something more readable than [object Object] + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "[object Object]" supplied to "note"', + ]); + expect(message.schema).toEqual({}); + }); + }); + + test('You cannot send in an array of actions that are missing "group"', () => { + const payload: Omit = { + ...getPatchRulesSchemaMock(), + actions: [{ id: 'id', action_type_id: 'action_type_id', params: {} }], + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "actions,group"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are missing "id"', () => { + const payload: Omit = { + ...getPatchRulesSchemaMock(), + actions: [{ group: 'group', action_type_id: 'action_type_id', params: {} }], + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "actions,id"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are missing "params"', () => { + const payload: Omit = { + ...getPatchRulesSchemaMock(), + actions: [{ group: 'group', id: 'id', action_type_id: 'action_type_id' }], + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "actions,params"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are including "actionTypeId"', () => { + const payload: Omit = { + ...getPatchRulesSchemaMock(), + actions: [ + { + group: 'group', + id: 'id', + actionTypeId: 'actionTypeId', + params: {}, + }, + ], + }; + + const decoded = patchRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "actions,action_type_id"', + ]); + expect(message.schema).toEqual({}); + }); + + // TODO: The exception_list tests are skipped and empty until we re-integrate it from the lists plugin + describe.skip('exception_list', () => { + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and exceptions_list] does validate', () => {}); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and empty exceptions_list] does validate', () => {}); + + test('rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and invalid exceptions_list] does NOT validate', () => {}); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and non-existent exceptions_list] does validate with empty exceptions_list', () => {}); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.ts new file mode 100644 index 0000000000000..605e0272bbb4c --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.ts @@ -0,0 +1,90 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; + +/* eslint-disable @typescript-eslint/camelcase */ +import { + description, + anomaly_threshold, + filters, + index, + output_index, + saved_id, + timeline_id, + timeline_title, + meta, + machine_learning_job_id, + risk_score, + rule_id, + name, + severity, + type, + note, + version, + actions, + false_positives, + interval, + max_signals, + from, + enabled, + tags, + threat, + throttle, + references, + to, + language, + listAndOrUndefined, + query, + id, +} from '../common/schemas'; +/* eslint-enable @typescript-eslint/camelcase */ + +/** + * All of the patch elements should default to undefined if not set + */ +export const patchRulesSchema = t.exact( + t.partial({ + description, + risk_score, + name, + severity, + type, + id, + actions, + anomaly_threshold, + enabled, + false_positives, + filters, + from, + rule_id, + index, + interval, + query, + language, + // TODO: output_index: This should be removed eventually + output_index, + saved_id, + timeline_id, + timeline_title, + meta, + machine_learning_job_id, + max_signals, + tags, + to, + threat, + throttle, + references, + note, + version, + exceptions_list: listAndOrUndefined, + }) +); + +export type PatchRulesSchema = t.TypeOf; + +// This type is used after a decode since some things are defaults after a decode. +export type PatchRulesSchemaDecoded = PatchRulesSchema; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_type_dependents.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_type_dependents.ts new file mode 100644 index 0000000000000..554cdb822762f --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_type_dependents.ts @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { PatchRulesSchema } from './patch_rules_schema'; + +export const validateQuery = (rule: PatchRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.query != null) { + return ['when "type" is "machine_learning", "query" cannot be set']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateLanguage = (rule: PatchRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.language != null) { + return ['when "type" is "machine_learning", "language" cannot be set']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateTimelineId = (rule: PatchRulesSchema): string[] => { + if (rule.timeline_id != null) { + if (rule.timeline_title == null) { + return ['when "timeline_id" exists, "timeline_title" must also exist']; + } else if (rule.timeline_id === '') { + return ['"timeline_id" cannot be an empty string']; + } else { + return []; + } + } + return []; +}; + +export const validateTimelineTitle = (rule: PatchRulesSchema): string[] => { + if (rule.timeline_title != null) { + if (rule.timeline_id == null) { + return ['when "timeline_title" exists, "timeline_id" must also exist']; + } else if (rule.timeline_title === '') { + return ['"timeline_title" cannot be an empty string']; + } else { + return []; + } + } + return []; +}; + +export const validateId = (rule: PatchRulesSchema): string[] => { + if (rule.id != null && rule.rule_id != null) { + return ['both "id" and "rule_id" cannot exist, choose one or the other']; + } else if (rule.id == null && rule.rule_id == null) { + return ['either "id" or "rule_id" must be set']; + } else { + return []; + } +}; + +export const patchRuleValidateTypeDependents = (schema: PatchRulesSchema): string[] => { + return [ + ...validateId(schema), + ...validateQuery(schema), + ...validateLanguage(schema), + ...validateTimelineId(schema), + ...validateTimelineTitle(schema), + ]; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_bulk_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_bulk_schema.test.ts new file mode 100644 index 0000000000000..4728f7dd84cbd --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_bulk_schema.test.ts @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { queryRulesBulkSchema, QueryRulesBulkSchema } from './query_rules_bulk_schema'; +import { exactCheck } from '../../../exact_check'; +import { foldLeftRight } from '../../../test_utils'; +import { formatErrors } from '../../../format_errors'; + +// only the basics of testing are here. +// see: query_rules_schema.test.ts for the bulk of the validation tests +// this just wraps queryRulesSchema in an array +describe('query_rules_bulk_schema', () => { + test('can take an empty array and validate it', () => { + const payload: QueryRulesBulkSchema = []; + + const decoded = queryRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual([]); + }); + + test('non uuid being supplied to id does not validate', () => { + const payload: QueryRulesBulkSchema = [ + { + id: '1', + }, + ]; + + const decoded = queryRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual(['Invalid value "1" supplied to "id"']); + expect(output.schema).toEqual({}); + }); + + test('both rule_id and id being supplied do validate', () => { + const payload: QueryRulesBulkSchema = [ + { + rule_id: '1', + id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f', + }, + ]; + + const decoded = queryRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual(payload); + }); + + test('only id validates with two elements', () => { + const payload: QueryRulesBulkSchema = [ + { id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f' }, + { id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f' }, + ]; + + const decoded = queryRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual(payload); + }); + + test('only rule_id validates', () => { + const payload: QueryRulesBulkSchema = [{ rule_id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f' }]; + + const decoded = queryRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual(payload); + }); + + test('only rule_id validates with two elements', () => { + const payload: QueryRulesBulkSchema = [ + { rule_id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f' }, + { rule_id: '2' }, + ]; + + const decoded = queryRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual(payload); + }); + + test('both id and rule_id validates with two separate elements', () => { + const payload: QueryRulesBulkSchema = [ + { id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f' }, + { rule_id: '2' }, + ]; + + const decoded = queryRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual(payload); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_bulk_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_bulk_schema.ts new file mode 100644 index 0000000000000..a5611bdc2f12f --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_bulk_schema.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; + +import { queryRulesSchema, QueryRulesSchemaDecoded } from './query_rules_schema'; + +export const queryRulesBulkSchema = t.array(queryRulesSchema); +export type QueryRulesBulkSchema = t.TypeOf; + +export type QueryRulesBulkSchemaDecoded = QueryRulesSchemaDecoded[]; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.test.ts new file mode 100644 index 0000000000000..c9cb6f310961a --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.test.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { queryRulesSchema, QueryRulesSchema } from './query_rules_schema'; +import { exactCheck } from '../../../exact_check'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { left } from 'fp-ts/lib/Either'; + +describe('query_rules_schema', () => { + test('empty objects do validate', () => { + const payload: Partial = {}; + + const decoded = queryRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual({}); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.ts new file mode 100644 index 0000000000000..cb8f21128b052 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; + +/* eslint-disable @typescript-eslint/camelcase */ +import { rule_id, id } from '../common/schemas'; +/* eslint-enable @typescript-eslint/camelcase */ + +export const queryRulesSchema = t.exact( + t.partial({ + rule_id, + id, + }) +); + +export type QueryRulesSchema = t.TypeOf; +export type QueryRulesSchemaDecoded = QueryRulesSchema; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_type_dependents.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_type_dependents.test.ts new file mode 100644 index 0000000000000..ad7f368d4eede --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_type_dependents.test.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { QueryRulesSchema } from './query_rules_schema'; +import { queryRuleValidateTypeDependents } from './query_rules_type_dependents'; + +describe('query_rules_type_dependents', () => { + test('You cannot have both an id and a rule_id', () => { + const schema: QueryRulesSchema = { + id: 'some-id', + rule_id: 'some-rule-id', + }; + const errors = queryRuleValidateTypeDependents(schema); + expect(errors).toEqual(['both "id" and "rule_id" cannot exist, choose one or the other']); + }); + + test('You must set either an id or a rule_id', () => { + const schema: QueryRulesSchema = {}; + const errors = queryRuleValidateTypeDependents(schema); + expect(errors).toEqual(['either "id" or "rule_id" must be set']); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_type_dependents.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_type_dependents.ts new file mode 100644 index 0000000000000..f3e602dff0f06 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_type_dependents.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { QueryRulesSchema } from './query_rules_schema'; + +export const validateId = (rule: QueryRulesSchema): string[] => { + if (rule.id != null && rule.rule_id != null) { + return ['both "id" and "rule_id" cannot exist, choose one or the other']; + } else if (rule.id == null && rule.rule_id == null) { + return ['either "id" or "rule_id" must be set']; + } else { + return []; + } +}; + +export const queryRuleValidateTypeDependents = (schema: QueryRulesSchema): string[] => { + return [...validateId(schema)]; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_signals_index_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_signals_index_schema.test.ts new file mode 100644 index 0000000000000..23e5fa7e721b0 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_signals_index_schema.test.ts @@ -0,0 +1,94 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { QuerySignalsSchema, querySignalsSchema } from './query_signals_index_schema'; +import { exactCheck } from '../../../exact_check'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { left } from 'fp-ts/lib/Either'; + +describe('query, aggs, size, _source and track_total_hits on signals index', () => { + test('query, aggs, size, _source and track_total_hits simultaneously', () => { + const payload: QuerySignalsSchema = { + query: {}, + aggs: {}, + size: 1, + track_total_hits: true, + _source: ['field'], + }; + + const decoded = querySignalsSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('query, only', () => { + const payload: QuerySignalsSchema = { + query: {}, + }; + + const decoded = querySignalsSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('aggs only', () => { + const payload: QuerySignalsSchema = { + aggs: {}, + }; + + const decoded = querySignalsSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('size only', () => { + const payload: QuerySignalsSchema = { + size: 1, + }; + + const decoded = querySignalsSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('track_total_hits only', () => { + const payload: QuerySignalsSchema = { + track_total_hits: true, + }; + + const decoded = querySignalsSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('_source only', () => { + const payload: QuerySignalsSchema = { + _source: ['field'], + }; + + const decoded = querySignalsSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_signals_index_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_signals_index_schema.ts new file mode 100644 index 0000000000000..3a050c9208f77 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_signals_index_schema.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { PositiveIntegerGreaterThanZero } from '../types/positive_integer_greater_than_zero'; + +export const querySignalsSchema = t.exact( + t.partial({ + query: t.object, + aggs: t.object, + size: PositiveIntegerGreaterThanZero, + track_total_hits: t.boolean, + _source: t.array(t.string), + }) +); + +export type QuerySignalsSchema = t.TypeOf; +export type QuerySignalsSchemaDecoded = QuerySignalsSchema; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.test.ts new file mode 100644 index 0000000000000..dc889892ba83e --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.test.ts @@ -0,0 +1,82 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { setSignalsStatusSchema, SetSignalsStatusSchema } from './set_signal_status_schema'; +import { exactCheck } from '../../../exact_check'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { left } from 'fp-ts/lib/Either'; + +describe('set signal status schema', () => { + test('signal_ids and status is valid', () => { + const payload: SetSignalsStatusSchema = { + signal_ids: ['somefakeid'], + status: 'open', + }; + + const decoded = setSignalsStatusSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('query and status is valid', () => { + const payload: SetSignalsStatusSchema = { + query: {}, + status: 'open', + }; + + const decoded = setSignalsStatusSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('signal_ids and missing status is invalid', () => { + const payload: Omit = { + signal_ids: ['somefakeid'], + }; + + const decoded = setSignalsStatusSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "status"', + ]); + expect(message.schema).toEqual({}); + }); + + test('query and missing status is invalid', () => { + const payload: Omit = { + query: {}, + }; + + const decoded = setSignalsStatusSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "status"', + ]); + expect(message.schema).toEqual({}); + }); + + test('signal_ids is present but status has wrong value', () => { + const payload: Omit & { status: 'fakeVal' } = { + query: {}, + status: 'fakeVal', + }; + + const decoded = setSignalsStatusSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "fakeVal" supplied to "status"', + ]); + expect(message.schema).toEqual({}); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.ts new file mode 100644 index 0000000000000..0e922aeaf8cdf --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_schema.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; + +/* eslint-disable @typescript-eslint/camelcase */ +import { signal_ids, signal_status_query, status } from '../common/schemas'; +/* eslint-enable @typescript-eslint/camelcase */ + +export const setSignalsStatusSchema = t.intersection([ + t.type({ + status, + }), + t.partial({ + signal_ids, + query: signal_status_query, + }), +]); + +export type SetSignalsStatusSchema = t.TypeOf; +export type SetSignalsStatusSchemaDecoded = SetSignalsStatusSchema; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_type_dependents.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_type_dependents.test.ts new file mode 100644 index 0000000000000..b79af2fef5c97 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_type_dependents.test.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { setSignalStatusValidateTypeDependents } from './set_signal_status_type_dependents'; +import { SetSignalsStatusSchema } from './set_signal_status_schema'; + +describe('update_rules_type_dependents', () => { + test('You can have just a "signals_id"', () => { + const schema: SetSignalsStatusSchema = { + status: 'open', + signal_ids: ['some-id'], + }; + const errors = setSignalStatusValidateTypeDependents(schema); + expect(errors).toEqual([]); + }); + + test('You can have just a "query"', () => { + const schema: SetSignalsStatusSchema = { + status: 'open', + query: {}, + }; + const errors = setSignalStatusValidateTypeDependents(schema); + expect(errors).toEqual([]); + }); + + test('You cannot have both a "signals_id" and a "query"', () => { + const schema: SetSignalsStatusSchema = { + status: 'open', + query: {}, + signal_ids: ['some-id'], + }; + const errors = setSignalStatusValidateTypeDependents(schema); + expect(errors).toEqual(['both "signal_ids" and "query" cannot exist, choose one or the other']); + }); + + test('You must set either an "signals_id" and a "query"', () => { + const schema: SetSignalsStatusSchema = { + status: 'open', + }; + const errors = setSignalStatusValidateTypeDependents(schema); + expect(errors).toEqual(['either "signal_ids" or "query" must be set']); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_type_dependents.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_type_dependents.ts new file mode 100644 index 0000000000000..c495860fa72bf --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_signal_status_type_dependents.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SetSignalsStatusSchema } from './set_signal_status_schema'; + +export const validateId = (signalStatus: SetSignalsStatusSchema): string[] => { + if (signalStatus.signal_ids != null && signalStatus.query != null) { + return ['both "signal_ids" and "query" cannot exist, choose one or the other']; + } else if (signalStatus.signal_ids == null && signalStatus.query == null) { + return ['either "signal_ids" or "query" must be set']; + } else { + return []; + } +}; + +export const setSignalStatusValidateTypeDependents = (schema: SetSignalsStatusSchema): string[] => { + return [...validateId(schema)]; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.test.ts new file mode 100644 index 0000000000000..edc652ce3b3f4 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.test.ts @@ -0,0 +1,277 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { updateRulesBulkSchema, UpdateRulesBulkSchema } from './update_rules_bulk_schema'; +import { exactCheck } from '../../../exact_check'; +import { foldLeftRight } from '../../../test_utils'; +import { formatErrors } from '../../../format_errors'; +import { + getUpdateRulesSchemaMock, + getUpdateRulesSchemaDecodedMock, +} from './update_rules_schema.mock'; +import { UpdateRulesSchema } from './update_rules_schema'; + +// only the basics of testing are here. +// see: update_rules_schema.test.ts for the bulk of the validation tests +// this just wraps updateRulesSchema in an array +describe('update_rules_bulk_schema', () => { + test('can take an empty array and validate it', () => { + const payload: UpdateRulesBulkSchema = []; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(output.errors).toEqual([]); + expect(output.schema).toEqual([]); + }); + + test('made up values do not validate for a single element', () => { + const payload: Array<{ madeUp: string }> = [{ madeUp: 'hi' }]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([ + 'Invalid value "undefined" supplied to "description"', + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(output.schema).toEqual({}); + }); + + test('single array element does validate', () => { + const payload: UpdateRulesBulkSchema = [getUpdateRulesSchemaMock()]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual([getUpdateRulesSchemaDecodedMock()]); + }); + + test('two array elements do validate', () => { + const payload: UpdateRulesBulkSchema = [getUpdateRulesSchemaMock(), getUpdateRulesSchemaMock()]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual([ + getUpdateRulesSchemaDecodedMock(), + getUpdateRulesSchemaDecodedMock(), + ]); + }); + + test('single array element with a missing value (risk_score) will not validate', () => { + const singleItem = getUpdateRulesSchemaMock(); + delete singleItem.risk_score; + const payload: UpdateRulesBulkSchema = [singleItem]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(output.schema).toEqual({}); + }); + + test('two array elements where the first is valid but the second is invalid (risk_score) will not validate', () => { + const singleItem = getUpdateRulesSchemaMock(); + const secondItem = getUpdateRulesSchemaMock(); + delete secondItem.risk_score; + const payload: UpdateRulesBulkSchema = [singleItem, secondItem]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(output.schema).toEqual({}); + }); + + test('two array elements where the first is invalid (risk_score) but the second is valid will not validate', () => { + const singleItem = getUpdateRulesSchemaMock(); + const secondItem = getUpdateRulesSchemaMock(); + delete singleItem.risk_score; + const payload: UpdateRulesBulkSchema = [singleItem, secondItem]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(output.schema).toEqual({}); + }); + + test('two array elements where both are invalid (risk_score) will not validate', () => { + const singleItem = getUpdateRulesSchemaMock(); + const secondItem = getUpdateRulesSchemaMock(); + delete singleItem.risk_score; + delete secondItem.risk_score; + const payload: UpdateRulesBulkSchema = [singleItem, secondItem]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(output.schema).toEqual({}); + }); + + test('two array elements where the first is invalid (extra key and value) but the second is valid will not validate', () => { + const singleItem: UpdateRulesSchema & { madeUpValue: string } = { + ...getUpdateRulesSchemaMock(), + madeUpValue: 'something', + }; + const secondItem = getUpdateRulesSchemaMock(); + const payload: UpdateRulesBulkSchema = [singleItem, secondItem]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual(['invalid keys "madeUpValue"']); + expect(output.schema).toEqual({}); + }); + + test('two array elements where the second is invalid (extra key and value) but the first is valid will not validate', () => { + const singleItem: UpdateRulesSchema = getUpdateRulesSchemaMock(); + const secondItem: UpdateRulesSchema & { madeUpValue: string } = { + ...getUpdateRulesSchemaMock(), + madeUpValue: 'something', + }; + const payload: UpdateRulesBulkSchema = [singleItem, secondItem]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual(['invalid keys "madeUpValue"']); + expect(output.schema).toEqual({}); + }); + + test('two array elements where both are invalid (extra key and value) will not validate', () => { + const singleItem: UpdateRulesSchema & { madeUpValue: string } = { + ...getUpdateRulesSchemaMock(), + madeUpValue: 'something', + }; + const secondItem: UpdateRulesSchema & { madeUpValue: string } = { + ...getUpdateRulesSchemaMock(), + madeUpValue: 'something', + }; + const payload: UpdateRulesBulkSchema = [singleItem, secondItem]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual(['invalid keys "madeUpValue,madeUpValue"']); + expect(output.schema).toEqual({}); + }); + + test('The default for "from" will be "now-6m"', () => { + const { from, ...withoutFrom } = getUpdateRulesSchemaMock(); + const payload: UpdateRulesBulkSchema = [withoutFrom]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect((output.schema as UpdateRulesBulkSchema)[0].from).toEqual('now-6m'); + }); + + test('The default for "to" will be "now"', () => { + const { to, ...withoutTo } = getUpdateRulesSchemaMock(); + const payload: UpdateRulesBulkSchema = [withoutTo]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect((output.schema as UpdateRulesBulkSchema)[0].to).toEqual('now'); + }); + + test('You cannot set the severity to a value other than low, medium, high, or critical', () => { + const badSeverity = { ...getUpdateRulesSchemaMock(), severity: 'madeup' }; + const payload = [badSeverity]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual(['Invalid value "madeup" supplied to "severity"']); + expect(output.schema).toEqual({}); + }); + + test('You can set "note" to a string', () => { + const payload: UpdateRulesBulkSchema = [ + { ...getUpdateRulesSchemaMock(), note: '# test markdown' }, + ]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual([ + { ...getUpdateRulesSchemaDecodedMock(), note: '# test markdown' }, + ]); + }); + + test('You can set "note" to an empty string', () => { + const payload: UpdateRulesBulkSchema = [{ ...getUpdateRulesSchemaMock(), note: '' }]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect(output.schema).toEqual([{ ...getUpdateRulesSchemaDecodedMock(), note: '' }]); + }); + + test('You can set "note" to anything other than string', () => { + const payload = [ + { + ...getUpdateRulesSchemaMock(), + note: { + something: 'some object', + }, + }, + ]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + // TODO: We should change the formatter used to better print objects + expect(formatErrors(output.errors)).toEqual([ + 'Invalid value "[object Object]" supplied to "note"', + ]); + expect(output.schema).toEqual({}); + }); + + test('The default for "actions" will be an empty array', () => { + const { actions, ...withoutActions } = getUpdateRulesSchemaMock(); + const payload: UpdateRulesBulkSchema = [withoutActions]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect((output.schema as UpdateRulesBulkSchema)[0].actions).toEqual([]); + }); + + test('The default for "throttle" will be null', () => { + const { throttle, ...withoutThrottle } = getUpdateRulesSchemaMock(); + const payload: UpdateRulesBulkSchema = [withoutThrottle]; + + const decoded = updateRulesBulkSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const output = foldLeftRight(checked); + expect(formatErrors(output.errors)).toEqual([]); + expect((output.schema as UpdateRulesBulkSchema)[0].throttle).toEqual(null); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.ts new file mode 100644 index 0000000000000..429103c7df13e --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; + +import { updateRulesSchema, UpdateRulesSchemaDecoded } from './update_rules_schema'; + +export const updateRulesBulkSchema = t.array(updateRulesSchema); +export type UpdateRulesBulkSchema = t.TypeOf; + +export type UpdateRulesBulkSchemaDecoded = UpdateRulesSchemaDecoded[]; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.mock.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.mock.ts new file mode 100644 index 0000000000000..b8a99115ba7d5 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.mock.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { UpdateRulesSchema, UpdateRulesSchemaDecoded } from './update_rules_schema'; +import { DEFAULT_MAX_SIGNALS } from '../../../constants'; + +export const getUpdateRulesSchemaMock = (): UpdateRulesSchema => ({ + description: 'some description', + name: 'Query with a rule id', + query: 'user.name: root or user.name: admin', + severity: 'high', + type: 'query', + risk_score: 55, + language: 'kuery', + rule_id: 'rule-1', +}); + +export const getUpdateRulesSchemaDecodedMock = (): UpdateRulesSchemaDecoded => ({ + description: 'some description', + name: 'Query with a rule id', + query: 'user.name: root or user.name: admin', + severity: 'high', + type: 'query', + risk_score: 55, + language: 'kuery', + references: [], + actions: [], + enabled: true, + false_positives: [], + from: 'now-6m', + interval: '5m', + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + to: 'now', + threat: [], + throttle: null, + exceptions_list: [], + rule_id: 'rule-1', +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.test.ts new file mode 100644 index 0000000000000..e60522e1964f4 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.test.ts @@ -0,0 +1,1387 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + updateRulesSchema, + UpdateRulesSchema, + UpdateRulesSchemaDecoded, +} from './update_rules_schema'; +import { exactCheck } from '../../../exact_check'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { + getUpdateRulesSchemaMock, + getUpdateRulesSchemaDecodedMock, +} from './update_rules_schema.mock'; +import { DEFAULT_MAX_SIGNALS } from '../../../constants'; + +describe('update rules schema', () => { + test('empty objects do not validate', () => { + const payload: Partial = {}; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "description"', + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('made up values do not validate', () => { + const payload: UpdateRulesSchema & { madeUp: string } = { + ...getUpdateRulesSchemaMock(), + madeUp: 'hi', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['invalid keys "madeUp"']); + expect(message.schema).toEqual({}); + }); + + test('[rule_id] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "description"', + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "name"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "severity"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + 'Invalid value "undefined" supplied to "type"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type, interval] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type, interval, index] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + interval: '5m', + index: ['index-1'], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, name, severity, type, query, index, interval] does validate', () => { + const payload: UpdateRulesSchema = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + query: 'some query', + index: ['index-1'], + interval: '5m', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + name: 'some-name', + severity: 'low', + type: 'query', + query: 'some query', + index: ['index-1'], + interval: '5m', + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, query, language] does not validate', () => { + const payload: Partial = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score] does validate', () => { + const payload: UpdateRulesSchema = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + rule_id: 'rule-1', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score, output_index] does validate', () => { + const payload: UpdateRulesSchema = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + query: 'some query', + language: 'kuery', + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score] does validate', () => { + const payload: UpdateRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index] does validate', () => { + const payload: UpdateRulesSchema = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('You can send in an empty array to threat', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + threat: [], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + ...getUpdateRulesSchemaDecodedMock(), + threat: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index, threat] does validate', () => { + const payload: UpdateRulesSchema = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + threat: [ + { + framework: 'someFramework', + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + rule_id: 'rule-1', + output_index: '.siem-signals', + risk_score: 50, + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + threat: [ + { + framework: 'someFramework', + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + throttle: null, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('allows references to be sent as valid', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + references: ['index-1'], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + ...getUpdateRulesSchemaDecodedMock(), + references: ['index-1'], + }; + expect(message.schema).toEqual(expected); + }); + + test('defaults references to an array if it is not sent in', () => { + const { references, ...noReferences } = getUpdateRulesSchemaMock(); + const decoded = updateRulesSchema.decode(noReferences); + const checked = exactCheck(noReferences, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + ...getUpdateRulesSchemaDecodedMock(), + references: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('references cannot be numbers', () => { + const payload: Omit & { references: number[] } = { + ...getUpdateRulesSchemaMock(), + references: [5], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('indexes cannot be numbers', () => { + const payload: Omit & { index: number[] } = { + ...getUpdateRulesSchemaMock(), + index: [5], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "index"']); + expect(message.schema).toEqual({}); + }); + + test('defaults interval to 5 min', () => { + const { interval, ...noInterval } = getUpdateRulesSchemaMock(); + const payload: UpdateRulesSchema = { + ...noInterval, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { interval: expectedInterval, ...expectedNoInterval } = getUpdateRulesSchemaDecodedMock(); + const expected: UpdateRulesSchemaDecoded = { + ...expectedNoInterval, + interval: '5m', + }; + expect(message.schema).toEqual(expected); + }); + + test('defaults max signals to 100', () => { + const { max_signals, ...noMaxSignals } = getUpdateRulesSchemaMock(); + const payload: UpdateRulesSchema = { + ...noMaxSignals, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { + max_signals: expectedMaxSignals, + ...expectedNoMaxSignals + } = getUpdateRulesSchemaDecodedMock(); + const expected: UpdateRulesSchemaDecoded = { + ...expectedNoMaxSignals, + max_signals: 100, + }; + expect(message.schema).toEqual(expected); + }); + + test('saved_query type can have filters with it', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + filters: [], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + ...getUpdateRulesSchemaDecodedMock(), + filters: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('filters cannot be a string', () => { + const payload: Omit & { filters: string } = { + ...getUpdateRulesSchemaMock(), + filters: 'some string', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "some string" supplied to "filters"', + ]); + expect(message.schema).toEqual({}); + }); + + test('language validates with kuery', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + language: 'kuery', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + ...getUpdateRulesSchemaDecodedMock(), + language: 'kuery', + }; + expect(message.schema).toEqual(expected); + }); + + test('language validates with lucene', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + language: 'lucene', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + ...getUpdateRulesSchemaDecodedMock(), + language: 'lucene', + }; + expect(message.schema).toEqual(expected); + }); + + test('language does not validate with something made up', () => { + const payload: Omit & { language: string } = { + ...getUpdateRulesSchemaMock(), + language: 'something-made-up', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "something-made-up" supplied to "language"', + ]); + expect(message.schema).toEqual({}); + }); + + test('max_signals cannot be negative', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + max_signals: -1, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('max_signals cannot be zero', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + max_signals: 0, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('max_signals can be 1', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + max_signals: 1, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + ...getUpdateRulesSchemaDecodedMock(), + max_signals: 1, + }; + expect(message.schema).toEqual(expected); + }); + + test('You can optionally send in an array of tags', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + tags: ['tag_1', 'tag_2'], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + ...getUpdateRulesSchemaDecodedMock(), + tags: ['tag_1', 'tag_2'], + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot send in an array of tags that are numbers', () => { + const payload: Omit & { tags: number[] } = { + ...getUpdateRulesSchemaMock(), + tags: [0, 1, 2], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "0" supplied to ""', + 'Invalid value "1" supplied to ""', + 'Invalid value "2" supplied to ""', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of threat that are missing "framework"', () => { + const payload: Omit & { + threat: Array>>; + } = { + ...getUpdateRulesSchemaMock(), + threat: [ + { + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "framework"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of threat that are missing "tactic"', () => { + const payload: Omit & { + threat: Array>>; + } = { + ...getUpdateRulesSchemaMock(), + threat: [ + { + framework: 'fake', + technique: [ + { + id: 'techniqueId', + name: 'techniqueName', + reference: 'techniqueRef', + }, + ], + }, + ], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "tactic"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of threat that are missing "technique"', () => { + const payload: Omit & { + threat: Array>>; + } = { + ...getUpdateRulesSchemaMock(), + threat: [ + { + framework: 'fake', + tactic: { + id: 'fakeId', + name: 'fakeName', + reference: 'fakeRef', + }, + }, + ], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "technique"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You can optionally send in an array of false positives', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + false_positives: ['false_1', 'false_2'], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + ...getUpdateRulesSchemaDecodedMock(), + false_positives: ['false_1', 'false_2'], + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot send in an array of false positives that are numbers', () => { + const payload: Omit & { false_positives: number[] } = { + ...getUpdateRulesSchemaMock(), + false_positives: [5, 4], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "5" supplied to ""', + 'Invalid value "4" supplied to ""', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot set the immutable to a number when trying to update a rule', () => { + const payload: Omit & { immutable: number } = { + ...getUpdateRulesSchemaMock(), + immutable: 5, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['invalid keys "immutable"']); + expect(message.schema).toEqual({}); + }); + + test('You cannot set the risk_score to 101', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + risk_score: 101, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "101" supplied to "risk_score"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot set the risk_score to -1', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + risk_score: -1, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to "risk_score"']); + expect(message.schema).toEqual({}); + }); + + test('You can set the risk_score to 0', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + risk_score: 0, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + ...getUpdateRulesSchemaDecodedMock(), + risk_score: 0, + }; + expect(message.schema).toEqual(expected); + }); + + test('You can set the risk_score to 100', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + risk_score: 100, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + ...getUpdateRulesSchemaDecodedMock(), + risk_score: 100, + }; + expect(message.schema).toEqual(expected); + }); + + test('You can set meta to any object you want', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + meta: { + somethingMadeUp: { somethingElse: true }, + }, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + ...getUpdateRulesSchemaDecodedMock(), + meta: { + somethingMadeUp: { somethingElse: true }, + }, + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot update meta as a string', () => { + const payload: Omit & { meta: string } = { + ...getUpdateRulesSchemaMock(), + meta: 'should not work', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "should not work" supplied to "meta"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You can omit the query string when filters are present', () => { + const { query, ...noQuery } = getUpdateRulesSchemaMock(); + const payload: UpdateRulesSchema = { + ...noQuery, + filters: [], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { query: expectedQuery, ...expectedNoQuery } = getUpdateRulesSchemaDecodedMock(); + const expected: UpdateRulesSchemaDecoded = { + ...expectedNoQuery, + filters: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('validates with timeline_id and timeline_title', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + timeline_id: 'timeline-id', + timeline_title: 'timeline-title', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + ...getUpdateRulesSchemaDecodedMock(), + timeline_id: 'timeline-id', + timeline_title: 'timeline-title', + }; + expect(message.schema).toEqual(expected); + }); + + test('The default for "from" will be "now-6m"', () => { + const { from, ...noFrom } = getUpdateRulesSchemaMock(); + const payload: UpdateRulesSchema = { + ...noFrom, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { from: expectedFrom, ...expectedNoFrom } = getUpdateRulesSchemaDecodedMock(); + const expected: UpdateRulesSchemaDecoded = { + ...expectedNoFrom, + from: 'now-6m', + }; + expect(message.schema).toEqual(expected); + }); + + test('The default for "to" will be "now"', () => { + const { to, ...noTo } = getUpdateRulesSchemaMock(); + const payload: UpdateRulesSchema = { + ...noTo, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { to: expectedTo, ...expectedNoTo } = getUpdateRulesSchemaDecodedMock(); + const expected: UpdateRulesSchemaDecoded = { + ...expectedNoTo, + to: 'now', + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot set the severity to a value other than low, medium, high, or critical', () => { + const payload: Omit & { severity: string } = { + ...getUpdateRulesSchemaMock(), + severity: 'junk', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "junk" supplied to "severity"']); + expect(message.schema).toEqual({}); + }); + + test('The default for "actions" will be an empty array', () => { + const { actions, ...noActions } = getUpdateRulesSchemaMock(); + const payload: UpdateRulesSchema = { + ...noActions, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { actions: expectedActions, ...expectedNoActions } = getUpdateRulesSchemaDecodedMock(); + const expected: UpdateRulesSchemaDecoded = { + ...expectedNoActions, + actions: [], + }; + expect(message.schema).toEqual(expected); + }); + + test('You cannot send in an array of actions that are missing "group"', () => { + const payload: Omit = { + ...getUpdateRulesSchemaMock(), + actions: [{ id: 'id', action_type_id: 'action_type_id', params: {} }], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "group"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are missing "id"', () => { + const payload: Omit = { + ...getUpdateRulesSchemaMock(), + actions: [{ group: 'group', action_type_id: 'action_type_id', params: {} }], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "undefined" supplied to "id"']); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are missing "action_type_id"', () => { + const payload: Omit = { + ...getUpdateRulesSchemaMock(), + actions: [{ group: 'group', id: 'id', params: {} }], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "action_type_id"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are missing "params"', () => { + const payload: Omit = { + ...getUpdateRulesSchemaMock(), + actions: [{ group: 'group', id: 'id', action_type_id: 'action_type_id' }], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "params"', + ]); + expect(message.schema).toEqual({}); + }); + + test('You cannot send in an array of actions that are including "actionTypeId"', () => { + const payload: Omit = { + ...getUpdateRulesSchemaMock(), + actions: [ + { + group: 'group', + id: 'id', + actionTypeId: 'actionTypeId', + params: {}, + }, + ], + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "action_type_id"', + ]); + expect(message.schema).toEqual({}); + }); + + test('The default for "throttle" will be null', () => { + const { throttle, ...noThrottle } = getUpdateRulesSchemaMock(); + const payload: UpdateRulesSchema = { + ...noThrottle, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + + const { throttle: expectedThrottle, ...expectedNoThrottle } = getUpdateRulesSchemaDecodedMock(); + const expected: UpdateRulesSchemaDecoded = { + ...expectedNoThrottle, + throttle: null, + }; + expect(message.schema).toEqual(expected); + }); + + describe('note', () => { + test('You can set note to a string', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + note: '# documentation markdown here', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + ...getUpdateRulesSchemaDecodedMock(), + note: '# documentation markdown here', + }; + expect(message.schema).toEqual(expected); + }); + + test('You can set note to an empty string', () => { + const payload: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + note: '', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + ...getUpdateRulesSchemaDecodedMock(), + note: '', + }; + expect(message.schema).toEqual(expected); + }); + + // Note: If you're looking to remove `note`, omit `note` entirely + test('You cannot set note to null', () => { + const payload: Omit & { note: null } = { + ...getUpdateRulesSchemaMock(), + note: null, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "null" supplied to "note"']); + expect(message.schema).toEqual({}); + }); + + test('You cannot set note as an object', () => { + const payload: Omit & { note: {} } = { + ...getUpdateRulesSchemaMock(), + note: { + somethingHere: 'something else', + }, + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + // TODO: Fix/Change the formatErrors to be better able to handle objects + 'Invalid value "[object Object]" supplied to "note"', + ]); + expect(message.schema).toEqual({}); + }); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note] does validate', () => { + const payload: UpdateRulesSchema = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + note: '# some markdown', + }; + + const decoded = updateRulesSchema.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + const expected: UpdateRulesSchemaDecoded = { + rule_id: 'rule-1', + description: 'some description', + from: 'now-5m', + to: 'now', + index: ['index-1'], + name: 'some-name', + severity: 'low', + interval: '5m', + type: 'query', + risk_score: 50, + note: '# some markdown', + references: [], + actions: [], + enabled: true, + false_positives: [], + max_signals: DEFAULT_MAX_SIGNALS, + tags: [], + threat: [], + throttle: null, + exceptions_list: [], + }; + expect(message.schema).toEqual(expected); + }); + }); + + // TODO: The exception_list tests are skipped and empty until we re-integrate it from the lists plugin + describe.skip('exception_list', () => { + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and exceptions_list] does validate', () => {}); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and empty exceptions_list] does validate', () => {}); + + test('rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and invalid exceptions_list] does NOT validate', () => {}); + + test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and non-existent exceptions_list] does validate with empty exceptions_list', () => {}); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.ts new file mode 100644 index 0000000000000..504233f95986f --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.ts @@ -0,0 +1,140 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; + +/* eslint-disable @typescript-eslint/camelcase */ +import { + description, + anomaly_threshold, + filters, + RuleId, + index, + output_index, + saved_id, + timeline_id, + timeline_title, + meta, + machine_learning_job_id, + risk_score, + rule_id, + MaxSignals, + name, + severity, + Tags, + To, + type, + Threat, + ThrottleOrNull, + note, + version, + References, + Actions, + Enabled, + FalsePositives, + From, + Interval, + language, + query, + id, +} from '../common/schemas'; +/* eslint-enable @typescript-eslint/camelcase */ + +import { DefaultStringArray } from '../types/default_string_array'; +import { DefaultActionsArray } from '../types/default_actions_array'; +import { DefaultBooleanTrue } from '../types/default_boolean_true'; +import { DefaultFromString } from '../types/default_from_string'; +import { DefaultIntervalString } from '../types/default_interval_string'; +import { DefaultMaxSignalsNumber } from '../types/default_max_signals_number'; +import { DefaultToString } from '../types/default_to_string'; +import { DefaultThreatArray } from '../types/default_threat_array'; +import { DefaultThrottleNull } from '../types/default_throttle_null'; +import { ListsDefaultArray, ListsDefaultArraySchema } from '../types/lists_default_array'; + +/** + * This almost identical to the create_rules_schema except for a few details. + * - The version will not be defaulted to a 1. If it is not given then its default will become the previous version auto-incremented + * This does break idempotency slightly as calls repeatedly without it will increment the number. If the version number is passed in + * this will update the rule's version number. + * - id is on here because you can pass in an id to update using it instead of rule_id. + */ +export const updateRulesSchema = t.intersection([ + t.exact( + t.type({ + description, + risk_score, + name, + severity, + type, + }) + ), + t.exact( + t.partial({ + id, // defaults to "undefined" if not set during decode + actions: DefaultActionsArray, // defaults to empty actions array if not set during decode + anomaly_threshold, // defaults to undefined if not set during decode + enabled: DefaultBooleanTrue, // defaults to true if not set during decode + false_positives: DefaultStringArray, // defaults to empty string array if not set during decode + filters, // defaults to undefined if not set during decode + from: DefaultFromString, // defaults to "now-6m" if not set during decode + rule_id, // defaults to "undefined" if not set during decode + index, // defaults to undefined if not set during decode + interval: DefaultIntervalString, // defaults to "5m" if not set during decode + query, // defaults to undefined if not set during decode + language, // defaults to undefined if not set during decode + // TODO: output_index: This should be removed eventually + output_index, // defaults to "undefined" if not set during decode + saved_id, // defaults to "undefined" if not set during decode + timeline_id, // defaults to "undefined" if not set during decode + timeline_title, // defaults to "undefined" if not set during decode + meta, // defaults to "undefined" if not set during decode + machine_learning_job_id, // defaults to "undefined" if not set during decode + max_signals: DefaultMaxSignalsNumber, // defaults to DEFAULT_MAX_SIGNALS (100) if not set during decode + tags: DefaultStringArray, // defaults to empty string array if not set during decode + to: DefaultToString, // defaults to "now" if not set during decode + threat: DefaultThreatArray, // defaults to empty array if not set during decode + throttle: DefaultThrottleNull, // defaults to "null" if not set during decode + references: DefaultStringArray, // defaults to empty array of strings if not set during decode + note, // defaults to "undefined" if not set during decode + version, // defaults to "undefined" if not set during decode + exceptions_list: ListsDefaultArray, // defaults to empty array if not set during decode + }) + ), +]); + +export type UpdateRulesSchema = t.TypeOf; + +// This type is used after a decode since some things are defaults after a decode. +export type UpdateRulesSchemaDecoded = Omit< + UpdateRulesSchema, + | 'references' + | 'actions' + | 'enabled' + | 'false_positives' + | 'from' + | 'interval' + | 'max_signals' + | 'tags' + | 'to' + | 'threat' + | 'throttle' + | 'exceptions_list' + | 'rule_id' +> & { + references: References; + actions: Actions; + enabled: Enabled; + false_positives: FalsePositives; + from: From; + interval: Interval; + max_signals: MaxSignals; + tags: Tags; + to: To; + threat: Threat; + throttle: ThrottleOrNull; + exceptions_list: ListsDefaultArraySchema; + rule_id: RuleId; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_type_dependents.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_type_dependents.test.ts new file mode 100644 index 0000000000000..a63c8243cb5f1 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_type_dependents.test.ts @@ -0,0 +1,88 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getUpdateRulesSchemaMock } from './update_rules_schema.mock'; +import { UpdateRulesSchema } from './update_rules_schema'; +import { updateRuleValidateTypeDependents } from './update_rules_type_dependents'; + +describe('update_rules_type_dependents', () => { + test('saved_id is required when type is saved_query and will not validate without out', () => { + const schema: UpdateRulesSchema = { ...getUpdateRulesSchemaMock(), type: 'saved_query' }; + delete schema.saved_id; + const errors = updateRuleValidateTypeDependents(schema); + expect(errors).toEqual(['when "type" is "saved_query", "saved_id" is required']); + }); + + test('saved_id is required when type is saved_query and validates with it', () => { + const schema: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + type: 'saved_query', + saved_id: '123', + }; + const errors = updateRuleValidateTypeDependents(schema); + expect(errors).toEqual([]); + }); + + test('You cannot omit timeline_title when timeline_id is present', () => { + const schema: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + timeline_id: '123', + }; + delete schema.timeline_title; + const errors = updateRuleValidateTypeDependents(schema); + expect(errors).toEqual(['when "timeline_id" exists, "timeline_title" must also exist']); + }); + + test('You cannot have empty string for timeline_title when timeline_id is present', () => { + const schema: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + timeline_id: '123', + timeline_title: '', + }; + const errors = updateRuleValidateTypeDependents(schema); + expect(errors).toEqual(['"timeline_title" cannot be an empty string']); + }); + + test('You cannot have timeline_title with an empty timeline_id', () => { + const schema: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + timeline_id: '', + timeline_title: 'some-title', + }; + const errors = updateRuleValidateTypeDependents(schema); + expect(errors).toEqual(['"timeline_id" cannot be an empty string']); + }); + + test('You cannot have timeline_title without timeline_id', () => { + const schema: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + timeline_title: 'some-title', + }; + delete schema.timeline_id; + const errors = updateRuleValidateTypeDependents(schema); + expect(errors).toEqual(['when "timeline_title" exists, "timeline_id" must also exist']); + }); + + test('You cannot have both an id and a rule_id', () => { + const schema: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + id: 'some-id', + rule_id: 'some-rule-id', + }; + const errors = updateRuleValidateTypeDependents(schema); + expect(errors).toEqual(['both "id" and "rule_id" cannot exist, choose one or the other']); + }); + + test('You must set either an id or a rule_id', () => { + const schema: UpdateRulesSchema = { + ...getUpdateRulesSchemaMock(), + }; + delete schema.id; + delete schema.rule_id; + const errors = updateRuleValidateTypeDependents(schema); + expect(errors).toEqual(['either "id" or "rule_id" must be set']); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_type_dependents.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_type_dependents.ts new file mode 100644 index 0000000000000..9204f727b2660 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_type_dependents.ts @@ -0,0 +1,116 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { UpdateRulesSchema } from './update_rules_schema'; + +export const validateAnomalyThreshold = (rule: UpdateRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.anomaly_threshold == null) { + return ['when "type" is "machine_learning" anomaly_threshold is required']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateQuery = (rule: UpdateRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.query != null) { + return ['when "type" is "machine_learning", "query" cannot be set']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateLanguage = (rule: UpdateRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.language != null) { + return ['when "type" is "machine_learning", "language" cannot be set']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateSavedId = (rule: UpdateRulesSchema): string[] => { + if (rule.type === 'saved_query') { + if (rule.saved_id == null) { + return ['when "type" is "saved_query", "saved_id" is required']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateMachineLearningJobId = (rule: UpdateRulesSchema): string[] => { + if (rule.type === 'machine_learning') { + if (rule.machine_learning_job_id == null) { + return ['when "type" is "machine_learning", "machine_learning_job_id" is required']; + } else { + return []; + } + } else { + return []; + } +}; + +export const validateTimelineId = (rule: UpdateRulesSchema): string[] => { + if (rule.timeline_id != null) { + if (rule.timeline_title == null) { + return ['when "timeline_id" exists, "timeline_title" must also exist']; + } else if (rule.timeline_id === '') { + return ['"timeline_id" cannot be an empty string']; + } else { + return []; + } + } + return []; +}; + +export const validateTimelineTitle = (rule: UpdateRulesSchema): string[] => { + if (rule.timeline_title != null) { + if (rule.timeline_id == null) { + return ['when "timeline_title" exists, "timeline_id" must also exist']; + } else if (rule.timeline_title === '') { + return ['"timeline_title" cannot be an empty string']; + } else { + return []; + } + } + return []; +}; + +export const validateId = (rule: UpdateRulesSchema): string[] => { + if (rule.id != null && rule.rule_id != null) { + return ['both "id" and "rule_id" cannot exist, choose one or the other']; + } else if (rule.id == null && rule.rule_id == null) { + return ['either "id" or "rule_id" must be set']; + } else { + return []; + } +}; + +export const updateRuleValidateTypeDependents = (schema: UpdateRulesSchema): string[] => { + return [ + ...validateId(schema), + ...validateAnomalyThreshold(schema), + ...validateQuery(schema), + ...validateLanguage(schema), + ...validateSavedId(schema), + ...validateMachineLearningJobId(schema), + ...validateTimelineId(schema), + ...validateTimelineTitle(schema), + ]; +}; diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/__mocks__/utils.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/__mocks__/utils.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/__mocks__/utils.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/__mocks__/utils.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/error_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.test.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/error_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.test.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/error_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/error_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/find_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/find_rules_schema.test.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/find_rules_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/find_rules_schema.test.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/find_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/find_rules_schema.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/find_rules_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/find_rules_schema.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/import_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/import_rules_schema.test.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/import_rules_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/import_rules_schema.test.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/import_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/import_rules_schema.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/import_rules_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/import_rules_schema.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/prepackaged_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_schema.test.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/prepackaged_rules_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_schema.test.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/prepackaged_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_schema.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/prepackaged_rules_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_schema.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/prepackaged_rules_status_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_status_schema.test.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/prepackaged_rules_status_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_status_schema.test.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/prepackaged_rules_status_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_status_schema.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/prepackaged_rules_status_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_status_schema.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/rules_bulk_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_bulk_schema.test.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/rules_bulk_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_bulk_schema.test.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/rules_bulk_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_bulk_schema.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/rules_bulk_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_bulk_schema.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.test.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/rules_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.test.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/rules_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/type_timeline_only_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/type_timeline_only_schema.test.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/type_timeline_only_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/type_timeline_only_schema.test.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/response/type_timeline_only_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/type_timeline_only_schema.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/response/type_timeline_only_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/response/type_timeline_only_schema.ts diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/deafult_boolean_true.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/deafult_boolean_true.test.ts new file mode 100644 index 0000000000000..a2deaf626624f --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/deafult_boolean_true.test.ts @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultBooleanTrue } from './default_boolean_true'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; + +describe('default_boolean_true', () => { + test('it should validate a boolean false', () => { + const payload = false; + const decoded = DefaultBooleanTrue.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate a boolean true', () => { + const payload = true; + const decoded = DefaultBooleanTrue.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate a number', () => { + const payload = 5; + const decoded = DefaultBooleanTrue.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default true', () => { + const payload = null; + const decoded = DefaultBooleanTrue.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(true); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/deafult_from_string.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/deafult_from_string.test.ts new file mode 100644 index 0000000000000..d68d447ca4454 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/deafult_from_string.test.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultFromString } from './default_from_string'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; + +describe('default_from_string', () => { + test('it should validate a from string', () => { + const payload = 'now-20m'; + const decoded = DefaultFromString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate a number', () => { + const payload = 5; + const decoded = DefaultFromString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default of "now-6m"', () => { + const payload = null; + const decoded = DefaultFromString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual('now-6m'); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.test.ts new file mode 100644 index 0000000000000..645eade71916f --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.test.ts @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultActionsArray } from './default_actions_array'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { Actions } from '../common/schemas'; + +describe('default_actions_array', () => { + test('it should validate an empty array', () => { + const payload: string[] = []; + const decoded = DefaultActionsArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate an array of actions', () => { + const payload: Actions = [ + { id: '123', group: 'group', action_type_id: 'action_type_id', params: {} }, + ]; + const decoded = DefaultActionsArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate an array with a number', () => { + const payload = [ + { id: '123', group: 'group', action_type_id: 'action_type_id', params: {} }, + 5, + ]; + const decoded = DefaultActionsArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default array entry', () => { + const payload = null; + const decoded = DefaultActionsArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual([]); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.ts new file mode 100644 index 0000000000000..ce3eb7fa7da83 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_actions_array.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; +import { actions, Actions } from '../common/schemas'; + +/** + * Types the DefaultStringArray as: + * - If null or undefined, then a default action array will be set + */ +export const DefaultActionsArray = new t.Type( + 'DefaultActionsArray', + actions.is, + (input): Either => (input == null ? t.success([]) : actions.decode(input)), + t.identity +); + +export type DefaultActionsArrayC = typeof DefaultActionsArray; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.test.ts new file mode 100644 index 0000000000000..1697928b17e0c --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.test.ts @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultBooleanFalse } from './default_boolean_false'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; + +describe('default_boolean_false', () => { + test('it should validate a boolean false', () => { + const payload = false; + const decoded = DefaultBooleanFalse.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate a boolean true', () => { + const payload = true; + const decoded = DefaultBooleanFalse.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate a number', () => { + const payload = 5; + const decoded = DefaultBooleanFalse.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default false', () => { + const payload = null; + const decoded = DefaultBooleanFalse.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(false); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.ts new file mode 100644 index 0000000000000..624b9802f680c --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_false.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; + +/** + * Types the DefaultBooleanFalse as: + * - If null or undefined, then a default false will be set + */ +export const DefaultBooleanFalse = new t.Type( + 'DefaultBooleanFalse', + t.boolean.is, + (input): Either => + input == null ? t.success(false) : t.boolean.decode(input), + t.identity +); + +export type DefaultBooleanFalseC = typeof DefaultBooleanFalse; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_true.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_true.ts new file mode 100644 index 0000000000000..58c912a0a8650 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_boolean_true.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; + +/** + * Types the DefaultBooleanTrue as: + * - If null or undefined, then a default true will be set + */ +export const DefaultBooleanTrue = new t.Type( + 'DefaultBooleanTrue', + t.boolean.is, + (input): Either => (input == null ? t.success(true) : t.boolean.decode(input)), + t.identity +); + +export type DefaultBooleanTrueC = typeof DefaultBooleanTrue; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.test.ts new file mode 100644 index 0000000000000..386d4c55905cd --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.test.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultEmptyString } from './default_empty_string'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; + +describe('default_empty_string', () => { + test('it should validate a regular string', () => { + const payload = 'some string'; + const decoded = DefaultEmptyString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate a number', () => { + const payload = 5; + const decoded = DefaultEmptyString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default of ""', () => { + const payload = null; + const decoded = DefaultEmptyString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(''); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.ts new file mode 100644 index 0000000000000..6216d0c1111b0 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_empty_string.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; + +/** + * Types the DefaultEmptyString as: + * - If null or undefined, then a default of an empty string "" will be used + */ +export const DefaultEmptyString = new t.Type( + 'DefaultEmptyString', + t.string.is, + (input): Either => (input == null ? t.success('') : t.string.decode(input)), + t.identity +); + +export type DefaultEmptyStringC = typeof DefaultEmptyString; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.test.ts new file mode 100644 index 0000000000000..328cd738d7de0 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.test.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultExportFileName } from './default_export_file_name'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; + +describe('default_export_file_name', () => { + test('it should validate a regular string', () => { + const payload = 'some string'; + const decoded = DefaultExportFileName.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate a number', () => { + const payload = 5; + const decoded = DefaultExportFileName.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default of "export.ndjson"', () => { + const payload = null; + const decoded = DefaultExportFileName.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual('export.ndjson'); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.ts new file mode 100644 index 0000000000000..41dfdee1e0da0 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_export_file_name.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; + +/** + * Types the DefaultExportFileName as: + * - If null or undefined, then a default of "export.ndjson" will be used + */ +export const DefaultExportFileName = new t.Type( + 'DefaultExportFileName', + t.string.is, + (input): Either => + input == null ? t.success('export.ndjson') : t.string.decode(input), + t.identity +); + +export type DefaultExportFileNameC = typeof DefaultExportFileName; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_from_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_from_string.ts new file mode 100644 index 0000000000000..4217532de954e --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_from_string.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; + +/** + * Types the DefaultFromString as: + * - If null or undefined, then a default of the string "now-6m" will be used + */ +export const DefaultFromString = new t.Type( + 'DefaultFromString', + t.string.is, + (input): Either => + input == null ? t.success('now-6m') : t.string.decode(input), + t.identity +); + +export type DefaultFromStringC = typeof DefaultFromString; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.test.ts new file mode 100644 index 0000000000000..9720178a4ae9b --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.test.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultIntervalString } from './default_interval_string'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; + +describe('default_interval_string', () => { + test('it should validate a interval string', () => { + const payload = '20m'; + const decoded = DefaultIntervalString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate a number', () => { + const payload = 5; + const decoded = DefaultIntervalString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default of "5m"', () => { + const payload = null; + const decoded = DefaultIntervalString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual('5m'); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.ts new file mode 100644 index 0000000000000..579e7591fdb03 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_interval_string.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; + +/** + * Types the DefaultIntervalString as: + * - If null or undefined, then a default of the string "5m" will be used + */ +export const DefaultIntervalString = new t.Type( + 'DefaultIntervalString', + t.string.is, + (input): Either => (input == null ? t.success('5m') : t.string.decode(input)), + t.identity +); + +export type DefaultIntervalStringC = typeof DefaultIntervalString; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.test.ts new file mode 100644 index 0000000000000..e3da8dbd280ab --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.test.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultLanguageString } from './default_language_string'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { Language } from '../common/schemas'; + +describe('default_language_string', () => { + test('it should validate a string', () => { + const payload: Language = 'lucene'; + const decoded = DefaultLanguageString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate a number', () => { + const payload = 5; + const decoded = DefaultLanguageString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default of "kuery"', () => { + const payload = null; + const decoded = DefaultLanguageString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual('kuery'); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.ts new file mode 100644 index 0000000000000..248e15d56dfd7 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_language_string.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; +import { language } from '../common/schemas'; + +/** + * Types the DefaultLanguageString as: + * - If null or undefined, then a default of the string "kuery" will be used + */ +export const DefaultLanguageString = new t.Type( + 'DefaultLanguageString', + t.string.is, + (input): Either => + input == null ? t.success('kuery') : language.decode(input), + t.identity +); + +export type DefaultLanguageStringC = typeof DefaultLanguageString; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.test.ts new file mode 100644 index 0000000000000..a6f137c3f2113 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.test.ts @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultMaxSignalsNumber } from './default_max_signals_number'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { DEFAULT_MAX_SIGNALS } from '../../../constants'; + +describe('default_from_string', () => { + test('it should validate a max signal number', () => { + const payload = 5; + const decoded = DefaultMaxSignalsNumber.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate a string', () => { + const payload = '5'; + const decoded = DefaultMaxSignalsNumber.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate a zero', () => { + const payload = 0; + const decoded = DefaultMaxSignalsNumber.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate a negative number', () => { + const payload = -1; + const decoded = DefaultMaxSignalsNumber.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default of DEFAULT_MAX_SIGNALS', () => { + const payload = null; + const decoded = DefaultMaxSignalsNumber.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(DEFAULT_MAX_SIGNALS); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.ts new file mode 100644 index 0000000000000..6f0c32c5466f3 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_max_signals_number.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; +// eslint-disable-next-line @typescript-eslint/camelcase +import { max_signals } from '../common/schemas'; +import { DEFAULT_MAX_SIGNALS } from '../../../constants'; + +/** + * Types the default max signal: + * - Natural Number (positive integer and not a float), + * - greater than 1 + * - If undefined then it will use DEFAULT_MAX_SIGNALS (100) as the default + */ +export const DefaultMaxSignalsNumber: DefaultMaxSignalsNumberC = new t.Type< + number, + number, + unknown +>( + 'DefaultMaxSignals', + t.number.is, + (input): Either => { + return input == null ? t.success(DEFAULT_MAX_SIGNALS) : max_signals.decode(input); + }, + t.identity +); + +export type DefaultMaxSignalsNumberC = t.Type; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.test.ts new file mode 100644 index 0000000000000..1d1d43667c710 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.test.ts @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultPage } from './default_page'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; + +describe('default_page', () => { + test('it should validate a regular number greater than zero', () => { + const payload = 5; + const decoded = DefaultPage.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate a string of a number', () => { + const payload = '5'; + const decoded = DefaultPage.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(5); + }); + + test('it should not validate a junk string', () => { + const payload = 'invalid-string'; + const decoded = DefaultPage.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "NaN" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate an empty string', () => { + const payload = ''; + const decoded = DefaultPage.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "NaN" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate a zero', () => { + const payload = 0; + const decoded = DefaultPage.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate a negative number', () => { + const payload = -1; + const decoded = DefaultPage.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default of 20', () => { + const payload = null; + const decoded = DefaultPage.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(1); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.ts new file mode 100644 index 0000000000000..95e3b42f3e138 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_page.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; +import { PositiveIntegerGreaterThanZero } from './positive_integer_greater_than_zero'; + +/** + * Types the DefaultPerPage as: + * - If a string this will convert the string to a number + * - If null or undefined, then a default of 1 will be used + * - If the number is 0 or less this will not validate as it has to be a positive number greater than zero + */ +export const DefaultPage = new t.Type( + 'DefaultPerPage', + t.number.is, + (input): Either => { + if (input == null) { + return t.success(1); + } else if (typeof input === 'string') { + return PositiveIntegerGreaterThanZero.decode(parseInt(input, 10)); + } else { + return PositiveIntegerGreaterThanZero.decode(input); + } + }, + t.identity +); + +export type DefaultPageC = typeof DefaultPage; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.test.ts new file mode 100644 index 0000000000000..3ecbae6ed43f5 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.test.ts @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultPerPage } from './default_per_page'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; + +describe('default_per_page', () => { + test('it should validate a regular number greater than zero', () => { + const payload = 5; + const decoded = DefaultPerPage.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate a string of a number', () => { + const payload = '5'; + const decoded = DefaultPerPage.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(5); + }); + + test('it should not validate a junk string', () => { + const payload = 'invalid-string'; + const decoded = DefaultPerPage.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "NaN" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate an empty string', () => { + const payload = ''; + const decoded = DefaultPerPage.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "NaN" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate a zero', () => { + const payload = 0; + const decoded = DefaultPerPage.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate a negative number', () => { + const payload = -1; + const decoded = DefaultPerPage.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default of 20', () => { + const payload = null; + const decoded = DefaultPerPage.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(20); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.ts new file mode 100644 index 0000000000000..f96f280f6af11 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_per_page.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; +import { PositiveIntegerGreaterThanZero } from './positive_integer_greater_than_zero'; + +/** + * Types the DefaultPerPage as: + * - If a string this will convert the string to a number + * - If null or undefined, then a default of 20 will be used + * - If the number is 0 or less this will not validate as it has to be a positive number greater than zero + */ +export const DefaultPerPage = new t.Type( + 'DefaultPerPage', + t.number.is, + (input): Either => { + if (input == null) { + return t.success(20); + } else if (typeof input === 'string') { + return PositiveIntegerGreaterThanZero.decode(parseInt(input, 10)); + } else { + return PositiveIntegerGreaterThanZero.decode(input); + } + }, + t.identity +); + +export type DefaultPerPageC = typeof DefaultPerPage; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.test.ts new file mode 100644 index 0000000000000..83142c8d65777 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.test.ts @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultStringArray } from './default_string_array'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; + +describe('default_string_array', () => { + test('it should validate an empty array', () => { + const payload: string[] = []; + const decoded = DefaultStringArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate an array of strings', () => { + const payload = ['value 1', 'value 2']; + const decoded = DefaultStringArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate an array with a number', () => { + const payload = ['value 1', 5]; + const decoded = DefaultStringArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default array entry', () => { + const payload = null; + const decoded = DefaultStringArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual([]); + }); +}); diff --git a/x-pack/plugins/lists/common/schemas/types/default_string_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.ts similarity index 75% rename from x-pack/plugins/lists/common/schemas/types/default_string_array.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.ts index c6ebffa379903..1f043cfd1b8e5 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_string_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_array.ts @@ -7,16 +7,16 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -export type DefaultStringArrayC = t.Type; - /** * Types the DefaultStringArray as: * - If null or undefined, then a default array will be set */ -export const DefaultStringArray: DefaultStringArrayC = new t.Type( - 'DefaultArray', +export const DefaultStringArray = new t.Type( + 'DefaultStringArray', t.array(t.string).is, (input): Either => input == null ? t.success([]) : t.array(t.string).decode(input), t.identity ); + +export type DefaultStringArrayC = typeof DefaultStringArray; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.test.ts new file mode 100644 index 0000000000000..1941a642e8baf --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.test.ts @@ -0,0 +1,93 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { DefaultStringBooleanFalse } from './default_string_boolean_false'; + +describe('default_string_boolean_false', () => { + test('it should validate a boolean false', () => { + const payload = false; + const decoded = DefaultStringBooleanFalse.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate a boolean true', () => { + const payload = true; + const decoded = DefaultStringBooleanFalse.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate a number', () => { + const payload = 5; + const decoded = DefaultStringBooleanFalse.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default false', () => { + const payload = null; + const decoded = DefaultStringBooleanFalse.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(false); + }); + + test('it should return a default false when given a string of "false"', () => { + const payload = 'false'; + const decoded = DefaultStringBooleanFalse.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(false); + }); + + test('it should return a default true when given a string of "true"', () => { + const payload = 'true'; + const decoded = DefaultStringBooleanFalse.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(true); + }); + + test('it should return a default true when given a string of "TruE"', () => { + const payload = 'TruE'; + const decoded = DefaultStringBooleanFalse.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(true); + }); + + test('it should not work with a strong of junk "junk"', () => { + const payload = 'junk'; + const decoded = DefaultStringBooleanFalse.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "junk" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should not work with an empty string', () => { + const payload = ''; + const decoded = DefaultStringBooleanFalse.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to ""']); + expect(message.schema).toEqual({}); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.ts new file mode 100644 index 0000000000000..48a40d4b9ceec --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_string_boolean_false.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; + +/** + * Types the DefaultStringBooleanFalse as: + * - If a string this will convert the string to a boolean + * - If null or undefined, then a default false will be set + */ +export const DefaultStringBooleanFalse = new t.Type( + 'DefaultStringBooleanFalse', + t.boolean.is, + (input): Either => { + if (input == null) { + return t.success(false); + } else if (typeof input === 'string' && input.toLowerCase() === 'true') { + return t.success(true); + } else if (typeof input === 'string' && input.toLowerCase() === 'false') { + return t.success(false); + } else { + return t.boolean.decode(input); + } + }, + t.identity +); + +export type DefaultStringBooleanFalseC = typeof DefaultStringBooleanFalse; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.test.ts new file mode 100644 index 0000000000000..9819da0b8d463 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.test.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultThreatArray } from './default_threat_array'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { Threat } from '../common/schemas'; + +describe('default_threat_null', () => { + test('it should validate an empty array', () => { + const payload: Threat = []; + const decoded = DefaultThreatArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate an array of threats', () => { + const payload: Threat = [ + { + framework: 'MITRE ATTACK', + technique: [{ reference: 'https://test.com', name: 'Audio Capture', id: 'T1123' }], + tactic: { reference: 'https://test.com', name: 'Collection', id: 'TA000999' }, + }, + ]; + const decoded = DefaultThreatArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate an array with a number', () => { + const payload = [ + { + framework: 'MITRE ATTACK', + technique: [{ reference: 'https://test.com', name: 'Audio Capture', id: 'T1123' }], + tactic: { reference: 'https://test.com', name: 'Collection', id: 'TA000999' }, + }, + 5, + ]; + const decoded = DefaultThreatArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default empty array if not provided a value', () => { + const payload = null; + const decoded = DefaultThreatArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual([]); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.ts new file mode 100644 index 0000000000000..da0611e24bc7e --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_threat_array.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; +import { Threat, threat } from '../common/schemas'; + +/** + * Types the DefaultThreatArray as: + * - If null or undefined, then an empty array will be set + */ +export const DefaultThreatArray = new t.Type( + 'DefaultThreatArray', + threat.is, + (input): Either => (input == null ? t.success([]) : threat.decode(input)), + t.identity +); + +export type DefaultThreatArrayC = typeof DefaultThreatArray; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.test.ts new file mode 100644 index 0000000000000..304fd65647c3c --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.test.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultThrottleNull } from './default_throttle_null'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; +import { Throttle } from '../common/schemas'; + +describe('default_throttle_null', () => { + test('it should validate a throttle string', () => { + const payload: Throttle = 'some string'; + const decoded = DefaultThrottleNull.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate an array with a number', () => { + const payload = 5; + const decoded = DefaultThrottleNull.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default "null" if not provided a value', () => { + const payload = undefined; + const decoded = DefaultThrottleNull.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(null); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.ts new file mode 100644 index 0000000000000..fd31594323f4d --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_throttle_null.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; +import { ThrottleOrNull, throttle } from '../common/schemas'; + +/** + * Types the DefaultThrottleNull as: + * - If null or undefined, then a null will be set + */ +export const DefaultThrottleNull = new t.Type( + 'DefaultThreatNull', + throttle.is, + (input): Either => + input == null ? t.success(null) : throttle.decode(input), + t.identity +); + +export type DefaultThrottleNullC = typeof DefaultThrottleNull; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.test.ts new file mode 100644 index 0000000000000..3e22d57cedf99 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.test.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultToString } from './default_to_string'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; + +describe('default_to_string', () => { + test('it should validate a to string', () => { + const payload = 'now-5m'; + const decoded = DefaultToString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate a number', () => { + const payload = 5; + const decoded = DefaultToString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default of "now"', () => { + const payload = null; + const decoded = DefaultToString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual('now'); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.ts new file mode 100644 index 0000000000000..163bcf8c4e5b2 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_to_string.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; + +/** + * Types the DefaultToString as: + * - If null or undefined, then a default of the string "now" will be used + */ +export const DefaultToString = new t.Type( + 'DefaultFromString', + t.string.is, + (input): Either => (input == null ? t.success('now') : t.string.decode(input)), + t.identity +); + +export type DefaultToStringC = typeof DefaultToString; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.test.ts new file mode 100644 index 0000000000000..7dab8869d5d87 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.test.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultUuid } from './default_uuid'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; + +describe('default_uuid', () => { + test('it should validate a regular string', () => { + const payload = '1'; + const decoded = DefaultUuid.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate a number', () => { + const payload = 5; + const decoded = DefaultUuid.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default of a uuid', () => { + const payload = null; + const decoded = DefaultUuid.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toMatch( + /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i + ); + }); +}); diff --git a/x-pack/plugins/lists/common/schemas/types/default_uuid.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.ts similarity index 84% rename from x-pack/plugins/lists/common/schemas/types/default_uuid.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.ts index 4fb4133d7353f..b0c328a93ff03 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_uuid.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_uuid.ts @@ -10,17 +10,17 @@ import uuid from 'uuid'; import { NonEmptyString } from './non_empty_string'; -export type DefaultUuidC = t.Type; - /** * Types the DefaultUuid as: * - If null or undefined, then a default string uuid.v4() will be * created otherwise it will be checked just against an empty string */ -export const DefaultUuid: DefaultUuidC = new t.Type( +export const DefaultUuid = new t.Type( 'DefaultUuid', t.string.is, (input): Either => input == null ? t.success(uuid.v4()) : NonEmptyString.decode(input), t.identity ); + +export type DefaultUuidC = typeof DefaultUuid; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.test.ts new file mode 100644 index 0000000000000..65697d8830b66 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.test.ts @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { DefaultVersionNumber } from './default_version_number'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; + +describe('default_version_number', () => { + test('it should validate a version number', () => { + const payload = 5; + const decoded = DefaultVersionNumber.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate a 0', () => { + const payload = 0; + const decoded = DefaultVersionNumber.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate a -1', () => { + const payload = -1; + const decoded = DefaultVersionNumber.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate a string', () => { + const payload = '5'; + const decoded = DefaultVersionNumber.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default of 1', () => { + const payload = null; + const decoded = DefaultVersionNumber.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(1); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.ts new file mode 100644 index 0000000000000..4a310329660df --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/default_version_number.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; +import { version, Version } from '../common/schemas'; + +/** + * Types the DefaultVersionNumber as: + * - If null or undefined, then a default of the number 1 will be used + */ +export const DefaultVersionNumber = new t.Type( + 'DefaultVersionNumber', + version.is, + (input): Either => (input == null ? t.success(1) : version.decode(input)), + t.identity +); + +export type DefaultVersionNumberC = typeof DefaultVersionNumber; diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/types/iso_date_string.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/iso_date_string.test.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/types/iso_date_string.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/types/iso_date_string.test.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/types/iso_date_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/iso_date_string.ts similarity index 85% rename from x-pack/plugins/siem/common/detection_engine/schemas/types/iso_date_string.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/types/iso_date_string.ts index d63c18154c5d4..4e12a45f21d0b 100644 --- a/x-pack/plugins/siem/common/detection_engine/schemas/types/iso_date_string.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/iso_date_string.ts @@ -7,13 +7,11 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -export type IsoDateStringC = t.Type; - /** * Types the IsoDateString as: * - A string that is an ISOString */ -export const IsoDateString: IsoDateStringC = new t.Type( +export const IsoDateString = new t.Type( 'IsoDateString', t.string.is, (input, context): Either => { @@ -34,3 +32,5 @@ export const IsoDateString: IsoDateStringC = new t.Type }, t.identity ); + +export type IsoDateStringC = typeof IsoDateString; diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/types/lists_default_array.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.test.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/types/lists_default_array.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.test.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/types/lists_default_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.ts similarity index 86% rename from x-pack/plugins/siem/common/detection_engine/schemas/types/lists_default_array.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.ts index 8244f4a29e193..8cdd865469112 100644 --- a/x-pack/plugins/siem/common/detection_engine/schemas/types/lists_default_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists_default_array.ts @@ -13,7 +13,6 @@ import { list_values_operator as listOperator, } from '../common/schemas'; -export type ListsDefaultArrayC = t.Type; export type List = t.TypeOf; export type ListValues = t.TypeOf; export type ListOperator = t.TypeOf; @@ -22,7 +21,7 @@ export type ListOperator = t.TypeOf; * Types the ListsDefaultArray as: * - If null or undefined, then a default array will be set for the list */ -export const ListsDefaultArray: ListsDefaultArrayC = new t.Type( +export const ListsDefaultArray = new t.Type( 'listsWithDefaultArray', t.array(listAnd).is, (input): Either => @@ -30,4 +29,6 @@ export const ListsDefaultArray: ListsDefaultArrayC = new t.Type; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/non_empty_string.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/non_empty_string.test.ts new file mode 100644 index 0000000000000..0a88b87421e70 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/non_empty_string.test.ts @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { NonEmptyString } from './non_empty_string'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; +import { foldLeftRight, getPaths } from '../../../test_utils'; + +describe('non_empty_string', () => { + test('it should validate a regular string', () => { + const payload = '1'; + const decoded = NonEmptyString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate a number', () => { + const payload = 5; + const decoded = NonEmptyString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate an empty string', () => { + const payload = ''; + const decoded = NonEmptyString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate empty spaces', () => { + const payload = ' '; + const decoded = NonEmptyString.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value " " supplied to ""']); + expect(message.schema).toEqual({}); + }); +}); diff --git a/x-pack/plugins/lists/common/schemas/types/non_empty_string.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/non_empty_string.ts similarity index 81% rename from x-pack/plugins/lists/common/schemas/types/non_empty_string.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/types/non_empty_string.ts index d1e2094bbcad3..b3fad548932d5 100644 --- a/x-pack/plugins/lists/common/schemas/types/non_empty_string.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/non_empty_string.ts @@ -7,13 +7,11 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -export type NonEmptyStringC = t.Type; - /** * Types the NonEmptyString as: * - A string that is not empty */ -export const NonEmptyString: NonEmptyStringC = new t.Type( +export const NonEmptyString = new t.Type( 'NonEmptyString', t.string.is, (input, context): Either => { @@ -25,3 +23,5 @@ export const NonEmptyString: NonEmptyStringC = new t.Type { + test('it should validate a boolean false as false', () => { + const payload = false; + const decoded = OnlyFalseAllowed.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should not validate a boolean true', () => { + const payload = true; + const decoded = OnlyFalseAllowed.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "true" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should not validate a number', () => { + const payload = 5; + const decoded = OnlyFalseAllowed.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); + expect(message.schema).toEqual({}); + }); + + test('it should return a default false', () => { + const payload = null; + const decoded = OnlyFalseAllowed.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(false); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/only_false_allowed.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/only_false_allowed.ts new file mode 100644 index 0000000000000..b22562e2ab9dc --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/only_false_allowed.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { Either } from 'fp-ts/lib/Either'; + +/** + * Types the OnlyFalseAllowed as: + * - If null or undefined, then a default false will be set + * - If true is sent in then this will return an error + * - If false is sent in then this will allow it only false + */ +export const OnlyFalseAllowed = new t.Type( + 'DefaultBooleanTrue', + t.boolean.is, + (input, context): Either => { + if (input == null) { + return t.success(false); + } else { + if (typeof input === 'boolean' && input === false) { + return t.success(false); + } else { + return t.failure(input, context); + } + } + }, + t.identity +); + +export type OnlyFalseAllowedC = typeof OnlyFalseAllowed; diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/types/positive_integer.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/positive_integer.ts similarity index 82% rename from x-pack/plugins/siem/common/detection_engine/schemas/types/positive_integer.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/types/positive_integer.ts index ac98dd6f5d85c..298487a3fae98 100644 --- a/x-pack/plugins/siem/common/detection_engine/schemas/types/positive_integer.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/positive_integer.ts @@ -7,14 +7,12 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -export type PositiveIntegerC = t.Type; - /** * Types the positive integer are: * - Natural Number (positive integer and not a float), * - zero or greater */ -export const PositiveInteger: PositiveIntegerC = new t.Type( +export const PositiveInteger = new t.Type( 'PositiveInteger', t.number.is, (input, context): Either => { @@ -24,3 +22,5 @@ export const PositiveInteger: PositiveIntegerC = new t.Type; - /** * Types the positive integer greater than zero is: * - Natural Number (positive integer and not a float), * - 1 or greater */ -export const PositiveIntegerGreaterThanZero: PositiveIntegerGreaterThanZeroC = new t.Type< - number, - number, - unknown ->( +export const PositiveIntegerGreaterThanZero = new t.Type( 'PositiveIntegerGreaterThanZero', t.number.is, (input, context): Either => { @@ -28,3 +22,5 @@ export const PositiveIntegerGreaterThanZero: PositiveIntegerGreaterThanZeroC = n }, t.identity ); + +export type PositiveIntegerGreaterThanZeroC = typeof PositiveIntegerGreaterThanZero; diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/types/postive_integer.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/postive_integer.test.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/types/postive_integer.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/types/postive_integer.test.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/types/references_default_array.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/references_default_array.test.ts similarity index 80% rename from x-pack/plugins/siem/common/detection_engine/schemas/types/references_default_array.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/types/references_default_array.test.ts index 43e2dbdac1fe1..83142c8d65777 100644 --- a/x-pack/plugins/siem/common/detection_engine/schemas/types/references_default_array.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/references_default_array.test.ts @@ -4,15 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ReferencesDefaultArray } from './references_default_array'; +import { DefaultStringArray } from './default_string_array'; import { pipe } from 'fp-ts/lib/pipeable'; import { left } from 'fp-ts/lib/Either'; import { foldLeftRight, getPaths } from '../../../test_utils'; -describe('references_default_array', () => { +describe('default_string_array', () => { test('it should validate an empty array', () => { const payload: string[] = []; - const decoded = ReferencesDefaultArray.decode(payload); + const decoded = DefaultStringArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -21,7 +21,7 @@ describe('references_default_array', () => { test('it should validate an array of strings', () => { const payload = ['value 1', 'value 2']; - const decoded = ReferencesDefaultArray.decode(payload); + const decoded = DefaultStringArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -30,7 +30,7 @@ describe('references_default_array', () => { test('it should not validate an array with a number', () => { const payload = ['value 1', 5]; - const decoded = ReferencesDefaultArray.decode(payload); + const decoded = DefaultStringArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to ""']); @@ -39,7 +39,7 @@ describe('references_default_array', () => { test('it should return a default array entry', () => { const payload = null; - const decoded = ReferencesDefaultArray.decode(payload); + const decoded = DefaultStringArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/types/references_default_array.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/references_default_array.ts similarity index 76% rename from x-pack/plugins/siem/common/detection_engine/schemas/types/references_default_array.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/types/references_default_array.ts index 57a7ed4e4d456..b809181ce8c32 100644 --- a/x-pack/plugins/siem/common/detection_engine/schemas/types/references_default_array.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/references_default_array.ts @@ -7,20 +7,16 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -export type ReferencesDefaultArrayC = t.Type; - /** * Types the ReferencesDefaultArray as: * - If null or undefined, then a default array will be set */ -export const ReferencesDefaultArray: ReferencesDefaultArrayC = new t.Type< - string[], - string[], - unknown ->( +export const ReferencesDefaultArray = new t.Type( 'referencesWithDefaultArray', t.array(t.string).is, (input): Either => input == null ? t.success([]) : t.array(t.string).decode(input), t.identity ); + +export type ReferencesDefaultArrayC = typeof ReferencesDefaultArray; diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/types/risk_score.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/risk_score.test.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/types/risk_score.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/types/risk_score.test.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/types/risk_score.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/risk_score.ts similarity index 84% rename from x-pack/plugins/siem/common/detection_engine/schemas/types/risk_score.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/types/risk_score.ts index c44fae3c6f3e7..7f057a6d178e1 100644 --- a/x-pack/plugins/siem/common/detection_engine/schemas/types/risk_score.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/risk_score.ts @@ -7,14 +7,12 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -export type RiskScoreC = t.Type; - /** * Types the risk score as: * - Natural Number (positive integer and not a float), * - Between the values [0 and 100] inclusive. */ -export const RiskScore: RiskScoreC = new t.Type( +export const RiskScore = new t.Type( 'RiskScore', t.number.is, (input, context): Either => { @@ -24,3 +22,5 @@ export const RiskScore: RiskScoreC = new t.Type( }, t.identity ); + +export type RiskScoreC = typeof RiskScore; diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/types/uuid.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/uuid.test.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/schemas/types/uuid.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/types/uuid.test.ts diff --git a/x-pack/plugins/siem/common/detection_engine/schemas/types/uuid.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/uuid.ts similarity index 86% rename from x-pack/plugins/siem/common/detection_engine/schemas/types/uuid.ts rename to x-pack/plugins/security_solution/common/detection_engine/schemas/types/uuid.ts index 88e9db5964198..3676aa5686cd6 100644 --- a/x-pack/plugins/siem/common/detection_engine/schemas/types/uuid.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/uuid.ts @@ -7,8 +7,6 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -export type UUIDC = t.Type; - const regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; /** @@ -16,7 +14,7 @@ const regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; * - Natural Number (positive integer and not a float), * - Between the values [0 and 100] inclusive. */ -export const UUID: UUIDC = new t.Type( +export const UUID = new t.Type( 'UUID', t.string.is, (input, context): Either => { @@ -26,3 +24,5 @@ export const UUID: UUIDC = new t.Type( }, t.identity ); + +export type UUIDC = typeof UUID; diff --git a/x-pack/plugins/siem/common/detection_engine/transform_actions.test.ts b/x-pack/plugins/security_solution/common/detection_engine/transform_actions.test.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/transform_actions.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/transform_actions.test.ts diff --git a/x-pack/plugins/siem/common/detection_engine/transform_actions.ts b/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/transform_actions.ts rename to x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts diff --git a/x-pack/plugins/siem/common/detection_engine/types.ts b/x-pack/plugins/security_solution/common/detection_engine/types.ts similarity index 100% rename from x-pack/plugins/siem/common/detection_engine/types.ts rename to x-pack/plugins/security_solution/common/detection_engine/types.ts diff --git a/x-pack/plugins/siem/common/endpoint/generate_data.test.ts b/x-pack/plugins/security_solution/common/endpoint/generate_data.test.ts similarity index 89% rename from x-pack/plugins/siem/common/endpoint/generate_data.test.ts rename to x-pack/plugins/security_solution/common/endpoint/generate_data.test.ts index 3fcb00d879583..6c8c5e3f51808 100644 --- a/x-pack/plugins/siem/common/endpoint/generate_data.test.ts +++ b/x-pack/plugins/security_solution/common/endpoint/generate_data.test.ts @@ -3,7 +3,14 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { EndpointDocGenerator, Event, Tree, TreeNode } from './generate_data'; +import { + EndpointDocGenerator, + Event, + Tree, + TreeNode, + RelatedEventCategory, + ECSCategory, +} from './generate_data'; interface Node { events: Event[]; @@ -106,7 +113,11 @@ describe('data generator', () => { generations, percentTerminated: 100, percentWithRelated: 100, - relatedEvents: 4, + relatedEvents: [ + { category: RelatedEventCategory.Driver, count: 1 }, + { category: RelatedEventCategory.File, count: 2 }, + { category: RelatedEventCategory.Network, count: 1 }, + ], }); }); @@ -117,6 +128,36 @@ describe('data generator', () => { return (inRelated || inLifecycle) && event.process.entity_id === node.id; }; + it('has the right related events for each node', () => { + const checkRelatedEvents = (node: TreeNode) => { + expect(node.relatedEvents.length).toEqual(4); + + const counts: Record = {}; + for (const event of node.relatedEvents) { + if (Array.isArray(event.event.category)) { + for (const cat of event.event.category) { + counts[cat] = counts[cat] + 1 || 1; + } + } else { + counts[event.event.category] = counts[event.event.category] + 1 || 1; + } + } + expect(counts[ECSCategory.Driver]).toEqual(1); + expect(counts[ECSCategory.File]).toEqual(2); + expect(counts[ECSCategory.Network]).toEqual(1); + }; + + for (const node of tree.ancestry.values()) { + checkRelatedEvents(node); + } + + for (const node of tree.children.values()) { + checkRelatedEvents(node); + } + + checkRelatedEvents(tree.origin); + }); + it('has the right number of ancestors', () => { expect(tree.ancestry.size).toEqual(ancestors); }); diff --git a/x-pack/plugins/siem/common/endpoint/generate_data.ts b/x-pack/plugins/security_solution/common/endpoint/generate_data.ts similarity index 86% rename from x-pack/plugins/siem/common/endpoint/generate_data.ts rename to x-pack/plugins/security_solution/common/endpoint/generate_data.ts index 57d41b6554907..b17a5aa28ac6a 100644 --- a/x-pack/plugins/siem/common/endpoint/generate_data.ts +++ b/x-pack/plugins/security_solution/common/endpoint/generate_data.ts @@ -24,7 +24,7 @@ interface EventOptions { entityID?: string; parentEntityID?: string; eventType?: string; - eventCategory?: string; + eventCategory?: string | string[]; processName?: string; } @@ -75,21 +75,98 @@ const POLICIES: Array<{ name: string; id: string }> = [ const FILE_OPERATIONS: string[] = ['creation', 'open', 'rename', 'execution', 'deletion']; interface EventInfo { - category: string; + category: string | string[]; /** * This denotes the `event.type` field for when an event is created, this can be `start` or `creation` */ creationType: string; } +/** + * The valid ecs categories. + */ +export enum ECSCategory { + Driver = 'driver', + File = 'file', + Network = 'network', + /** + * Registry has not been added to ecs yet. + */ + Registry = 'registry', + Authentication = 'authentication', + Session = 'session', +} + +/** + * High level categories for related events. These specify the type of related events that should be generated. + */ +export enum RelatedEventCategory { + /** + * The Random category allows the related event categories to be chosen randomly + */ + Random = 'random', + Driver = 'driver', + File = 'file', + Network = 'network', + Registry = 'registry', + /** + * Security isn't an actual category but defines a type of related event to be created. + */ + Security = 'security', +} + +/** + * This map defines the relationship between a higher level event type defined by the RelatedEventCategory enums and + * the ECS categories that is should map to. This should only be used for tests that need to determine the exact + * ecs categories that were created based on the related event information passed to the generator. + */ +export const categoryMapping: Record = { + [RelatedEventCategory.Security]: [ECSCategory.Authentication, ECSCategory.Session], + [RelatedEventCategory.Driver]: ECSCategory.Driver, + [RelatedEventCategory.File]: ECSCategory.File, + [RelatedEventCategory.Network]: ECSCategory.Network, + [RelatedEventCategory.Registry]: ECSCategory.Registry, + /** + * Random is only used by the generator to indicate that it should randomly choose the event information when generating + * related events. It does not map to a specific ecs category. + */ + [RelatedEventCategory.Random]: '', +}; + +/** + * The related event category and number of events that should be generated. + */ +export interface RelatedEventInfo { + category: RelatedEventCategory; + count: number; +} + // These are from the v1 schemas and aren't all valid ECS event categories, still in flux -const OTHER_EVENT_CATEGORIES: EventInfo[] = [ - { category: 'driver', creationType: 'start' }, - { category: 'file', creationType: 'creation' }, - { category: 'library', creationType: 'start' }, - { category: 'network', creationType: 'start' }, - { category: 'registry', creationType: 'creation' }, -]; +const OTHER_EVENT_CATEGORIES: Record< + Exclude, + EventInfo +> = { + [RelatedEventCategory.Security]: { + category: categoryMapping[RelatedEventCategory.Security], + creationType: 'start', + }, + [RelatedEventCategory.Driver]: { + category: categoryMapping[RelatedEventCategory.Driver], + creationType: 'start', + }, + [RelatedEventCategory.File]: { + category: categoryMapping[RelatedEventCategory.File], + creationType: 'creation', + }, + [RelatedEventCategory.Network]: { + category: categoryMapping[RelatedEventCategory.Network], + creationType: 'start', + }, + [RelatedEventCategory.Registry]: { + category: categoryMapping[RelatedEventCategory.Registry], + creationType: 'creation', + }, +}; interface HostInfo { elastic: { @@ -164,7 +241,7 @@ export interface TreeOptions { ancestors?: number; generations?: number; children?: number; - relatedEvents?: number; + relatedEvents?: RelatedEventInfo[]; percentWithRelated?: number; percentTerminated?: number; alwaysGenMaxChildrenPerNode?: boolean; @@ -487,7 +564,8 @@ export class EndpointDocGenerator { * @param alertAncestors - number of ancestor generations to create relative to the alert * @param childGenerations - number of child generations to create relative to the alert * @param maxChildrenPerNode - maximum number of children for any given node in the tree - * @param relatedEventsPerNode - number of related events (file, registry, etc) to create for each process event in the tree + * @param relatedEventsPerNode - can be an array of RelatedEventInfo objects describing the related events that should be generated for each process node + * or a number which defines the number of related events and will default to random categories * @param percentNodesWithRelated - percent of nodes which should have related events * @param percentTerminated - percent of nodes which will have process termination events * @param alwaysGenMaxChildrenPerNode - flag to always return the max children per node instead of it being a random number of children @@ -496,7 +574,7 @@ export class EndpointDocGenerator { alertAncestors?: number, childGenerations?: number, maxChildrenPerNode?: number, - relatedEventsPerNode?: number, + relatedEventsPerNode?: RelatedEventInfo[] | number, percentNodesWithRelated?: number, percentTerminated?: number, alwaysGenMaxChildrenPerNode?: boolean @@ -525,13 +603,14 @@ export class EndpointDocGenerator { /** * Creates an alert event and associated process ancestry. The alert event will always be the last event in the return array. * @param alertAncestors - number of ancestor generations to create - * @param relatedEventsPerNode - number of related events to add to each process node being created + * @param relatedEventsPerNode - can be an array of RelatedEventInfo objects describing the related events that should be generated for each process node + * or a number which defines the number of related events and will default to random categories * @param pctWithRelated - percent of ancestors that will have related events * @param pctWithTerminated - percent of ancestors that will have termination events */ public createAlertEventAncestry( alertAncestors = 3, - relatedEventsPerNode = 5, + relatedEventsPerNode: RelatedEventInfo[] | number = 5, pctWithRelated = 30, pctWithTerminated = 100 ): Event[] { @@ -611,7 +690,8 @@ export class EndpointDocGenerator { * @param root - The process event to use as the root node of the tree * @param generations - number of child generations to create. The root node is not counted as a generation. * @param maxChildrenPerNode - maximum number of children for any given node in the tree - * @param relatedEventsPerNode - number of related events (file, registry, etc) to create for each process event in the tree + * @param relatedEventsPerNode - can be an array of RelatedEventInfo objects describing the related events that should be generated for each process node + * or a number which defines the number of related events and will default to random categories * @param percentNodesWithRelated - percent of nodes which should have related events * @param percentChildrenTerminated - percent of nodes which will have process termination events * @param alwaysGenMaxChildrenPerNode - flag to always return the max children per node instead of it being a random number of children @@ -620,7 +700,7 @@ export class EndpointDocGenerator { root: Event, generations = 2, maxChildrenPerNode = 2, - relatedEventsPerNode = 3, + relatedEventsPerNode: RelatedEventInfo[] | number = 3, percentNodesWithRelated = 100, percentChildrenTerminated = 100, alwaysGenMaxChildrenPerNode = false @@ -686,25 +766,40 @@ export class EndpointDocGenerator { /** * Creates related events for a process event * @param node - process event to relate events to by entityID - * @param numRelatedEvents - number of related events to generate + * @param relatedEvents - can be an array of RelatedEventInfo objects describing the related events that should be generated for each process node + * or a number which defines the number of related events and will default to random categories * @param processDuration - maximum number of seconds after process event that related event timestamp can be */ public *relatedEventsGenerator( node: Event, - numRelatedEvents = 10, + relatedEvents: RelatedEventInfo[] | number = 10, processDuration: number = 6 * 3600 ) { - for (let i = 0; i < numRelatedEvents; i++) { - const eventInfo = this.randomChoice(OTHER_EVENT_CATEGORIES); - - const ts = node['@timestamp'] + this.randomN(processDuration) * 1000; - yield this.generateEvent({ - timestamp: ts, - entityID: node.process.entity_id, - parentEntityID: node.process.parent?.entity_id, - eventCategory: eventInfo.category, - eventType: eventInfo.creationType, - }); + let relatedEventsInfo: RelatedEventInfo[]; + if (typeof relatedEvents === 'number') { + relatedEventsInfo = [{ category: RelatedEventCategory.Random, count: relatedEvents }]; + } else { + relatedEventsInfo = relatedEvents; + } + for (const event of relatedEventsInfo) { + let eventInfo: EventInfo; + + for (let i = 0; i < event.count; i++) { + if (event.category === RelatedEventCategory.Random) { + eventInfo = this.randomChoice(Object.values(OTHER_EVENT_CATEGORIES)); + } else { + eventInfo = OTHER_EVENT_CATEGORIES[event.category]; + } + + const ts = node['@timestamp'] + this.randomN(processDuration) * 1000; + yield this.generateEvent({ + timestamp: ts, + entityID: node.process.entity_id, + parentEntityID: node.process.parent?.entity_id, + eventCategory: eventInfo.category, + eventType: eventInfo.creationType, + }); + } } } @@ -834,7 +929,7 @@ export class EndpointDocGenerator { status: HostPolicyResponseActionStatus.success, }, { - name: 'load_malware_mode', + name: 'load_malware_model', message: 'Error deserializing EXE model; no valid malware model installed', status: HostPolicyResponseActionStatus.success, }, diff --git a/x-pack/plugins/siem/common/endpoint/models/event.ts b/x-pack/plugins/security_solution/common/endpoint/models/event.ts similarity index 100% rename from x-pack/plugins/siem/common/endpoint/models/event.ts rename to x-pack/plugins/security_solution/common/endpoint/models/event.ts diff --git a/x-pack/plugins/siem/common/endpoint/models/policy_config.ts b/x-pack/plugins/security_solution/common/endpoint/models/policy_config.ts similarity index 100% rename from x-pack/plugins/siem/common/endpoint/models/policy_config.ts rename to x-pack/plugins/security_solution/common/endpoint/models/policy_config.ts diff --git a/x-pack/plugins/siem/common/endpoint/schema/policy.ts b/x-pack/plugins/security_solution/common/endpoint/schema/policy.ts similarity index 100% rename from x-pack/plugins/siem/common/endpoint/schema/policy.ts rename to x-pack/plugins/security_solution/common/endpoint/schema/policy.ts diff --git a/x-pack/plugins/siem/common/endpoint/schema/resolver.ts b/x-pack/plugins/security_solution/common/endpoint/schema/resolver.ts similarity index 100% rename from x-pack/plugins/siem/common/endpoint/schema/resolver.ts rename to x-pack/plugins/security_solution/common/endpoint/schema/resolver.ts diff --git a/x-pack/plugins/security_solution/common/endpoint/types.ts b/x-pack/plugins/security_solution/common/endpoint/types.ts new file mode 100644 index 0000000000000..816f9b77115ec --- /dev/null +++ b/x-pack/plugins/security_solution/common/endpoint/types.ts @@ -0,0 +1,733 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Datasource, NewDatasource } from '../../../ingest_manager/common'; + +/** + * Object that allows you to maintain stateful information in the location object across navigation events + * + */ + +export interface AppLocation { + pathname: string; + search: string; + hash: string; + key?: string; + state?: { + isTabChange?: boolean; + }; +} + +/** + * A deep readonly type that will make all children of a given object readonly recursively + */ +export type Immutable = T extends undefined | null | boolean | string | number + ? T + : unknown extends T + ? unknown + : T extends Array + ? ImmutableArray + : T extends Map + ? ImmutableMap + : T extends Set + ? ImmutableSet + : ImmutableObject; + +export type ImmutableArray = ReadonlyArray>; +type ImmutableMap = ReadonlyMap, Immutable>; +type ImmutableSet = ReadonlySet>; +type ImmutableObject = { readonly [K in keyof T]: Immutable }; + +export interface EventStats { + /** + * The total number of related events (all events except process and alerts) that exist for a node. + */ + total: number; + /** + * A mapping of ECS event.category to the number of related events are marked with that category + * For example: + * { + * network: 5, + * file: 2 + * } + */ + byCategory: Record; +} + +/** + * Statistical information for a node in a resolver tree. + */ +export interface ResolverNodeStats { + /** + * The stats for related events (excludes alerts and process events) for a particular node in the resolver tree. + */ + events: EventStats; + /** + * The total number of alerts that exist for a node. + */ + totalAlerts: number; +} + +/** + * A child node can also have additional children so we need to provide a pagination cursor. + */ +export interface ChildNode extends LifecycleNode { + /** + * A child node's pagination cursor can be null for a couple reasons: + * 1. At the time of querying it could have no children in ES, in which case it will be marked as + * null because we know it does not have children during this query. + * 2. If the max level was reached we do not know if this node has children or not so we'll mark it as null + */ + nextChild: string | null; +} + +/** + * The response structure for the children route. The structure is an array of nodes where each node + * has an array of lifecycle events. + */ +export interface ResolverChildren { + childNodes: ChildNode[]; + /** + * This is the children cursor for the origin of a tree. + */ + nextChild: string | null; +} + +/** + * A flattened tree representing the nodes in a resolver graph. + */ +export interface ResolverTree { + /** + * Origin of the tree. This is in the middle of the tree. Typically this would be the same + * process node that generated an alert. + */ + entityID: string; + children: ResolverChildren; + relatedEvents: Omit; + ancestry: ResolverAncestry; + lifecycle: ResolverEvent[]; + stats: ResolverNodeStats; +} + +/** + * The lifecycle events (start, end etc) for a node. + */ +export interface LifecycleNode { + entityID: string; + lifecycle: ResolverEvent[]; + /** + * stats are only set when the entire tree is being fetched + */ + stats?: ResolverNodeStats; +} + +/** + * The response structure when searching for ancestors of a node. + */ +export interface ResolverAncestry { + /** + * An array of ancestors with the lifecycle events grouped together + */ + ancestors: LifecycleNode[]; + /** + * A cursor for retrieving additional ancestors for a particular node. `null` indicates that there were no additional + * ancestors when the request returned. More could have been ingested by ES after the fact though. + */ + nextAncestor: string | null; +} + +/** + * Response structure for the related events route. + */ +export interface ResolverRelatedEvents { + entityID: string; + events: ResolverEvent[]; + nextEvent: string | null; +} + +/** + * Returned by the server via /api/endpoint/metadata + */ +export interface HostResultList { + /* the hosts restricted by the page size */ + hosts: HostInfo[]; + /* the total number of unique hosts in the index */ + total: number; + /* the page size requested */ + request_page_size: number; + /* the page index requested */ + request_page_index: number; +} + +/** + * Operating System metadata for a host. + */ +export interface HostOS { + full: string; + name: string; + version: string; + variant: string; +} + +/** + * Host metadata. Describes an endpoint host. + */ +export interface Host { + id: string; + hostname: string; + ip: string[]; + mac: string[]; + os: HostOS; +} + +/** + * A record of hashes for something. Provides hashes in multiple formats. A favorite structure of the Elastic Endpoint. + */ +interface Hashes { + /** + * A hash in MD5 format. + */ + md5: string; + /** + * A hash in SHA-1 format. + */ + sha1: string; + /** + * A hash in SHA-256 format. + */ + sha256: string; +} + +interface MalwareClassification { + identifier: string; + score: number; + threshold: number; + version: string; +} + +interface ThreadFields { + id: number; + service_name: string; + start: number; + start_address: number; + start_address_module: string; +} + +interface DllFields { + pe: { + architecture: string; + imphash: string; + }; + code_signature: { + subject_name: string; + trusted: boolean; + }; + compile_time: number; + hash: Hashes; + malware_classification: MalwareClassification; + mapped_address: number; + mapped_size: number; + path: string; +} + +/** + * Describes an Alert Event. + */ +export type AlertEvent = Immutable<{ + '@timestamp': number; + agent: { + id: string; + version: string; + }; + event: { + id: string; + action: string; + category: string; + kind: string; + dataset: string; + module: string; + type: string; + }; + endpoint: { + policy: { + id: string; + }; + }; + process: { + code_signature: { + subject_name: string; + trusted: boolean; + }; + command_line?: string; + domain?: string; + pid: number; + ppid?: number; + entity_id: string; + parent?: { + pid: number; + entity_id: string; + }; + name: string; + hash: Hashes; + pe?: { + imphash: string; + }; + executable: string; + sid?: string; + start: number; + malware_classification?: MalwareClassification; + token: { + domain: string; + type: string; + user: string; + sid: string; + integrity_level: number; + integrity_level_name: string; + privileges?: Array<{ + description: string; + name: string; + enabled: boolean; + }>; + }; + thread?: ThreadFields[]; + uptime: number; + user: string; + }; + file: { + owner: string; + name: string; + path: string; + accessed: number; + mtime: number; + created: number; + size: number; + hash: Hashes; + pe?: { + imphash: string; + }; + code_signature: { + trusted: boolean; + subject_name: string; + }; + malware_classification: MalwareClassification; + temp_file_path: string; + }; + host: Host; + dll?: DllFields[]; +}>; + +/** + * The status of the host + */ +export enum HostStatus { + /** + * Default state of the host when no host information is present or host information cannot + * be retrieved. e.g. API error + */ + ERROR = 'error', + + /** + * Host is online as indicated by its checkin status during the last checkin window + */ + ONLINE = 'online', + + /** + * Host is offline as indicated by its checkin status during the last checkin window + */ + OFFLINE = 'offline', +} + +export type HostInfo = Immutable<{ + metadata: HostMetadata; + host_status: HostStatus; +}>; + +export type HostMetadata = Immutable<{ + '@timestamp': number; + event: { + created: number; + }; + elastic: { + agent: { + id: string; + }; + }; + endpoint: { + policy: { + id: string; + }; + }; + agent: { + id: string; + version: string; + }; + host: Host; +}>; + +export interface LegacyEndpointEvent { + '@timestamp': number; + endgame: { + pid?: number; + ppid?: number; + event_type_full?: string; + event_subtype_full?: string; + event_timestamp?: number; + event_type?: number; + unique_pid: number; + unique_ppid?: number; + machine_id?: string; + process_name?: string; + process_path?: string; + timestamp_utc?: string; + serial_event_id?: number; + }; + agent: { + id: string; + type: string; + version: string; + }; + process?: object; + rule?: object; + user?: object; + event?: { + action?: string; + type?: string; + category?: string | string[]; + }; +} + +export interface EndpointEvent { + '@timestamp': number; + agent: { + id: string; + version: string; + type: string; + }; + ecs: { + version: string; + }; + event: { + category: string | string[]; + type: string | string[]; + id: string; + kind: string; + }; + host: { + id: string; + hostname: string; + ip: string[]; + mac: string[]; + os: HostOS; + }; + process: { + entity_id: string; + name: string; + parent?: { + entity_id: string; + name?: string; + }; + }; +} + +export type ResolverEvent = EndpointEvent | LegacyEndpointEvent; + +/** + * Takes a @kbn/config-schema 'schema' type and returns a type that represents valid inputs. + * Similar to `TypeOf`, but allows strings as input for `schema.number()` (which is inline + * with the behavior of the validator.) Also, for `schema.object`, when a value is a `schema.maybe` + * the key will be marked optional (via `?`) so that you can omit keys for optional values. + * + * Use this when creating a value that will be passed to the schema. + * e.g. + * ```ts + * const input: KbnConfigSchemaInputTypeOf = value + * schema.validate(input) // should be valid + * ``` + * Note that because the types coming from `@kbn/config-schema`'s schemas sometimes have deeply nested + * `Type` types, we process the result of `TypeOf` instead, as this will be consistent. + */ +export type KbnConfigSchemaInputTypeOf = T extends Record + ? KbnConfigSchemaInputObjectTypeOf< + T + > /** `schema.number()` accepts strings, so this type should accept them as well. */ + : number extends T + ? T | string + : T; + +/** + * Works like ObjectResultType, except that 'maybe' schema will create an optional key. + * This allows us to avoid passing 'maybeKey: undefined' when constructing such an object. + * + * Instead of using this directly, use `InputTypeOf`. + */ +type KbnConfigSchemaInputObjectTypeOf

> = { + /** Use ? to make the field optional if the prop accepts undefined. + * This allows us to avoid writing `field: undefined` for optional fields. + */ + [K in Exclude>]?: KbnConfigSchemaInputTypeOf< + P[K] + >; +} & + { [K in keyof KbnConfigSchemaNonOptionalProps

]: KbnConfigSchemaInputTypeOf }; + +/** + * Takes the props of a schema.object type, and returns a version that excludes + * optional values. Used by `InputObjectTypeOf`. + * + * Instead of using this directly, use `InputTypeOf`. + */ +type KbnConfigSchemaNonOptionalProps> = Pick< + Props, + { + [Key in keyof Props]: undefined extends Props[Key] + ? never + : null extends Props[Key] + ? never + : Key; + }[keyof Props] +>; + +/** + * Endpoint Policy configuration + */ +export interface PolicyConfig { + windows: { + events: { + dll_and_driver_load: boolean; + dns: boolean; + file: boolean; + network: boolean; + process: boolean; + registry: boolean; + security: boolean; + }; + malware: MalwareFields; + logging: { + stdout: string; + file: string; + }; + advanced: PolicyConfigAdvancedOptions; + }; + mac: { + events: { + file: boolean; + process: boolean; + network: boolean; + }; + malware: MalwareFields; + logging: { + stdout: string; + file: string; + }; + advanced: PolicyConfigAdvancedOptions; + }; + linux: { + events: { + file: boolean; + process: boolean; + network: boolean; + }; + logging: { + stdout: string; + file: string; + }; + advanced: PolicyConfigAdvancedOptions; + }; +} + +/** + * The set of Policy configuration settings that are show/edited via the UI + */ +export interface UIPolicyConfig { + /** + * Windows-specific policy configuration that is supported via the UI + */ + windows: Pick; + /** + * Mac-specific policy configuration that is supported via the UI + */ + mac: Pick; + /** + * Linux-specific policy configuration that is supported via the UI + */ + linux: Pick; +} + +interface PolicyConfigAdvancedOptions { + elasticsearch: { + indices: { + control: string; + event: string; + logging: string; + }; + kernel: { + connect: boolean; + process: boolean; + }; + }; +} + +/** Policy: Malware protection fields */ +export interface MalwareFields { + mode: ProtectionModes; +} + +/** Policy protection mode options */ +export enum ProtectionModes { + detect = 'detect', + prevent = 'prevent', + preventNotify = 'preventNotify', + off = 'off', +} + +/** + * Endpoint Policy data, which extends Ingest's `Datasource` type + */ +export type PolicyData = Datasource & NewPolicyData; + +/** + * New policy data. Used when updating the policy record via ingest APIs + */ +export type NewPolicyData = NewDatasource & { + inputs: [ + { + type: 'endpoint'; + enabled: boolean; + streams: []; + config: { + policy: { + value: PolicyConfig; + }; + }; + } + ]; +}; + +/** + * the possible status for actions, configurations and overall Policy Response + */ +export enum HostPolicyResponseActionStatus { + success = 'success', + failure = 'failure', + warning = 'warning', +} + +/** + * The name of actions that can be applied during the processing of a policy + */ +type HostPolicyActionName = + | 'download_model' + | 'ingest_events_config' + | 'workflow' + | 'configure_elasticsearch_connection' + | 'configure_kernel' + | 'configure_logging' + | 'configure_malware' + | 'connect_kernel' + | 'detect_file_open_events' + | 'detect_file_write_events' + | 'detect_image_load_events' + | 'detect_process_events' + | 'download_global_artifacts' + | 'load_config' + | 'load_malware_model' + | 'read_elasticsearch_config' + | 'read_events_config' + | 'read_kernel_config' + | 'read_logging_config' + | 'read_malware_config' + | string; + +/** + * Host Policy Response Applied Action + */ +export interface HostPolicyResponseAppliedAction { + name: HostPolicyActionName; + status: HostPolicyResponseActionStatus; + message: string; +} + +export type HostPolicyResponseConfiguration = HostPolicyResponse['endpoint']['policy']['applied']['response']['configurations']; + +interface HostPolicyResponseConfigurationStatus { + status: HostPolicyResponseActionStatus; + concerned_actions: HostPolicyActionName[]; +} + +/** + * Host Policy Response Applied Artifact + */ +interface HostPolicyResponseAppliedArtifact { + name: string; + sha256: string; +} + +/** + * Information about the applying of a policy to a given host + */ +export interface HostPolicyResponse { + '@timestamp': number; + elastic: { + agent: { + id: string; + }; + }; + ecs: { + version: string; + }; + host: { + id: string; + }; + event: { + created: number; + kind: string; + id: string; + category: string; + type: string; + module: string; + action: string; + dataset: string; + }; + agent: { + version: string; + id: string; + }; + endpoint: { + policy: { + applied: { + version: string; + id: string; + status: HostPolicyResponseActionStatus; + actions: HostPolicyResponseAppliedAction[]; + response: { + configurations: { + malware: HostPolicyResponseConfigurationStatus; + events: HostPolicyResponseConfigurationStatus; + logging: HostPolicyResponseConfigurationStatus; + streaming: HostPolicyResponseConfigurationStatus; + }; + }; + artifacts: { + global: { + version: string; + identifiers: HostPolicyResponseAppliedArtifact[]; + }; + user: { + version: string; + identifiers: HostPolicyResponseAppliedArtifact[]; + }; + }; + }; + }; + }; +} + +/** + * REST API response for retrieving a host's Policy Response status + */ +export interface GetHostPolicyResponse { + policy_response: HostPolicyResponse; +} diff --git a/x-pack/plugins/siem/common/endpoint_alerts/alert_constants.ts b/x-pack/plugins/security_solution/common/endpoint_alerts/alert_constants.ts similarity index 100% rename from x-pack/plugins/siem/common/endpoint_alerts/alert_constants.ts rename to x-pack/plugins/security_solution/common/endpoint_alerts/alert_constants.ts diff --git a/x-pack/plugins/siem/common/endpoint_alerts/schema/alert_index.ts b/x-pack/plugins/security_solution/common/endpoint_alerts/schema/alert_index.ts similarity index 84% rename from x-pack/plugins/siem/common/endpoint_alerts/schema/alert_index.ts rename to x-pack/plugins/security_solution/common/endpoint_alerts/schema/alert_index.ts index 6794eea20066b..bf57a366f341d 100644 --- a/x-pack/plugins/siem/common/endpoint_alerts/schema/alert_index.ts +++ b/x-pack/plugins/security_solution/common/endpoint_alerts/schema/alert_index.ts @@ -47,7 +47,7 @@ export const alertingIndexGetQuerySchema = schema.object( try { decode(value); } catch (err) { - return i18n.translate('xpack.siem.endpoint.alerts.errors.bad_rison', { + return i18n.translate('xpack.securitySolution.endpoint.alerts.errors.bad_rison', { defaultMessage: 'must be a valid rison-encoded string', }); } @@ -62,7 +62,7 @@ export const alertingIndexGetQuerySchema = schema.object( try { decode(value); } catch (err) { - return i18n.translate('xpack.siem.endpoint.alerts.errors.bad_rison', { + return i18n.translate('xpack.securitySolution.endpoint.alerts.errors.bad_rison', { defaultMessage: 'must be a valid rison-encoded string', }); } @@ -77,7 +77,7 @@ export const alertingIndexGetQuerySchema = schema.object( try { decode(value); } catch (err) { - return i18n.translate('xpack.siem.endpoint.alerts.errors.bad_rison', { + return i18n.translate('xpack.securitySolution.endpoint.alerts.errors.bad_rison', { defaultMessage: 'must be a valid rison-encoded string', }); } @@ -89,7 +89,7 @@ export const alertingIndexGetQuerySchema = schema.object( validate(value) { if (value.after !== undefined && value.page_index !== undefined) { return i18n.translate( - 'xpack.siem.endpoint.alerts.errors.page_index_cannot_be_used_with_after', + 'xpack.securitySolution.endpoint.alerts.errors.page_index_cannot_be_used_with_after', { defaultMessage: '[page_index] cannot be used with [after]', } @@ -97,7 +97,7 @@ export const alertingIndexGetQuerySchema = schema.object( } if (value.before !== undefined && value.page_index !== undefined) { return i18n.translate( - 'xpack.siem.endpoint.alerts.errors.page_index_cannot_be_used_with_before', + 'xpack.securitySolution.endpoint.alerts.errors.page_index_cannot_be_used_with_before', { defaultMessage: '[page_index] cannot be used with [before]', } @@ -105,7 +105,7 @@ export const alertingIndexGetQuerySchema = schema.object( } if (value.before !== undefined && value.after !== undefined) { return i18n.translate( - 'xpack.siem.endpoint.alerts.errors.before_cannot_be_used_with_after', + 'xpack.securitySolution.endpoint.alerts.errors.before_cannot_be_used_with_after', { defaultMessage: '[before] cannot be used with [after]', } diff --git a/x-pack/plugins/siem/common/endpoint_alerts/schema/index_pattern.ts b/x-pack/plugins/security_solution/common/endpoint_alerts/schema/index_pattern.ts similarity index 100% rename from x-pack/plugins/siem/common/endpoint_alerts/schema/index_pattern.ts rename to x-pack/plugins/security_solution/common/endpoint_alerts/schema/index_pattern.ts diff --git a/x-pack/plugins/siem/common/endpoint_alerts/types.ts b/x-pack/plugins/security_solution/common/endpoint_alerts/types.ts similarity index 100% rename from x-pack/plugins/siem/common/endpoint_alerts/types.ts rename to x-pack/plugins/security_solution/common/endpoint_alerts/types.ts diff --git a/x-pack/plugins/siem/common/exact_check.test.ts b/x-pack/plugins/security_solution/common/exact_check.test.ts similarity index 89% rename from x-pack/plugins/siem/common/exact_check.test.ts rename to x-pack/plugins/security_solution/common/exact_check.test.ts index a5701603de0d6..96a1b1266ea9a 100644 --- a/x-pack/plugins/siem/common/exact_check.test.ts +++ b/x-pack/plugins/security_solution/common/exact_check.test.ts @@ -86,6 +86,23 @@ describe('exact_check', () => { expect(message.schema).toEqual({ a: 'test' }); }); + test('it will work with decoding a null payload when the schema expects a null', () => { + const someType = t.union([ + t.exact( + t.type({ + a: t.string, + }) + ), + t.null, + ]); + const payload = null; + const decoded = someType.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(null); + }); + test('it should find no differences recursively with two empty objects', () => { const difference = findDifferencesRecursive({}, {}); expect(difference).toEqual([]); @@ -151,4 +168,9 @@ describe('exact_check', () => { ); expect(difference).toEqual(['d']); }); + + test('it should not find any differences when the original and decoded are both null', () => { + const difference = findDifferencesRecursive(null, null); + expect(difference).toEqual([]); + }); }); diff --git a/x-pack/plugins/siem/common/exact_check.ts b/x-pack/plugins/security_solution/common/exact_check.ts similarity index 90% rename from x-pack/plugins/siem/common/exact_check.ts rename to x-pack/plugins/security_solution/common/exact_check.ts index 30c5b585a3480..48afc35b56ba1 100644 --- a/x-pack/plugins/siem/common/exact_check.ts +++ b/x-pack/plugins/security_solution/common/exact_check.ts @@ -25,7 +25,10 @@ import { isObject, get } from 'lodash/fp'; * @param decoded The decoded either which has either an existing error or the * decoded object which could have additional keys stripped from it. */ -export const exactCheck = (original: T, decoded: Either): Either => { +export const exactCheck = ( + original: unknown, + decoded: Either +): Either => { const onLeft = (errors: t.Errors): Either => left(errors); const onRight = (decodedValue: T): Either => { const differences = findDifferencesRecursive(original, decodedValue); @@ -45,7 +48,11 @@ export const exactCheck = (original: T, decoded: Either): Either }; export const findDifferencesRecursive = (original: T, decodedValue: T): string[] => { - if (decodedValue == null) { + if (decodedValue === null && original === null) { + // both the decodedValue and the original are null which indicates that they are equal + // so do not report differences + return []; + } else if (decodedValue == null) { try { // It is null and painful when the original contains an object or an array // the the decoded value does not have. diff --git a/x-pack/plugins/siem/common/format_errors.test.ts b/x-pack/plugins/security_solution/common/format_errors.test.ts similarity index 100% rename from x-pack/plugins/siem/common/format_errors.test.ts rename to x-pack/plugins/security_solution/common/format_errors.test.ts diff --git a/x-pack/plugins/siem/common/format_errors.ts b/x-pack/plugins/security_solution/common/format_errors.ts similarity index 100% rename from x-pack/plugins/siem/common/format_errors.ts rename to x-pack/plugins/security_solution/common/format_errors.ts diff --git a/x-pack/plugins/siem/common/graphql/root/index.ts b/x-pack/plugins/security_solution/common/graphql/root/index.ts similarity index 100% rename from x-pack/plugins/siem/common/graphql/root/index.ts rename to x-pack/plugins/security_solution/common/graphql/root/index.ts diff --git a/x-pack/plugins/siem/common/graphql/root/schema.gql.ts b/x-pack/plugins/security_solution/common/graphql/root/schema.gql.ts similarity index 100% rename from x-pack/plugins/siem/common/graphql/root/schema.gql.ts rename to x-pack/plugins/security_solution/common/graphql/root/schema.gql.ts diff --git a/x-pack/plugins/siem/common/graphql/shared/index.ts b/x-pack/plugins/security_solution/common/graphql/shared/index.ts similarity index 100% rename from x-pack/plugins/siem/common/graphql/shared/index.ts rename to x-pack/plugins/security_solution/common/graphql/shared/index.ts diff --git a/x-pack/plugins/siem/common/graphql/shared/schema.gql.ts b/x-pack/plugins/security_solution/common/graphql/shared/schema.gql.ts similarity index 100% rename from x-pack/plugins/siem/common/graphql/shared/schema.gql.ts rename to x-pack/plugins/security_solution/common/graphql/shared/schema.gql.ts diff --git a/x-pack/plugins/siem/common/machine_learning/empty_ml_capabilities.ts b/x-pack/plugins/security_solution/common/machine_learning/empty_ml_capabilities.ts similarity index 100% rename from x-pack/plugins/siem/common/machine_learning/empty_ml_capabilities.ts rename to x-pack/plugins/security_solution/common/machine_learning/empty_ml_capabilities.ts diff --git a/x-pack/plugins/siem/common/machine_learning/has_ml_admin_permissions.test.ts b/x-pack/plugins/security_solution/common/machine_learning/has_ml_admin_permissions.test.ts similarity index 100% rename from x-pack/plugins/siem/common/machine_learning/has_ml_admin_permissions.test.ts rename to x-pack/plugins/security_solution/common/machine_learning/has_ml_admin_permissions.test.ts diff --git a/x-pack/plugins/siem/common/machine_learning/has_ml_admin_permissions.ts b/x-pack/plugins/security_solution/common/machine_learning/has_ml_admin_permissions.ts similarity index 100% rename from x-pack/plugins/siem/common/machine_learning/has_ml_admin_permissions.ts rename to x-pack/plugins/security_solution/common/machine_learning/has_ml_admin_permissions.ts diff --git a/x-pack/plugins/siem/common/machine_learning/has_ml_user_permissions.test.ts b/x-pack/plugins/security_solution/common/machine_learning/has_ml_user_permissions.test.ts similarity index 100% rename from x-pack/plugins/siem/common/machine_learning/has_ml_user_permissions.test.ts rename to x-pack/plugins/security_solution/common/machine_learning/has_ml_user_permissions.test.ts diff --git a/x-pack/plugins/siem/common/machine_learning/has_ml_user_permissions.ts b/x-pack/plugins/security_solution/common/machine_learning/has_ml_user_permissions.ts similarity index 100% rename from x-pack/plugins/siem/common/machine_learning/has_ml_user_permissions.ts rename to x-pack/plugins/security_solution/common/machine_learning/has_ml_user_permissions.ts diff --git a/x-pack/plugins/siem/common/machine_learning/helpers.test.ts b/x-pack/plugins/security_solution/common/machine_learning/helpers.test.ts similarity index 100% rename from x-pack/plugins/siem/common/machine_learning/helpers.test.ts rename to x-pack/plugins/security_solution/common/machine_learning/helpers.test.ts diff --git a/x-pack/plugins/siem/common/machine_learning/helpers.ts b/x-pack/plugins/security_solution/common/machine_learning/helpers.ts similarity index 100% rename from x-pack/plugins/siem/common/machine_learning/helpers.ts rename to x-pack/plugins/security_solution/common/machine_learning/helpers.ts diff --git a/x-pack/plugins/siem/common/test_utils.ts b/x-pack/plugins/security_solution/common/test_utils.ts similarity index 100% rename from x-pack/plugins/siem/common/test_utils.ts rename to x-pack/plugins/security_solution/common/test_utils.ts diff --git a/x-pack/plugins/siem/common/typed_json.ts b/x-pack/plugins/security_solution/common/typed_json.ts similarity index 100% rename from x-pack/plugins/siem/common/typed_json.ts rename to x-pack/plugins/security_solution/common/typed_json.ts diff --git a/x-pack/plugins/siem/common/types/timeline/index.ts b/x-pack/plugins/security_solution/common/types/timeline/index.ts similarity index 100% rename from x-pack/plugins/siem/common/types/timeline/index.ts rename to x-pack/plugins/security_solution/common/types/timeline/index.ts diff --git a/x-pack/plugins/siem/common/types/timeline/note/index.ts b/x-pack/plugins/security_solution/common/types/timeline/note/index.ts similarity index 100% rename from x-pack/plugins/siem/common/types/timeline/note/index.ts rename to x-pack/plugins/security_solution/common/types/timeline/note/index.ts diff --git a/x-pack/plugins/siem/common/types/timeline/pinned_event/index.ts b/x-pack/plugins/security_solution/common/types/timeline/pinned_event/index.ts similarity index 100% rename from x-pack/plugins/siem/common/types/timeline/pinned_event/index.ts rename to x-pack/plugins/security_solution/common/types/timeline/pinned_event/index.ts diff --git a/x-pack/plugins/siem/common/utility_types.ts b/x-pack/plugins/security_solution/common/utility_types.ts similarity index 100% rename from x-pack/plugins/siem/common/utility_types.ts rename to x-pack/plugins/security_solution/common/utility_types.ts diff --git a/x-pack/plugins/siem/cypress/.eslintrc.json b/x-pack/plugins/security_solution/cypress/.eslintrc.json similarity index 100% rename from x-pack/plugins/siem/cypress/.eslintrc.json rename to x-pack/plugins/security_solution/cypress/.eslintrc.json diff --git a/x-pack/plugins/siem/cypress/.gitignore b/x-pack/plugins/security_solution/cypress/.gitignore similarity index 100% rename from x-pack/plugins/siem/cypress/.gitignore rename to x-pack/plugins/security_solution/cypress/.gitignore diff --git a/x-pack/plugins/security_solution/cypress/README.md b/x-pack/plugins/security_solution/cypress/README.md new file mode 100644 index 0000000000000..ad3af2aaa4e8a --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/README.md @@ -0,0 +1,355 @@ +# Cypress Tests + +The `security_solution/cypress` directory contains end to end tests, (plus a few tests +that rely on mocked API calls), that execute via [Cypress](https://www.cypress.io/). + +Cypress tests may be run against: + +- A local Kibana instance, interactively or via the command line. Credentials +are specified via `kibana.dev.yml` or environment variables. +- A remote Elastic Cloud instance (override `baseUrl`), interactively or via +the command line. Again, credentials are specified via `kibana.dev.yml` or +environment variables. +- As part of CI (override `baseUrl` and pass credentials via the +`CYPRESS_ELASTICSEARCH_USERNAME` and `CYPRESS_ELASTICSEARCH_PASSWORD` +environment variables), via command line. + +At present, Cypress tests are only executed manually. They are **not** yet +integrated in the Kibana CI infrastructure, and therefore do **not** run +automatically when you submit a PR. + +## Smoke Tests + +Smoke Tests are located in `security_solution/cypress/integration/smoke_tests` + +## Structure + +### Tasks + +_Tasks_ are functions that my be re-used across tests. Inside the _tasks_ folder there are some other folders that represents +the page to which we will perform the actions. For each folder we are going to create a file for each one of the sections that + has the page. + +i.e. +- tasks + - hosts + - events.ts + +### Screens + +In _screens_ folder we are going to find all the elements we want to interact in our tests. Inside _screens_ fonder there +are some other folders that represents the page that contains the elements the tests are going to interact with. For each +folder we are going to create a file for each one of the sections that the page has. + +i.e. +- tasks + - hosts + - events.ts + +## Mock Data + +We prefer not to mock API responses in most of our smoke tests, but sometimes +it's necessary because a test must assert that a specific value is rendered, +and it's not possible to derive that value based on the data in the +environment where tests are running. + +Mocked responses API from the server are located in `security_solution/cypress/fixtures`. + +## Speeding up test execution time + +Loading the web page takes a big amount of time, in order to minimize that impact, the following points should be +taken into consideration until another solution is implemented: + +- Don't refresh the page for every test to clean the state of it. +- Instead, group the tests that are similar in different contexts. +- For every context login only once, clean the state between tests if needed without re-loading the page. +- All tests in a spec file must be order-independent. + - If you need to reload the page to make the tests order-independent, consider to create a new context. + +Remember that minimizing the number of times the web page is loaded, we minimize as well the execution time. + +## Authentication + +When running tests, there are two ways to specify the credentials used to +authenticate with Kibana: + +- Via `kibana.dev.yml` (recommended for developers) +- Via the `CYPRESS_ELASTICSEARCH_USERNAME` and `CYPRESS_ELASTICSEARCH_PASSWORD` +environment variables (recommended for CI), or when testing a remote Kibana +instance, e.g. in Elastic Cloud. + +Note: Tests that use the `login()` test helper function for authentication will +automatically use the `CYPRESS_ELASTICSEARCH_USERNAME` and `CYPRESS_ELASTICSEARCH_PASSWORD` +environment variables when they are defined, and fall back to the values in +`config/kibana.dev.yml` when they are unset. + +### Content Security Policy (CSP) Settings + +Your local or cloud Kibana server must have the `csp.strict: false` setting +configured in `kibana.dev.yml`, or `kibana.yml`, as shown in the example below: + +```yaml +csp.strict: false +``` + +The above setting is required to prevent the _Please upgrade +your browser_ / _This Kibana installation has strict security requirements +enabled that your current browser does not meet._ warning that's displayed for +unsupported user agents, like the one reported by Cypress when running tests. + +### Example `kibana.dev.yml` + +If you're a developer running tests interactively or on the command line, the +easiset way to specify the credentials used for authentication is to update + `kibana.dev.yml` per the following example: + +```yaml +csp.strict: false +elasticsearch: + username: 'elastic' + password: '' + hosts: ['https://:9200'] +``` + +## Running (Headless) Tests on the Command Line as a Jenkins execution (The preferred way) + +To run (headless) tests as a Jenkins execution. + +1. First bootstrap kibana changes from the Kibana root directory: + +```sh +yarn kbn bootstrap +``` + +2. Launch Cypress command line test runner: + +```sh +cd x-pack/plugins/security_solution +yarn cypress:run-as-ci +``` + +Note that with this type of execution you don't need to have running a kibana and elasticsearch instance. This is because + the command, as it would happen in the CI, will launch the instances. The elasticsearch instance will be fed data + found in: `x-pack/test/security_solution_cypress/es_archives` + +As in this case we want to mimic a CI execution we want to execute the tests with the same set of data, this is why +in this case does not make sense to override Cypress environment variables. + +### Test data + +As mentioned above, when running the tests as Jenkins the tests are populated with data ("archives") found in: `x-pack/test/security_solution_cypress/es_archives`. + +By default, each test is populated with some base data: an empty kibana index and a set of auditbeat data (the `empty_kibana` and `auditbeat` archives, respectively). This is usually enough to cover most of the scenarios that we are testing. + +#### Running tests with additional archives + +When the base data is insufficient, one can specify additional archives. Use `esArchiverLoad` to load the necessary archive, and `esArchiverUnload` to remove the archive from elasticsearch: + +```typescript +import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver'; + +describe('This are going to be a set of tests', () => { + before(() => { + esArchiverLoad('name_of_the_data_set_you_want_to_load'); + }); + + after(() => { + esArchiverUnload('name_of_the_data_set_you_want_to_unload'); + }); + + it('Going to test something awesome', () => { + hereGoesYourAwesomeTestcode + }); +}); + +``` + +Note that loading and unloading data take a significant amount of time, so try to minimize their use. + +### Current archives + +The current archives can be found in `x-pack/test/security_solution_cypress/es_archives/`. + +- auditbeat + - Auditbeat data generated in Sep, 2019 with the following hosts present: + - suricata-iowa + - siem-kibana + - siem-es + - jessie +- closed_alerts + - Set of data with 108 closed alerts linked to "Alerts test" custom rule. +- custome_rules + - Set if data with just 4 custom activated rules. +- empty_kibana + - Empty kibana board. +- prebuilt_rules_loaded + - Elastic prebuilt loaded rules and deactivated. +- alerts + - Set of data with 108 opened alerts linked to "Alerts test" custom rule. + +### How to generate a new archive + +We are using es_archiver in order to manage the data that our Cypress tests needs. + +1. Setup if possible a clean instance of kibana and elasticsearch (if not, possible please try to clean the data that you are going to generate). +2. With the kibana and elasticsearch instance up and running, create the data that you need for your test. +3. When you are sure that you have all the data you need run the following command from: `x-pack/plugins/security_solution` + +```sh +node ../../../scripts/es_archiver save --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url http://:@: +``` + +Example: +```sh +node ../../../scripts/es_archiver save custom_rules ".kibana",".siem-signal*" --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url http://elastic:changeme@localhost:9220 +``` + +Note that the command is going to create the folder if does not exist in the directory with the imported data. + + +## Running Tests Interactively + +Use the Cypress interactive test runner to develop and debug specific tests +by adding a `.only` to the test you're developing, or click on a specific +spec in the interactive test runner to run just the tests in that spec. + +To run and debug tests in interactively via the Cypress test runner: + +1. Disable CSP on the local or remote Kibana instance, as described in the +_Content Security Policy (CSP) Settings_ section above. + +2. To specify the credentials required for authentication, configure +`config/kibana.dev.yml`, as described in the _Server and Authentication +Requirements_ section above, or specify them via environment variables +as described later in this section. + +3. Start a local instance of the Kibana development server (only if testing against a +local host): + +```sh +yarn start --no-base-path +``` + +4. Launch the Cypress interactive test runner via one of the following options: + +- To run tests interactively against the default (local) host specified by +`baseUrl`, as configured in `plugins/security_solution/cypress.json`: + +```sh +cd x-pack/plugins/security_solution +yarn cypress:open +``` + +- To (optionally) run tests interactively against a different host, pass the +`CYPRESS_baseUrl` environment variable on the command line when launching the +test runner, as shown in the following example: + +```sh +cd x-pack/plugins/security_solution +CYPRESS_baseUrl=http://localhost:5601 yarn cypress:open +``` + +- To (optionally) override username and password via environment variables when +running tests interactively: + +```sh +cd x-pack/plugins/security_solution +CYPRESS_baseUrl=http://localhost:5601 CYPRESS_ELASTICSEARCH_USERNAME=elastic CYPRESS_ELASTICSEARCH_PASSWORD= yarn cypress:open +``` + +5. Click the `Run all specs` button in the Cypress test runner (after adding +a `.only` to an `it` or `describe` block). + +## Running (Headless) Tests on the Command Line + +To run (headless) tests on the command line: + +1. Disable CSP on the local or remote Kibana instance, as described in the +_Content Security Policy (CSP) Settings_ section above. + +2. To specify the credentials required for authentication, configure +`config/kibana.dev.yml`, as described in the _Server and Authentication +Requirements_ section above, or specify them via environment variables +as described later in this section. + +3. Start a local instance of the Kibana development server (only if testing against a +local host): + +```sh +yarn start --no-base-path +``` + +4. Launch the Cypress command line test runner via one of the following options: + +- To run tests on the command line against the default (local) host specified by +`baseUrl`, as configured in `plugins/security_solution/cypress.json`: + +```sh +cd x-pack/plugins/security_solution +yarn cypress:run +``` + +- To (optionally) run tests on the command line against a different host, pass +`CYPRESS_baseUrl` as an environment variable on the command line, as shown in +the following example: + +```sh +cd x-pack/plugins/security_solution +CYPRESS_baseUrl=http://localhost:5601 yarn cypress:run +``` + +- To (optionally) override username and password via environment variables when +running via the command line: + +```sh +cd x-pack/plugins/security_solution +CYPRESS_baseUrl=http://localhost:5601 CYPRESS_ELASTICSEARCH_USERNAME=elastic CYPRESS_ELASTICSEARCH_PASSWORD= yarn cypress:run +``` + +## Reporting + +When Cypress tests are run on the command line via `yarn cypress:run`, +reporting artifacts are generated under the `target` directory in the root +of the Kibana, as detailed for each artifact type in the sections below. + +### HTML Reports + +An HTML report (e.g. for email notifications) is output to: + +``` +target/kibana-security-solution/cypress/results/output.html +``` + +### Screenshots + +Screenshots of failed tests are output to: + +``` +target/kibana-security-solution/cypress/screenshots +``` + +### `junit` Reports + +The Kibana CI process reports `junit` test results from the `target/junit` directory. + +Cypress `junit` reports are generated in `target/kibana-security-solution/cypress/results` +and copied to the `target/junit` directory. + +### Videos (optional) + +Videos are disabled by default, but can optionally be enabled by setting the +`CYPRESS_video=true` environment variable: + +``` +CYPRESS_video=true yarn cypress:run +``` + +Videos are (optionally) output to: + +``` +target/kibana-security-solution/cypress/videos +``` + +## Linting + +Optional linting rules for Cypress and linting setup can be found [here](https://github.com/cypress-io/eslint-plugin-cypress#usage) diff --git a/x-pack/plugins/security_solution/cypress/cypress.json b/x-pack/plugins/security_solution/cypress/cypress.json new file mode 100644 index 0000000000000..b097b0432e75d --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/cypress.json @@ -0,0 +1,8 @@ +{ + "baseUrl": "http://localhost:5601", + "defaultCommandTimeout": 120000, + "screenshotsFolder": "../../../target/kibana-security-solution/cypress/screenshots", + "trashAssetsBeforeRuns": false, + "video": false, + "videosFolder": "../../../target/kibana-security-solution/cypress/videos" +} diff --git a/x-pack/plugins/siem/cypress/fixtures/overview.json b/x-pack/plugins/security_solution/cypress/fixtures/overview.json similarity index 100% rename from x-pack/plugins/siem/cypress/fixtures/overview.json rename to x-pack/plugins/security_solution/cypress/fixtures/overview.json diff --git a/x-pack/plugins/siem/cypress/integration/cases.spec.ts b/x-pack/plugins/security_solution/cypress/integration/cases.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/cases.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/cases.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/cases_connectors.spec.ts b/x-pack/plugins/security_solution/cypress/integration/cases_connectors.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/cases_connectors.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/cases_connectors.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/detections.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detections.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/detections.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/detections.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/detections_timeline.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detections_timeline.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/detections_timeline.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/detections_timeline.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/events_viewer.spec.ts b/x-pack/plugins/security_solution/cypress/integration/events_viewer.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/events_viewer.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/events_viewer.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/fields_browser.spec.ts b/x-pack/plugins/security_solution/cypress/integration/fields_browser.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/fields_browser.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/fields_browser.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/inspect.spec.ts b/x-pack/plugins/security_solution/cypress/integration/inspect.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/inspect.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/inspect.spec.ts diff --git a/x-pack/plugins/security_solution/cypress/integration/ml_conditional_links.spec.ts b/x-pack/plugins/security_solution/cypress/integration/ml_conditional_links.spec.ts new file mode 100644 index 0000000000000..e96c1fe691966 --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/integration/ml_conditional_links.spec.ts @@ -0,0 +1,203 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { KQL_INPUT } from '../screens/siem_header'; + +import { loginAndWaitForPageWithoutDateRange } from '../tasks/login'; + +import { + mlHostMultiHostKqlQuery, + mlHostMultiHostNullKqlQuery, + mlHostSingleHostKqlQuery, + mlHostSingleHostKqlQueryVariable, + mlHostSingleHostNullKqlQuery, + mlHostVariableHostKqlQuery, + mlHostVariableHostNullKqlQuery, + mlNetworkKqlQuery, + mlNetworkMultipleIpKqlQuery, + mlNetworkMultipleIpNullKqlQuery, + mlNetworkNullKqlQuery, + mlNetworkSingleIpKqlQuery, + mlNetworkSingleIpNullKqlQuery, +} from '../urls/ml_conditional_links'; + +describe('ml conditional links', () => { + it('sets the KQL from a single IP with a value for the query', () => { + loginAndWaitForPageWithoutDateRange(mlNetworkSingleIpKqlQuery); + cy.get(KQL_INPUT).should( + 'have.attr', + 'value', + '(process.name: "conhost.exe" or process.name: "sc.exe")' + ); + }); + + it('sets the KQL from a multiple IPs with a null for the query', () => { + loginAndWaitForPageWithoutDateRange(mlNetworkMultipleIpNullKqlQuery); + cy.get(KQL_INPUT).should( + 'have.attr', + 'value', + '((source.ip: "127.0.0.1" or destination.ip: "127.0.0.1") or (source.ip: "127.0.0.2" or destination.ip: "127.0.0.2"))' + ); + }); + + it('sets the KQL from a multiple IPs with a value for the query', () => { + loginAndWaitForPageWithoutDateRange(mlNetworkMultipleIpKqlQuery); + cy.get(KQL_INPUT).should( + 'have.attr', + 'value', + '((source.ip: "127.0.0.1" or destination.ip: "127.0.0.1") or (source.ip: "127.0.0.2" or destination.ip: "127.0.0.2")) and ((process.name: "conhost.exe" or process.name: "sc.exe"))' + ); + }); + + it('sets the KQL from a $ip$ with a value for the query', () => { + loginAndWaitForPageWithoutDateRange(mlNetworkKqlQuery); + cy.get(KQL_INPUT).should( + 'have.attr', + 'value', + '(process.name: "conhost.exe" or process.name: "sc.exe")' + ); + }); + + it('sets the KQL from a single host name with a value for query', () => { + loginAndWaitForPageWithoutDateRange(mlHostSingleHostKqlQuery); + cy.get(KQL_INPUT).should( + 'have.attr', + 'value', + '(process.name: "conhost.exe" or process.name: "sc.exe")' + ); + }); + + it('sets the KQL from a multiple host names with null for query', () => { + loginAndWaitForPageWithoutDateRange(mlHostMultiHostNullKqlQuery); + cy.get(KQL_INPUT).should( + 'have.attr', + 'value', + '(host.name: "siem-windows" or host.name: "siem-suricata")' + ); + }); + + it('sets the KQL from a multiple host names with a value for query', () => { + loginAndWaitForPageWithoutDateRange(mlHostMultiHostKqlQuery); + cy.get(KQL_INPUT).should( + 'have.attr', + 'value', + '(host.name: "siem-windows" or host.name: "siem-suricata") and ((process.name: "conhost.exe" or process.name: "sc.exe"))' + ); + }); + + it('sets the KQL from a undefined/null host name but with a value for query', () => { + loginAndWaitForPageWithoutDateRange(mlHostVariableHostKqlQuery); + cy.get(KQL_INPUT).should( + 'have.attr', + 'value', + '(process.name: "conhost.exe" or process.name: "sc.exe")' + ); + }); + + it('redirects from a single IP with a null for the query', () => { + loginAndWaitForPageWithoutDateRange(mlNetworkSingleIpNullKqlQuery); + cy.url().should( + 'include', + '/app/security#/network/ip/127.0.0.1/source?timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))' + ); + }); + + it('redirects from a single IP with a value for the query', () => { + loginAndWaitForPageWithoutDateRange(mlNetworkSingleIpKqlQuery); + cy.url().should( + 'include', + "/app/security#/network/ip/127.0.0.1/source?query=(language:kuery,query:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)')&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))" + ); + }); + + it('redirects from a multiple IPs with a null for the query', () => { + loginAndWaitForPageWithoutDateRange(mlNetworkMultipleIpNullKqlQuery); + cy.url().should( + 'include', + "app/security#/network/flows?query=(language:kuery,query:'((source.ip:%20%22127.0.0.1%22%20or%20destination.ip:%20%22127.0.0.1%22)%20or%20(source.ip:%20%22127.0.0.2%22%20or%20destination.ip:%20%22127.0.0.2%22))')&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999))" + ); + }); + + it('redirects from a multiple IPs with a value for the query', () => { + loginAndWaitForPageWithoutDateRange(mlNetworkMultipleIpKqlQuery); + cy.url().should( + 'include', + "/app/security#/network/flows?query=(language:kuery,query:'((source.ip:%20%22127.0.0.1%22%20or%20destination.ip:%20%22127.0.0.1%22)%20or%20(source.ip:%20%22127.0.0.2%22%20or%20destination.ip:%20%22127.0.0.2%22))%20and%20((process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22))')&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))" + ); + }); + + it('redirects from a $ip$ with a null query', () => { + loginAndWaitForPageWithoutDateRange(mlNetworkNullKqlQuery); + cy.url().should( + 'include', + '/app/security#/network/flows?timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))' + ); + }); + + it('redirects from a $ip$ with a value for the query', () => { + loginAndWaitForPageWithoutDateRange(mlNetworkKqlQuery); + cy.url().should( + 'include', + "/app/security#/network/flows?query=(language:kuery,query:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)')&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))" + ); + }); + + it('redirects from a single host name with a null for the query', () => { + loginAndWaitForPageWithoutDateRange(mlHostSingleHostNullKqlQuery); + cy.url().should( + 'include', + '/app/security#/hosts/siem-windows/anomalies?timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))' + ); + }); + + it('redirects from a host name with a variable in the query', () => { + loginAndWaitForPageWithoutDateRange(mlHostSingleHostKqlQueryVariable); + cy.url().should( + 'include', + '/app/security#/hosts/siem-windows/anomalies?timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))' + ); + }); + + it('redirects from a single host name with a value for query', () => { + loginAndWaitForPageWithoutDateRange(mlHostSingleHostKqlQuery); + cy.url().should( + 'include', + "/app/security#/hosts/siem-windows/anomalies?query=(language:kuery,query:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)')&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))" + ); + }); + + it('redirects from a multiple host names with null for query', () => { + loginAndWaitForPageWithoutDateRange(mlHostMultiHostNullKqlQuery); + cy.url().should( + 'include', + "/app/security#/hosts/anomalies?query=(language:kuery,query:'(host.name:%20%22siem-windows%22%20or%20host.name:%20%22siem-suricata%22)')&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))" + ); + }); + + it('redirects from a multiple host names with a value for query', () => { + loginAndWaitForPageWithoutDateRange(mlHostMultiHostKqlQuery); + cy.url().should( + 'include', + "/app/security#/hosts/anomalies?query=(language:kuery,query:'(host.name:%20%22siem-windows%22%20or%20host.name:%20%22siem-suricata%22)%20and%20((process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22))')&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))" + ); + }); + + it('redirects from a undefined/null host name with a null for the KQL', () => { + loginAndWaitForPageWithoutDateRange(mlHostVariableHostNullKqlQuery); + cy.url().should( + 'include', + '/app/security#/hosts/anomalies?timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))' + ); + }); + + it('redirects from a undefined/null host name but with a value for query', () => { + loginAndWaitForPageWithoutDateRange(mlHostVariableHostKqlQuery); + cy.url().should( + 'include', + "/app/security#/hosts/anomalies?query=(language:kuery,query:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)')&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))" + ); + }); +}); diff --git a/x-pack/plugins/siem/cypress/integration/navigation.spec.ts b/x-pack/plugins/security_solution/cypress/integration/navigation.spec.ts similarity index 79% rename from x-pack/plugins/siem/cypress/integration/navigation.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/navigation.spec.ts index bebd5f7d679cf..a9e5a848d54a8 100644 --- a/x-pack/plugins/siem/cypress/integration/navigation.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/navigation.spec.ts @@ -16,26 +16,26 @@ describe('top-level navigation common to all pages in the SIEM app', () => { }); it('navigates to the Overview page', () => { navigateFromHeaderTo(OVERVIEW); - cy.url().should('include', '/siem#/overview'); + cy.url().should('include', '/security#/overview'); }); it('navigates to the Hosts page', () => { navigateFromHeaderTo(HOSTS); - cy.url().should('include', '/siem#/hosts'); + cy.url().should('include', '/security#/hosts'); }); it('navigates to the Network page', () => { navigateFromHeaderTo(NETWORK); - cy.url().should('include', '/siem#/network'); + cy.url().should('include', '/security#/network'); }); it('navigates to the Detections page', () => { navigateFromHeaderTo(DETECTIONS); - cy.url().should('include', '/siem#/detections'); + cy.url().should('include', '/security#/detections'); }); it('navigates to the Timelines page', () => { navigateFromHeaderTo(TIMELINES); - cy.url().should('include', '/siem#/timelines'); + cy.url().should('include', '/security#/timelines'); }); }); diff --git a/x-pack/plugins/siem/cypress/integration/overview.spec.ts b/x-pack/plugins/security_solution/cypress/integration/overview.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/overview.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/overview.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/pagination.spec.ts b/x-pack/plugins/security_solution/cypress/integration/pagination.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/pagination.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/pagination.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/signal_detection_rules.spec.ts b/x-pack/plugins/security_solution/cypress/integration/signal_detection_rules.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/signal_detection_rules.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/signal_detection_rules.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/signal_detection_rules_custom.spec.ts b/x-pack/plugins/security_solution/cypress/integration/signal_detection_rules_custom.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/signal_detection_rules_custom.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/signal_detection_rules_custom.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/signal_detection_rules_export.spec.ts b/x-pack/plugins/security_solution/cypress/integration/signal_detection_rules_export.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/signal_detection_rules_export.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/signal_detection_rules_export.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/signal_detection_rules_ml.spec.ts b/x-pack/plugins/security_solution/cypress/integration/signal_detection_rules_ml.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/signal_detection_rules_ml.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/signal_detection_rules_ml.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/signal_detection_rules_prebuilt.spec.ts b/x-pack/plugins/security_solution/cypress/integration/signal_detection_rules_prebuilt.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/signal_detection_rules_prebuilt.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/signal_detection_rules_prebuilt.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/timeline_data_providers.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timeline_data_providers.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/timeline_data_providers.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/timeline_data_providers.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/timeline_flyout_button.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timeline_flyout_button.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/timeline_flyout_button.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/timeline_flyout_button.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/timeline_search_or_filter.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timeline_search_or_filter.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/timeline_search_or_filter.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/timeline_search_or_filter.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/timeline_toggle_column.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timeline_toggle_column.spec.ts similarity index 100% rename from x-pack/plugins/siem/cypress/integration/timeline_toggle_column.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/timeline_toggle_column.spec.ts diff --git a/x-pack/plugins/siem/cypress/integration/url_state.spec.ts b/x-pack/plugins/security_solution/cypress/integration/url_state.spec.ts similarity index 98% rename from x-pack/plugins/siem/cypress/integration/url_state.spec.ts rename to x-pack/plugins/security_solution/cypress/integration/url_state.spec.ts index 5625e1812f696..cf69a83dbf951 100644 --- a/x-pack/plugins/siem/cypress/integration/url_state.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/url_state.spec.ts @@ -255,8 +255,8 @@ describe('url state', () => { expect(matched).to.have.lengthOf(1); closeTimeline(); cy.visit('/app/kibana'); - cy.visit(`/app/siem#/overview?timeline\=(id:'${newTimelineId}',isOpen:!t)`); - cy.contains('a', 'SIEM'); + cy.visit(`/app/security#/overview?timeline\=(id:'${newTimelineId}',isOpen:!t)`); + cy.contains('a', 'Security'); cy.get(DATE_PICKER_APPLY_BUTTON_TIMELINE).invoke('text').should('not.equal', 'Updating'); cy.get(TIMELINE_TITLE).should('have.attr', 'value', timelineName); }); diff --git a/x-pack/plugins/siem/cypress/objects/case.ts b/x-pack/plugins/security_solution/cypress/objects/case.ts similarity index 100% rename from x-pack/plugins/siem/cypress/objects/case.ts rename to x-pack/plugins/security_solution/cypress/objects/case.ts diff --git a/x-pack/plugins/siem/cypress/objects/rule.ts b/x-pack/plugins/security_solution/cypress/objects/rule.ts similarity index 100% rename from x-pack/plugins/siem/cypress/objects/rule.ts rename to x-pack/plugins/security_solution/cypress/objects/rule.ts diff --git a/x-pack/plugins/siem/cypress/objects/timeline.ts b/x-pack/plugins/security_solution/cypress/objects/timeline.ts similarity index 100% rename from x-pack/plugins/siem/cypress/objects/timeline.ts rename to x-pack/plugins/security_solution/cypress/objects/timeline.ts diff --git a/x-pack/plugins/siem/cypress/plugins/index.js b/x-pack/plugins/security_solution/cypress/plugins/index.js similarity index 100% rename from x-pack/plugins/siem/cypress/plugins/index.js rename to x-pack/plugins/security_solution/cypress/plugins/index.js diff --git a/x-pack/plugins/security_solution/cypress/reporter_config.json b/x-pack/plugins/security_solution/cypress/reporter_config.json new file mode 100644 index 0000000000000..b72a5cf077c6a --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/reporter_config.json @@ -0,0 +1,10 @@ +{ + "reporterEnabled": "mochawesome, mocha-junit-reporter", + "reporterOptions": { + "html": false, + "json": true, + "mochaFile": "../../../target/kibana-security-solution/cypress/results/TEST-security-solution-cypress-[hash].xml", + "overwrite": false, + "reportDir": "../../../target/kibana-security-solution/cypress/results" + } +} diff --git a/x-pack/plugins/siem/cypress/screens/alert_detection_rules.ts b/x-pack/plugins/security_solution/cypress/screens/alert_detection_rules.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/alert_detection_rules.ts rename to x-pack/plugins/security_solution/cypress/screens/alert_detection_rules.ts diff --git a/x-pack/plugins/siem/cypress/screens/all_cases.ts b/x-pack/plugins/security_solution/cypress/screens/all_cases.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/all_cases.ts rename to x-pack/plugins/security_solution/cypress/screens/all_cases.ts diff --git a/x-pack/plugins/siem/cypress/screens/case_details.ts b/x-pack/plugins/security_solution/cypress/screens/case_details.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/case_details.ts rename to x-pack/plugins/security_solution/cypress/screens/case_details.ts diff --git a/x-pack/plugins/siem/cypress/screens/configure_cases.ts b/x-pack/plugins/security_solution/cypress/screens/configure_cases.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/configure_cases.ts rename to x-pack/plugins/security_solution/cypress/screens/configure_cases.ts diff --git a/x-pack/plugins/siem/cypress/screens/create_new_case.ts b/x-pack/plugins/security_solution/cypress/screens/create_new_case.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/create_new_case.ts rename to x-pack/plugins/security_solution/cypress/screens/create_new_case.ts diff --git a/x-pack/plugins/siem/cypress/screens/create_new_rule.ts b/x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/create_new_rule.ts rename to x-pack/plugins/security_solution/cypress/screens/create_new_rule.ts diff --git a/x-pack/plugins/siem/cypress/screens/date_picker.ts b/x-pack/plugins/security_solution/cypress/screens/date_picker.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/date_picker.ts rename to x-pack/plugins/security_solution/cypress/screens/date_picker.ts diff --git a/x-pack/plugins/siem/cypress/screens/detections.ts b/x-pack/plugins/security_solution/cypress/screens/detections.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/detections.ts rename to x-pack/plugins/security_solution/cypress/screens/detections.ts diff --git a/x-pack/plugins/siem/cypress/screens/fields_browser.ts b/x-pack/plugins/security_solution/cypress/screens/fields_browser.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/fields_browser.ts rename to x-pack/plugins/security_solution/cypress/screens/fields_browser.ts diff --git a/x-pack/plugins/siem/cypress/screens/hosts/all_hosts.ts b/x-pack/plugins/security_solution/cypress/screens/hosts/all_hosts.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/hosts/all_hosts.ts rename to x-pack/plugins/security_solution/cypress/screens/hosts/all_hosts.ts diff --git a/x-pack/plugins/siem/cypress/screens/hosts/authentications.ts b/x-pack/plugins/security_solution/cypress/screens/hosts/authentications.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/hosts/authentications.ts rename to x-pack/plugins/security_solution/cypress/screens/hosts/authentications.ts diff --git a/x-pack/plugins/siem/cypress/screens/hosts/events.ts b/x-pack/plugins/security_solution/cypress/screens/hosts/events.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/hosts/events.ts rename to x-pack/plugins/security_solution/cypress/screens/hosts/events.ts diff --git a/x-pack/plugins/siem/cypress/screens/hosts/main.ts b/x-pack/plugins/security_solution/cypress/screens/hosts/main.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/hosts/main.ts rename to x-pack/plugins/security_solution/cypress/screens/hosts/main.ts diff --git a/x-pack/plugins/siem/cypress/screens/hosts/uncommon_processes.ts b/x-pack/plugins/security_solution/cypress/screens/hosts/uncommon_processes.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/hosts/uncommon_processes.ts rename to x-pack/plugins/security_solution/cypress/screens/hosts/uncommon_processes.ts diff --git a/x-pack/plugins/siem/cypress/screens/inspect.ts b/x-pack/plugins/security_solution/cypress/screens/inspect.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/inspect.ts rename to x-pack/plugins/security_solution/cypress/screens/inspect.ts diff --git a/x-pack/plugins/siem/cypress/screens/network/flows.ts b/x-pack/plugins/security_solution/cypress/screens/network/flows.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/network/flows.ts rename to x-pack/plugins/security_solution/cypress/screens/network/flows.ts diff --git a/x-pack/plugins/siem/cypress/screens/overview.ts b/x-pack/plugins/security_solution/cypress/screens/overview.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/overview.ts rename to x-pack/plugins/security_solution/cypress/screens/overview.ts diff --git a/x-pack/plugins/siem/cypress/screens/pagination.ts b/x-pack/plugins/security_solution/cypress/screens/pagination.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/pagination.ts rename to x-pack/plugins/security_solution/cypress/screens/pagination.ts diff --git a/x-pack/plugins/siem/cypress/screens/rule_details.ts b/x-pack/plugins/security_solution/cypress/screens/rule_details.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/rule_details.ts rename to x-pack/plugins/security_solution/cypress/screens/rule_details.ts diff --git a/x-pack/plugins/siem/cypress/screens/siem_header.ts b/x-pack/plugins/security_solution/cypress/screens/siem_header.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/siem_header.ts rename to x-pack/plugins/security_solution/cypress/screens/siem_header.ts diff --git a/x-pack/plugins/siem/cypress/screens/siem_main.ts b/x-pack/plugins/security_solution/cypress/screens/siem_main.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/siem_main.ts rename to x-pack/plugins/security_solution/cypress/screens/siem_main.ts diff --git a/x-pack/plugins/siem/cypress/screens/timeline.ts b/x-pack/plugins/security_solution/cypress/screens/timeline.ts similarity index 100% rename from x-pack/plugins/siem/cypress/screens/timeline.ts rename to x-pack/plugins/security_solution/cypress/screens/timeline.ts diff --git a/x-pack/plugins/siem/cypress/support/commands.js b/x-pack/plugins/security_solution/cypress/support/commands.js similarity index 94% rename from x-pack/plugins/siem/cypress/support/commands.js rename to x-pack/plugins/security_solution/cypress/support/commands.js index 4bc62da22aca7..d086981cb98f7 100644 --- a/x-pack/plugins/siem/cypress/support/commands.js +++ b/x-pack/plugins/security_solution/cypress/support/commands.js @@ -37,5 +37,5 @@ Cypress.Commands.add('stubSIEMapi', function (dataFileName) { }); cy.server(); cy.fixture(dataFileName).as(`${dataFileName}JSON`); - cy.route('POST', 'api/siem/graphql', `@${dataFileName}JSON`); + cy.route('POST', 'api/solutions/security/graphql', `@${dataFileName}JSON`); }); diff --git a/x-pack/plugins/siem/cypress/support/index.d.ts b/x-pack/plugins/security_solution/cypress/support/index.d.ts similarity index 100% rename from x-pack/plugins/siem/cypress/support/index.d.ts rename to x-pack/plugins/security_solution/cypress/support/index.d.ts diff --git a/x-pack/plugins/siem/cypress/support/index.js b/x-pack/plugins/security_solution/cypress/support/index.js similarity index 100% rename from x-pack/plugins/siem/cypress/support/index.js rename to x-pack/plugins/security_solution/cypress/support/index.js diff --git a/x-pack/plugins/siem/cypress/tasks/alert_detection_rules.ts b/x-pack/plugins/security_solution/cypress/tasks/alert_detection_rules.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/alert_detection_rules.ts rename to x-pack/plugins/security_solution/cypress/tasks/alert_detection_rules.ts diff --git a/x-pack/plugins/siem/cypress/tasks/all_cases.ts b/x-pack/plugins/security_solution/cypress/tasks/all_cases.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/all_cases.ts rename to x-pack/plugins/security_solution/cypress/tasks/all_cases.ts diff --git a/x-pack/plugins/siem/cypress/tasks/case_details.ts b/x-pack/plugins/security_solution/cypress/tasks/case_details.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/case_details.ts rename to x-pack/plugins/security_solution/cypress/tasks/case_details.ts diff --git a/x-pack/plugins/siem/cypress/tasks/common.ts b/x-pack/plugins/security_solution/cypress/tasks/common.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/common.ts rename to x-pack/plugins/security_solution/cypress/tasks/common.ts diff --git a/x-pack/plugins/siem/cypress/tasks/configure_cases.ts b/x-pack/plugins/security_solution/cypress/tasks/configure_cases.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/configure_cases.ts rename to x-pack/plugins/security_solution/cypress/tasks/configure_cases.ts diff --git a/x-pack/plugins/siem/cypress/tasks/create_new_case.ts b/x-pack/plugins/security_solution/cypress/tasks/create_new_case.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/create_new_case.ts rename to x-pack/plugins/security_solution/cypress/tasks/create_new_case.ts diff --git a/x-pack/plugins/siem/cypress/tasks/create_new_rule.ts b/x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/create_new_rule.ts rename to x-pack/plugins/security_solution/cypress/tasks/create_new_rule.ts diff --git a/x-pack/plugins/siem/cypress/tasks/date_picker.ts b/x-pack/plugins/security_solution/cypress/tasks/date_picker.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/date_picker.ts rename to x-pack/plugins/security_solution/cypress/tasks/date_picker.ts diff --git a/x-pack/plugins/siem/cypress/tasks/detections.ts b/x-pack/plugins/security_solution/cypress/tasks/detections.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/detections.ts rename to x-pack/plugins/security_solution/cypress/tasks/detections.ts diff --git a/x-pack/plugins/security_solution/cypress/tasks/es_archiver.ts b/x-pack/plugins/security_solution/cypress/tasks/es_archiver.ts new file mode 100644 index 0000000000000..5a09a2f753dc4 --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/tasks/es_archiver.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const esArchiverLoadEmptyKibana = () => { + cy.exec( + `node ../../../scripts/es_archiver empty_kibana load empty--dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url ${Cypress.env( + 'ELASTICSEARCH_URL' + )} --kibana-url ${Cypress.config().baseUrl}` + ); +}; + +export const esArchiverLoad = (folder: string) => { + cy.exec( + `node ../../../scripts/es_archiver load ${folder} --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url ${Cypress.env( + 'ELASTICSEARCH_URL' + )} --kibana-url ${Cypress.config().baseUrl}` + ); +}; + +export const esArchiverUnload = (folder: string) => { + cy.exec( + `node ../../../scripts/es_archiver unload ${folder} --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url ${Cypress.env( + 'ELASTICSEARCH_URL' + )} --kibana-url ${Cypress.config().baseUrl}` + ); +}; + +export const esArchiverUnloadEmptyKibana = () => { + cy.exec( + `node ../../../scripts/es_archiver unload empty_kibana empty--dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url ${Cypress.env( + 'ELASTICSEARCH_URL' + )} --kibana-url ${Cypress.config().baseUrl}` + ); +}; + +export const esArchiverResetKibana = () => { + cy.exec( + `node ../../../scripts/es_archiver empty-kibana-index --config ../../../test/functional/config.js --es-url ${Cypress.env( + 'ELASTICSEARCH_URL' + )} --kibana-url ${Cypress.config().baseUrl}` + ); +}; diff --git a/x-pack/plugins/siem/cypress/tasks/fields_browser.ts b/x-pack/plugins/security_solution/cypress/tasks/fields_browser.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/fields_browser.ts rename to x-pack/plugins/security_solution/cypress/tasks/fields_browser.ts diff --git a/x-pack/plugins/siem/cypress/tasks/hosts/all_hosts.ts b/x-pack/plugins/security_solution/cypress/tasks/hosts/all_hosts.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/hosts/all_hosts.ts rename to x-pack/plugins/security_solution/cypress/tasks/hosts/all_hosts.ts diff --git a/x-pack/plugins/siem/cypress/tasks/hosts/authentications.ts b/x-pack/plugins/security_solution/cypress/tasks/hosts/authentications.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/hosts/authentications.ts rename to x-pack/plugins/security_solution/cypress/tasks/hosts/authentications.ts diff --git a/x-pack/plugins/siem/cypress/tasks/hosts/events.ts b/x-pack/plugins/security_solution/cypress/tasks/hosts/events.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/hosts/events.ts rename to x-pack/plugins/security_solution/cypress/tasks/hosts/events.ts diff --git a/x-pack/plugins/siem/cypress/tasks/hosts/main.ts b/x-pack/plugins/security_solution/cypress/tasks/hosts/main.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/hosts/main.ts rename to x-pack/plugins/security_solution/cypress/tasks/hosts/main.ts diff --git a/x-pack/plugins/siem/cypress/tasks/hosts/uncommon_processes.ts b/x-pack/plugins/security_solution/cypress/tasks/hosts/uncommon_processes.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/hosts/uncommon_processes.ts rename to x-pack/plugins/security_solution/cypress/tasks/hosts/uncommon_processes.ts diff --git a/x-pack/plugins/siem/cypress/tasks/inspect.ts b/x-pack/plugins/security_solution/cypress/tasks/inspect.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/inspect.ts rename to x-pack/plugins/security_solution/cypress/tasks/inspect.ts diff --git a/x-pack/plugins/siem/cypress/tasks/login.ts b/x-pack/plugins/security_solution/cypress/tasks/login.ts similarity index 98% rename from x-pack/plugins/siem/cypress/tasks/login.ts rename to x-pack/plugins/security_solution/cypress/tasks/login.ts index 13580037b3d7c..4479c8d9d1fbe 100644 --- a/x-pack/plugins/siem/cypress/tasks/login.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/login.ts @@ -124,12 +124,12 @@ export const loginAndWaitForPage = (url: string) => { cy.visit( `${url}?timerange=(global:(linkTo:!(timeline),timerange:(from:1547914976217,fromStr:'2019-01-19T16:22:56.217Z',kind:relative,to:1579537385745,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1547914976217,fromStr:'2019-01-19T16:22:56.217Z',kind:relative,to:1579537385745,toStr:now)))` ); - cy.contains('a', 'SIEM'); + cy.contains('a', 'Security'); }; export const loginAndWaitForPageWithoutDateRange = (url: string) => { login(); cy.viewport('macbook-15'); cy.visit(url); - cy.contains('a', 'SIEM', { timeout: 120000 }); + cy.contains('a', 'Security', { timeout: 120000 }); }; diff --git a/x-pack/plugins/siem/cypress/tasks/network/flows.ts b/x-pack/plugins/security_solution/cypress/tasks/network/flows.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/network/flows.ts rename to x-pack/plugins/security_solution/cypress/tasks/network/flows.ts diff --git a/x-pack/plugins/siem/cypress/tasks/overview.ts b/x-pack/plugins/security_solution/cypress/tasks/overview.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/overview.ts rename to x-pack/plugins/security_solution/cypress/tasks/overview.ts diff --git a/x-pack/plugins/siem/cypress/tasks/pagination.ts b/x-pack/plugins/security_solution/cypress/tasks/pagination.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/pagination.ts rename to x-pack/plugins/security_solution/cypress/tasks/pagination.ts diff --git a/x-pack/plugins/siem/cypress/tasks/siem_header.ts b/x-pack/plugins/security_solution/cypress/tasks/siem_header.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/siem_header.ts rename to x-pack/plugins/security_solution/cypress/tasks/siem_header.ts diff --git a/x-pack/plugins/siem/cypress/tasks/siem_main.ts b/x-pack/plugins/security_solution/cypress/tasks/siem_main.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/siem_main.ts rename to x-pack/plugins/security_solution/cypress/tasks/siem_main.ts diff --git a/x-pack/plugins/siem/cypress/tasks/timeline.ts b/x-pack/plugins/security_solution/cypress/tasks/timeline.ts similarity index 100% rename from x-pack/plugins/siem/cypress/tasks/timeline.ts rename to x-pack/plugins/security_solution/cypress/tasks/timeline.ts diff --git a/x-pack/plugins/siem/cypress/test_files/expected_rules_export.ndjson b/x-pack/plugins/security_solution/cypress/test_files/expected_rules_export.ndjson similarity index 100% rename from x-pack/plugins/siem/cypress/test_files/expected_rules_export.ndjson rename to x-pack/plugins/security_solution/cypress/test_files/expected_rules_export.ndjson diff --git a/x-pack/plugins/siem/cypress/tsconfig.json b/x-pack/plugins/security_solution/cypress/tsconfig.json similarity index 100% rename from x-pack/plugins/siem/cypress/tsconfig.json rename to x-pack/plugins/security_solution/cypress/tsconfig.json diff --git a/x-pack/plugins/security_solution/cypress/urls/ml_conditional_links.ts b/x-pack/plugins/security_solution/cypress/urls/ml_conditional_links.ts new file mode 100644 index 0000000000000..cfa18099e5888 --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/urls/ml_conditional_links.ts @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/* + * These links are for different test scenarios that try and capture different drill downs into + * ml-network and ml-hosts and are of the flavor of testing: + * A filter being null: (query:!n) + * A filter being set with single values: query=(query:%27process.name%20:%20%22conhost.exe%22%27,language:kuery) + * A filter being set with multiple values: query=(query:%27process.name%20:%20%22conhost.exe,sc.exe%22%27,language:kuery) + * A filter containing variables not replaced: query=(query:%27process.name%20:%20%$process.name$%22%27,language:kuery) + * + * In different combination with: + * network not being set: $ip$ + * host not being set: $host.name$ + * ...or... + * network being set normally: 127.0.0.1 + * host being set normally: suricata-iowa + * ...or... + * network having multiple values: 127.0.0.1,127.0.0.2 + * host having multiple values: suricata-iowa,siem-windows + */ + +// Single IP with a null for the Query: +export const mlNetworkSingleIpNullKqlQuery = + "/app/security#/ml-network/ip/127.0.0.1?query=!n&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))"; + +// Single IP with a value for the Query: +export const mlNetworkSingleIpKqlQuery = + "/app/security#/ml-network/ip/127.0.0.1?query=(language:kuery,query:'process.name%20:%20%22conhost.exe,sc.exe%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))"; + +// Multiple IPs with a null for the Query: +export const mlNetworkMultipleIpNullKqlQuery = + "/app/security#/ml-network/ip/127.0.0.1,127.0.0.2?query=!n&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))"; + +// Multiple IPs with a value for the Query: +export const mlNetworkMultipleIpKqlQuery = + "/app/security#/ml-network/ip/127.0.0.1,127.0.0.2?query=(language:kuery,query:'process.name%20:%20%22conhost.exe,sc.exe%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))"; + +// $ip$ with a null Query: +export const mlNetworkNullKqlQuery = + "/app/security#/ml-network/ip/$ip$?query=!n&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))"; + +// $ip$ with a value for the Query: +export const mlNetworkKqlQuery = + "/app/security#/ml-network/ip/$ip$?query=(language:kuery,query:'process.name%20:%20%22conhost.exe,sc.exe%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-28T11:00:00.000Z',kind:absolute,to:'2019-08-28T13:59:59.999Z')))"; + +// Single host name with a null for the Query: +export const mlHostSingleHostNullKqlQuery = + "/app/security#/ml-hosts/siem-windows?query=!n&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))"; + +// Single host name with a variable in the Query: +export const mlHostSingleHostKqlQueryVariable = + "/app/security#/ml-hosts/siem-windows?query=(language:kuery,query:'process.name%20:%20%22$process.name$%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))"; + +// Single host name with a value for Query: +export const mlHostSingleHostKqlQuery = + "/app/security#/ml-hosts/siem-windows?query=(language:kuery,query:'process.name%20:%20%22conhost.exe,sc.exe%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))"; + +// Multiple host names with null for Query: +export const mlHostMultiHostNullKqlQuery = + "/app/security#/ml-hosts/siem-windows,siem-suricata?query=!n&&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))"; + +// Multiple host names with a value for Query: +export const mlHostMultiHostKqlQuery = + "/app/security#/ml-hosts/siem-windows,siem-suricata?query=(language:kuery,query:'process.name%20:%20%22conhost.exe,sc.exe%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))"; + +// Undefined/null host name with a null for the KQL: +export const mlHostVariableHostNullKqlQuery = + "/app/security#/ml-hosts/$host.name$?query=!n&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))"; + +// Undefined/null host name but with a value for Query: +export const mlHostVariableHostKqlQuery = + "/app/security#/ml-hosts/$host.name$?query=(language:kuery,query:'process.name%20:%20%22conhost.exe,sc.exe%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')),timeline:(linkTo:!(global),timerange:(from:'2019-06-06T06:00:00.000Z',kind:absolute,to:'2019-06-07T05:59:59.999Z')))"; diff --git a/x-pack/plugins/security_solution/cypress/urls/navigation.ts b/x-pack/plugins/security_solution/cypress/urls/navigation.ts new file mode 100644 index 0000000000000..9bfe2e9e5102e --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/urls/navigation.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const CASES = '/app/security#/case'; +export const DETECTIONS = 'app/security#/detections'; +export const HOSTS_PAGE = '/app/security#/hosts/allHosts'; +export const HOSTS_PAGE_TAB_URLS = { + allHosts: '/app/security#/hosts/allHosts', + anomalies: '/app/security#/hosts/anomalies', + authentications: '/app/security#/hosts/authentications', + events: '/app/security#/hosts/events', + uncommonProcesses: '/app/security#/hosts/uncommonProcesses', +}; +export const NETWORK_PAGE = '/app/security#/network'; +export const OVERVIEW_PAGE = '/app/security#/overview'; +export const TIMELINES_PAGE = '/app/security#/timelines'; diff --git a/x-pack/plugins/security_solution/cypress/urls/state.ts b/x-pack/plugins/security_solution/cypress/urls/state.ts new file mode 100644 index 0000000000000..6de30fdafdaf8 --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/urls/state.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const ABSOLUTE_DATE_RANGE = { + url: + '/app/security#/network/?timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1564691609186)))', + + urlUnlinked: + '/app/security#/network/?timerange=(global:(linkTo:!(),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(),timerange:(from:1564776209186,kind:absolute,to:1564779809186)))', + urlKqlNetworkNetwork: `/app/security#/network/?query=(language:kuery,query:'source.ip:%20"10.142.0.9"')&timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1564691609186)))`, + urlKqlNetworkHosts: `/app/security#/network/?query=(language:kuery,query:'source.ip:%20"10.142.0.9"')&timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1564691609186)))`, + urlKqlHostsNetwork: `/app/security#/hosts/allHosts?query=(language:kuery,query:'source.ip:%20"10.142.0.9"')&timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1564691609186)))`, + urlKqlHostsHosts: `/app/security#/hosts/allHosts?query=(language:kuery,query:'source.ip:%20"10.142.0.9"')&timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1564691609186)))`, + urlHost: + '/app/security#/hosts/authentications?timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1564691609186)))', + urlHostNew: + '/app/security#/hosts/authentications?timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1577914409186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1577914409186)))', +}; diff --git a/x-pack/plugins/security_solution/kibana.json b/x-pack/plugins/security_solution/kibana.json new file mode 100644 index 0000000000000..8ce8820a8e57d --- /dev/null +++ b/x-pack/plugins/security_solution/kibana.json @@ -0,0 +1,32 @@ +{ + "id": "securitySolution", + "version": "8.0.0", + "kibanaVersion": "kibana", + "configPath": ["xpack", "securitySolution"], + "requiredPlugins": [ + "actions", + "alerts", + "data", + "dataEnhanced", + "embeddable", + "features", + "home", + "ingestManager", + "inspector", + "licensing", + "maps", + "triggers_actions_ui", + "uiActions" + ], + "optionalPlugins": [ + "encryptedSavedObjects", + "ml", + "newsfeed", + "security", + "spaces", + "usageCollection", + "lists" + ], + "server": true, + "ui": true +} diff --git a/x-pack/plugins/security_solution/package.json b/x-pack/plugins/security_solution/package.json new file mode 100644 index 0000000000000..73347e00e6b34 --- /dev/null +++ b/x-pack/plugins/security_solution/package.json @@ -0,0 +1,24 @@ +{ + "author": "Elastic", + "name": "security_solution", + "version": "8.0.0", + "private": true, + "license": "Elastic-License", + "scripts": { + "extract-mitre-attacks": "node scripts/extract_tactics_techniques_mitre.js && node ../../../scripts/eslint ./public/pages/detection_engine/mitre/mitre_tactics_techniques.ts --fix", + "build-graphql-types": "node scripts/generate_types_from_graphql.js", + "cypress:open": "cypress open --config-file ./cypress/cypress.json", + "cypress:run": "cypress run --browser chrome --headless --spec ./cypress/integration/**/*.spec.ts --config-file ./cypress/cypress.json --reporter ../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json; status=$?; ../../node_modules/.bin/mochawesome-merge --reportDir ../../../target/kibana-security-solution/cypress/results > ../../../target/kibana-security-solution/cypress/results/output.json; ../../../node_modules/.bin/marge ../../../target/kibana-security-solution/cypress/results/output.json --reportDir ../../../target/kibana-security-solution/cypress/results; mkdir -p ../../../target/junit && cp ../../../target/kibana-security-solution/cypress/results/*.xml ../../../target/junit/ && exit $status;", + "cypress:run-as-ci": "node ../../../scripts/functional_tests --config ../../test/security_solution_cypress/config.ts", + "test:generate": "ts-node --project scripts/endpoint/cli_tsconfig.json scripts/endpoint/resolver_generator.ts" + }, + "devDependencies": { + "@types/lodash": "^4.14.110" + }, + "dependencies": { + "lodash": "^4.17.15", + "querystring": "^0.2.0", + "redux-devtools-extension": "^2.13.8", + "@types/seedrandom": ">=2.0.0 <4.0.0" + } +} diff --git a/x-pack/plugins/siem/public/alerts/components/activity_monitor/columns.tsx b/x-pack/plugins/security_solution/public/alerts/components/activity_monitor/columns.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/activity_monitor/columns.tsx rename to x-pack/plugins/security_solution/public/alerts/components/activity_monitor/columns.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/activity_monitor/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/activity_monitor/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/activity_monitor/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/activity_monitor/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/activity_monitor/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/activity_monitor/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/activity_monitor/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/activity_monitor/index.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/activity_monitor/types.ts b/x-pack/plugins/security_solution/public/alerts/components/activity_monitor/types.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/activity_monitor/types.ts rename to x-pack/plugins/security_solution/public/alerts/components/activity_monitor/types.ts diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_histogram_panel/alerts_histogram.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/alerts_histogram.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_histogram_panel/alerts_histogram.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/alerts_histogram.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_histogram_panel/alerts_histogram.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/alerts_histogram.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_histogram_panel/alerts_histogram.tsx rename to x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/alerts_histogram.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_histogram_panel/config.ts b/x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/config.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_histogram_panel/config.ts rename to x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/config.ts diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_histogram_panel/helpers.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/helpers.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_histogram_panel/helpers.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/helpers.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_histogram_panel/helpers.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/helpers.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_histogram_panel/helpers.tsx rename to x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/helpers.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_histogram_panel/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_histogram_panel/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/index.tsx new file mode 100644 index 0000000000000..ed98a37775576 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/index.tsx @@ -0,0 +1,290 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { Position } from '@elastic/charts'; +import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiSelect, EuiPanel } from '@elastic/eui'; +import numeral from '@elastic/numeral'; +import React, { memo, useCallback, useMemo, useState, useEffect } from 'react'; +import styled from 'styled-components'; +import { isEmpty } from 'lodash/fp'; +import uuid from 'uuid'; + +import { DEFAULT_NUMBER_FORMAT } from '../../../../common/constants'; +import { UpdateDateRange } from '../../../common/components/charts/common'; +import { LegendItem } from '../../../common/components/charts/draggable_legend_item'; +import { escapeDataProviderId } from '../../../common/components/drag_and_drop/helpers'; +import { HeaderSection } from '../../../common/components/header_section'; +import { Filter, esQuery, Query } from '../../../../../../../src/plugins/data/public'; +import { useQueryAlerts } from '../../containers/detection_engine/alerts/use_query'; +import { getDetectionEngineUrl } from '../../../common/components/link_to'; +import { defaultLegendColors } from '../../../common/components/matrix_histogram/utils'; +import { InspectButtonContainer } from '../../../common/components/inspect'; +import { useGetUrlSearch } from '../../../common/components/navigation/use_get_url_search'; +import { MatrixLoader } from '../../../common/components/matrix_histogram/matrix_loader'; +import { MatrixHistogramOption } from '../../../common/components/matrix_histogram/types'; +import { useKibana, useUiSetting$ } from '../../../common/lib/kibana'; +import { navTabs } from '../../../app/home/home_navigations'; +import { alertsHistogramOptions } from './config'; +import { formatAlertsData, getAlertsHistogramQuery, showInitialLoadingSpinner } from './helpers'; +import { AlertsHistogram } from './alerts_histogram'; +import * as i18n from './translations'; +import { RegisterQuery, AlertsHistogramOption, AlertsAggregation, AlertsTotal } from './types'; + +const DEFAULT_PANEL_HEIGHT = 300; + +const StyledEuiPanel = styled(EuiPanel)<{ height?: number }>` + display: flex; + flex-direction: column; + ${({ height }) => (height != null ? `height: ${height}px;` : '')} + position: relative; +`; + +const defaultTotalAlertsObj: AlertsTotal = { + value: 0, + relation: 'eq', +}; + +export const DETECTIONS_HISTOGRAM_ID = 'detections-histogram'; + +const ViewAlertsFlexItem = styled(EuiFlexItem)` + margin-left: 24px; +`; + +interface AlertsHistogramPanelProps { + chartHeight?: number; + defaultStackByOption?: AlertsHistogramOption; + deleteQuery?: ({ id }: { id: string }) => void; + filters?: Filter[]; + from: number; + headerChildren?: React.ReactNode; + /** Override all defaults, and only display this field */ + onlyField?: string; + query?: Query; + legendPosition?: Position; + panelHeight?: number; + signalIndexName: string | null; + setQuery: (params: RegisterQuery) => void; + showLinkToAlerts?: boolean; + showTotalAlertsCount?: boolean; + stackByOptions?: AlertsHistogramOption[]; + title?: string; + to: number; + updateDateRange: UpdateDateRange; +} + +const getHistogramOption = (fieldName: string): MatrixHistogramOption => ({ + text: fieldName, + value: fieldName, +}); + +const NO_LEGEND_DATA: LegendItem[] = []; + +export const AlertsHistogramPanel = memo( + ({ + chartHeight, + defaultStackByOption = alertsHistogramOptions[0], + deleteQuery, + filters, + headerChildren, + onlyField, + query, + from, + legendPosition = 'right', + panelHeight = DEFAULT_PANEL_HEIGHT, + setQuery, + signalIndexName, + showLinkToAlerts = false, + showTotalAlertsCount = false, + stackByOptions, + to, + title = i18n.HISTOGRAM_HEADER, + updateDateRange, + }) => { + // create a unique, but stable (across re-renders) query id + const uniqueQueryId = useMemo(() => `${DETECTIONS_HISTOGRAM_ID}-${uuid.v4()}`, []); + const [isInitialLoading, setIsInitialLoading] = useState(true); + const [defaultNumberFormat] = useUiSetting$(DEFAULT_NUMBER_FORMAT); + const [totalAlertsObj, setTotalAlertsObj] = useState(defaultTotalAlertsObj); + const [selectedStackByOption, setSelectedStackByOption] = useState( + onlyField == null ? defaultStackByOption : getHistogramOption(onlyField) + ); + const { + loading: isLoadingAlerts, + data: alertsData, + setQuery: setAlertsQuery, + response, + request, + refetch, + } = useQueryAlerts<{}, AlertsAggregation>( + getAlertsHistogramQuery(selectedStackByOption.value, from, to, []), + signalIndexName + ); + const kibana = useKibana(); + const urlSearch = useGetUrlSearch(navTabs.detections); + + const totalAlerts = useMemo( + () => + i18n.SHOWING_ALERTS( + numeral(totalAlertsObj.value).format(defaultNumberFormat), + totalAlertsObj.value, + totalAlertsObj.relation === 'gte' ? '>' : totalAlertsObj.relation === 'lte' ? '<' : '' + ), + // eslint-disable-next-line react-hooks/exhaustive-deps + [totalAlertsObj] + ); + + const setSelectedOptionCallback = useCallback((event: React.ChangeEvent) => { + setSelectedStackByOption( + stackByOptions?.find((co) => co.value === event.target.value) ?? defaultStackByOption + ); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const formattedAlertsData = useMemo(() => formatAlertsData(alertsData), [alertsData]); + + const legendItems: LegendItem[] = useMemo( + () => + alertsData?.aggregations?.alertsByGrouping?.buckets != null + ? alertsData.aggregations.alertsByGrouping.buckets.map((bucket, i) => ({ + color: i < defaultLegendColors.length ? defaultLegendColors[i] : undefined, + dataProviderId: escapeDataProviderId( + `draggable-legend-item-${uuid.v4()}-${selectedStackByOption.value}-${bucket.key}` + ), + field: selectedStackByOption.value, + value: bucket.key, + })) + : NO_LEGEND_DATA, + // eslint-disable-next-line react-hooks/exhaustive-deps + [alertsData, selectedStackByOption.value] + ); + + useEffect(() => { + let canceled = false; + + if (!canceled && !showInitialLoadingSpinner({ isInitialLoading, isLoadingAlerts })) { + setIsInitialLoading(false); + } + + return () => { + canceled = true; // prevent long running data fetches from updating state after unmounting + }; + }, [isInitialLoading, isLoadingAlerts, setIsInitialLoading]); + + useEffect(() => { + return () => { + if (deleteQuery) { + deleteQuery({ id: uniqueQueryId }); + } + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + if (refetch != null && setQuery != null) { + setQuery({ + id: uniqueQueryId, + inspect: { + dsl: [request], + response: [response], + }, + loading: isLoadingAlerts, + refetch, + }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [setQuery, isLoadingAlerts, alertsData, response, request, refetch]); + + useEffect(() => { + setTotalAlertsObj( + alertsData?.hits.total ?? { + value: 0, + relation: 'eq', + } + ); + }, [alertsData]); + + useEffect(() => { + const converted = esQuery.buildEsQuery( + undefined, + query != null ? [query] : [], + filters?.filter((f) => f.meta.disabled === false) ?? [], + { + ...esQuery.getEsQueryConfig(kibana.services.uiSettings), + dateFormatTZ: undefined, + } + ); + + setAlertsQuery( + getAlertsHistogramQuery( + selectedStackByOption.value, + from, + to, + !isEmpty(converted) ? [converted] : [] + ) + ); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selectedStackByOption.value, from, to, query, filters]); + + const linkButton = useMemo(() => { + if (showLinkToAlerts) { + return ( + + {i18n.VIEW_ALERTS} + + ); + } + }, [showLinkToAlerts, urlSearch]); + + const titleText = useMemo(() => (onlyField == null ? title : i18n.TOP(onlyField)), [ + onlyField, + title, + ]); + + return ( + + + + + + {stackByOptions && ( + + )} + {headerChildren != null && headerChildren} + + {linkButton} + + + + {isInitialLoading ? ( + + ) : ( + + )} + + + ); + } +); + +AlertsHistogramPanel.displayName = 'AlertsHistogramPanel'; diff --git a/x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/translations.ts b/x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/translations.ts new file mode 100644 index 0000000000000..6eaa0ba3fc4ec --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/translations.ts @@ -0,0 +1,122 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const STACK_BY_LABEL = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.stackByLabel', + { + defaultMessage: 'Stack by', + } +); + +export const STACK_BY_RISK_SCORES = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.riskScoresDropDown', + { + defaultMessage: 'Risk scores', + } +); + +export const STACK_BY_SEVERITIES = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.severitiesDropDown', + { + defaultMessage: 'Severities', + } +); + +export const STACK_BY_DESTINATION_IPS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.destinationIpsDropDown', + { + defaultMessage: 'Top destination IPs', + } +); + +export const STACK_BY_SOURCE_IPS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.sourceIpsDropDown', + { + defaultMessage: 'Top source IPs', + } +); + +export const STACK_BY_ACTIONS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.eventActionsDropDown', + { + defaultMessage: 'Top event actions', + } +); + +export const STACK_BY_CATEGORIES = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.eventCategoriesDropDown', + { + defaultMessage: 'Top event categories', + } +); + +export const STACK_BY_HOST_NAMES = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.hostNamesDropDown', + { + defaultMessage: 'Top host names', + } +); + +export const STACK_BY_RULE_TYPES = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.ruleTypesDropDown', + { + defaultMessage: 'Top rule types', + } +); + +export const STACK_BY_RULE_NAMES = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.rulesDropDown', + { + defaultMessage: 'Top rules', + } +); + +export const STACK_BY_USERS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.usersDropDown', + { + defaultMessage: 'Top users', + } +); + +export const TOP = (fieldName: string) => + i18n.translate('xpack.securitySolution.detectionEngine.alerts.histogram.topNLabel', { + values: { fieldName }, + defaultMessage: `Top {fieldName}`, + }); + +export const HISTOGRAM_HEADER = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.histogram.headerTitle', + { + defaultMessage: 'Alert count', + } +); + +export const ALL_OTHERS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.histogram.allOthersGroupingLabel', + { + defaultMessage: 'All others', + } +); + +export const VIEW_ALERTS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.histogram.viewAlertsButtonLabel', + { + defaultMessage: 'View alerts', + } +); + +export const SHOWING_ALERTS = ( + totalAlertsFormatted: string, + totalAlerts: number, + modifier: string +) => + i18n.translate('xpack.securitySolution.detectionEngine.alerts.histogram.showingAlertsTitle', { + values: { totalAlertsFormatted, totalAlerts, modifier }, + defaultMessage: + 'Showing: {modifier}{totalAlertsFormatted} {totalAlerts, plural, =1 {alert} other {alerts}}', + }); diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_histogram_panel/types.ts b/x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/types.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_histogram_panel/types.ts rename to x-pack/plugins/security_solution/public/alerts/components/alerts_histogram_panel/types.ts diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_info/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_info/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_info/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/alerts_info/index.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_info/query.dsl.ts b/x-pack/plugins/security_solution/public/alerts/components/alerts_info/query.dsl.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_info/query.dsl.ts rename to x-pack/plugins/security_solution/public/alerts/components/alerts_info/query.dsl.ts diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_info/types.ts b/x-pack/plugins/security_solution/public/alerts/components/alerts_info/types.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_info/types.ts rename to x-pack/plugins/security_solution/public/alerts/components/alerts_info/types.ts diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_table/actions.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/actions.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_table/actions.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/alerts_table/actions.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_table/actions.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/actions.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_table/actions.tsx rename to x-pack/plugins/security_solution/public/alerts/components/alerts_table/actions.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_table/alerts_filter_group/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/alerts_filter_group/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_table/alerts_filter_group/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/alerts_table/alerts_filter_group/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_table/alerts_filter_group/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/alerts_filter_group/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_table/alerts_filter_group/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/alerts_table/alerts_filter_group/index.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_table/alerts_utility_bar/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/alerts_utility_bar/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_table/alerts_utility_bar/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/alerts_table/alerts_utility_bar/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_table/alerts_utility_bar/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/alerts_utility_bar/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_table/alerts_utility_bar/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/alerts_table/alerts_utility_bar/index.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/alerts_table/alerts_utility_bar/translations.ts b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/alerts_utility_bar/translations.ts new file mode 100644 index 0000000000000..9427464e23726 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/alerts_utility_bar/translations.ts @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const SHOWING_ALERTS = (totalAlertsFormatted: string, totalAlerts: number) => + i18n.translate('xpack.securitySolution.detectionEngine.alerts.utilityBar.showingAlertsTitle', { + values: { totalAlertsFormatted, totalAlerts }, + defaultMessage: + 'Showing {totalAlertsFormatted} {totalAlerts, plural, =1 {alert} other {alerts}}', + }); + +export const SELECTED_ALERTS = (selectedAlertsFormatted: string, selectedAlerts: number) => + i18n.translate('xpack.securitySolution.detectionEngine.alerts.utilityBar.selectedAlertsTitle', { + values: { selectedAlertsFormatted, selectedAlerts }, + defaultMessage: + 'Selected {selectedAlertsFormatted} {selectedAlerts, plural, =1 {alert} other {alerts}}', + }); + +export const SELECT_ALL_ALERTS = (totalAlertsFormatted: string, totalAlerts: number) => + i18n.translate('xpack.securitySolution.detectionEngine.alerts.utilityBar.selectAllAlertsTitle', { + values: { totalAlertsFormatted, totalAlerts }, + defaultMessage: + 'Select all {totalAlertsFormatted} {totalAlerts, plural, =1 {alert} other {alerts}}', + }); + +export const CLEAR_SELECTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.utilityBar.clearSelectionTitle', + { + defaultMessage: 'Clear selection', + } +); + +export const BATCH_ACTIONS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActionsTitle', + { + defaultMessage: 'Batch actions', + } +); + +export const BATCH_ACTION_VIEW_SELECTED_IN_HOSTS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.viewSelectedInHostsTitle', + { + defaultMessage: 'View selected in hosts', + } +); + +export const BATCH_ACTION_VIEW_SELECTED_IN_NETWORK = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.viewSelectedInNetworkTitle', + { + defaultMessage: 'View selected in network', + } +); + +export const BATCH_ACTION_VIEW_SELECTED_IN_TIMELINE = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.viewSelectedInTimelineTitle', + { + defaultMessage: 'View selected in timeline', + } +); + +export const BATCH_ACTION_OPEN_SELECTED = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.openSelectedTitle', + { + defaultMessage: 'Open selected', + } +); + +export const BATCH_ACTION_CLOSE_SELECTED = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.closeSelectedTitle', + { + defaultMessage: 'Close selected', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_table/default_config.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/default_config.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_table/default_config.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/alerts_table/default_config.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_table/default_config.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/default_config.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_table/default_config.tsx rename to x-pack/plugins/security_solution/public/alerts/components/alerts_table/default_config.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_table/helpers.test.ts b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/helpers.test.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_table/helpers.test.ts rename to x-pack/plugins/security_solution/public/alerts/components/alerts_table/helpers.test.ts diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_table/helpers.ts b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/helpers.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_table/helpers.ts rename to x-pack/plugins/security_solution/public/alerts/components/alerts_table/helpers.ts diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_table/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_table/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/alerts_table/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/index.tsx new file mode 100644 index 0000000000000..2be20a9d47f67 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/index.tsx @@ -0,0 +1,413 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiPanel, EuiLoadingContent } from '@elastic/eui'; +import { isEmpty } from 'lodash/fp'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { connect, ConnectedProps } from 'react-redux'; +import { Dispatch } from 'redux'; + +import { Filter, esQuery } from '../../../../../../../src/plugins/data/public'; +import { useFetchIndexPatterns } from '../../../alerts/containers/detection_engine/rules/fetch_index_patterns'; +import { StatefulEventsViewer } from '../../../common/components/events_viewer'; +import { HeaderSection } from '../../../common/components/header_section'; +import { combineQueries } from '../../../timelines/components/timeline/helpers'; +import { useKibana } from '../../../common/lib/kibana'; +import { inputsSelectors, State, inputsModel } from '../../../common/store'; +import { timelineActions, timelineSelectors } from '../../../timelines/store/timeline'; +import { TimelineModel } from '../../../timelines/store/timeline/model'; +import { timelineDefaults } from '../../../timelines/store/timeline/defaults'; +import { useManageTimeline } from '../../../timelines/components/manage_timeline'; +import { useApolloClient } from '../../../common/utils/apollo_context'; + +import { updateAlertStatusAction } from './actions'; +import { + getAlertActions, + requiredFieldsForActions, + alertsClosedFilters, + alertsDefaultModel, + alertsOpenFilters, +} from './default_config'; +import { + FILTER_CLOSED, + FILTER_OPEN, + AlertFilterOption, + AlertsTableFilterGroup, +} from './alerts_filter_group'; +import { AlertsUtilityBar } from './alerts_utility_bar'; +import * as i18n from './translations'; +import { + CreateTimelineProps, + SetEventsDeletedProps, + SetEventsLoadingProps, + UpdateAlertsStatusCallback, + UpdateAlertsStatusProps, +} from './types'; +import { dispatchUpdateTimeline } from '../../../timelines/components/open_timeline/helpers'; +import { + useStateToaster, + displaySuccessToast, + displayErrorToast, +} from '../../../common/components/toasters'; + +export const ALERTS_TABLE_TIMELINE_ID = 'alerts-table'; + +interface OwnProps { + canUserCRUD: boolean; + defaultFilters?: Filter[]; + hasIndexWrite: boolean; + from: number; + loading: boolean; + signalsIndex: string; + to: number; +} + +type AlertsTableComponentProps = OwnProps & PropsFromRedux; + +export const AlertsTableComponent: React.FC = ({ + canUserCRUD, + clearEventsDeleted, + clearEventsLoading, + clearSelected, + defaultFilters, + from, + globalFilters, + globalQuery, + hasIndexWrite, + isSelectAllChecked, + loading, + loadingEventIds, + selectedEventIds, + setEventsDeleted, + setEventsLoading, + signalsIndex, + to, + updateTimeline, + updateTimelineIsLoading, +}) => { + const [selectAll, setSelectAll] = useState(false); + const apolloClient = useApolloClient(); + + const [showClearSelectionAction, setShowClearSelectionAction] = useState(false); + const [filterGroup, setFilterGroup] = useState(FILTER_OPEN); + const [{ browserFields, indexPatterns }] = useFetchIndexPatterns( + signalsIndex !== '' ? [signalsIndex] : [] + ); + const kibana = useKibana(); + const [, dispatchToaster] = useStateToaster(); + + const getGlobalQuery = useCallback(() => { + if (browserFields != null && indexPatterns != null) { + return combineQueries({ + config: esQuery.getEsQueryConfig(kibana.services.uiSettings), + dataProviders: [], + indexPattern: indexPatterns, + browserFields, + filters: isEmpty(defaultFilters) + ? globalFilters + : [...(defaultFilters ?? []), ...globalFilters], + kqlQuery: globalQuery, + kqlMode: globalQuery.language, + start: from, + end: to, + isEventViewer: true, + }); + } + return null; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [browserFields, globalFilters, globalQuery, indexPatterns, kibana, to, from]); + + // Callback for creating a new timeline -- utilized by row/batch actions + const createTimelineCallback = useCallback( + ({ from: fromTimeline, timeline, to: toTimeline, ruleNote }: CreateTimelineProps) => { + updateTimelineIsLoading({ id: 'timeline-1', isLoading: false }); + updateTimeline({ + duplicate: true, + from: fromTimeline, + id: 'timeline-1', + notes: [], + timeline: { + ...timeline, + show: true, + }, + to: toTimeline, + ruleNote, + })(); + }, + [updateTimeline, updateTimelineIsLoading] + ); + + const setEventsLoadingCallback = useCallback( + ({ eventIds, isLoading }: SetEventsLoadingProps) => { + setEventsLoading!({ id: ALERTS_TABLE_TIMELINE_ID, eventIds, isLoading }); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [setEventsLoading, ALERTS_TABLE_TIMELINE_ID] + ); + + const setEventsDeletedCallback = useCallback( + ({ eventIds, isDeleted }: SetEventsDeletedProps) => { + setEventsDeleted!({ id: ALERTS_TABLE_TIMELINE_ID, eventIds, isDeleted }); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [setEventsDeleted, ALERTS_TABLE_TIMELINE_ID] + ); + + const onAlertStatusUpdateSuccess = useCallback( + (count: number, status: string) => { + const title = + status === 'closed' + ? i18n.CLOSED_ALERT_SUCCESS_TOAST(count) + : i18n.OPENED_ALERT_SUCCESS_TOAST(count); + + displaySuccessToast(title, dispatchToaster); + }, + [dispatchToaster] + ); + + const onAlertStatusUpdateFailure = useCallback( + (status: string, error: Error) => { + const title = + status === 'closed' ? i18n.CLOSED_ALERT_FAILED_TOAST : i18n.OPENED_ALERT_FAILED_TOAST; + displayErrorToast(title, [error.message], dispatchToaster); + }, + [dispatchToaster] + ); + + // Catches state change isSelectAllChecked->false upon user selection change to reset utility bar + useEffect(() => { + if (!isSelectAllChecked) { + setShowClearSelectionAction(false); + } else { + setSelectAll(false); + } + }, [isSelectAllChecked]); + + // Callback for when open/closed filter changes + const onFilterGroupChangedCallback = useCallback( + (newFilterGroup: AlertFilterOption) => { + clearEventsLoading!({ id: ALERTS_TABLE_TIMELINE_ID }); + clearEventsDeleted!({ id: ALERTS_TABLE_TIMELINE_ID }); + clearSelected!({ id: ALERTS_TABLE_TIMELINE_ID }); + setFilterGroup(newFilterGroup); + }, + [clearEventsLoading, clearEventsDeleted, clearSelected, setFilterGroup] + ); + + // Callback for clearing entire selection from utility bar + const clearSelectionCallback = useCallback(() => { + clearSelected!({ id: ALERTS_TABLE_TIMELINE_ID }); + setSelectAll(false); + setShowClearSelectionAction(false); + }, [clearSelected, setSelectAll, setShowClearSelectionAction]); + + // Callback for selecting all events on all pages from utility bar + // Dispatches to stateful_body's selectAll via TimelineTypeContext props + // as scope of response data required to actually set selectedEvents + const selectAllCallback = useCallback(() => { + setSelectAll(true); + setShowClearSelectionAction(true); + }, [setSelectAll, setShowClearSelectionAction]); + + const updateAlertsStatusCallback: UpdateAlertsStatusCallback = useCallback( + async (refetchQuery: inputsModel.Refetch, { status }: UpdateAlertsStatusProps) => { + await updateAlertStatusAction({ + query: showClearSelectionAction ? getGlobalQuery()?.filterQuery : undefined, + alertIds: Object.keys(selectedEventIds), + status, + setEventsDeleted: setEventsDeletedCallback, + setEventsLoading: setEventsLoadingCallback, + onAlertStatusUpdateSuccess, + onAlertStatusUpdateFailure, + }); + refetchQuery(); + }, + [ + getGlobalQuery, + selectedEventIds, + setEventsDeletedCallback, + setEventsLoadingCallback, + showClearSelectionAction, + onAlertStatusUpdateSuccess, + onAlertStatusUpdateFailure, + ] + ); + + // Callback for creating the AlertsUtilityBar which receives totalCount from EventsViewer component + const utilityBarCallback = useCallback( + (refetchQuery: inputsModel.Refetch, totalCount: number) => { + return ( + 0} + clearSelection={clearSelectionCallback} + hasIndexWrite={hasIndexWrite} + isFilteredToOpen={filterGroup === FILTER_OPEN} + selectAll={selectAllCallback} + selectedEventIds={selectedEventIds} + showClearSelection={showClearSelectionAction} + totalCount={totalCount} + updateAlertsStatus={updateAlertsStatusCallback.bind(null, refetchQuery)} + /> + ); + }, + [ + canUserCRUD, + hasIndexWrite, + clearSelectionCallback, + filterGroup, + loadingEventIds.length, + selectAllCallback, + selectedEventIds, + showClearSelectionAction, + updateAlertsStatusCallback, + ] + ); + + // Send to Timeline / Update Alert Status Actions for each table row + const additionalActions = useMemo( + () => + getAlertActions({ + apolloClient, + canUserCRUD, + hasIndexWrite, + createTimeline: createTimelineCallback, + setEventsLoading: setEventsLoadingCallback, + setEventsDeleted: setEventsDeletedCallback, + status: filterGroup === FILTER_OPEN ? FILTER_CLOSED : FILTER_OPEN, + updateTimelineIsLoading, + onAlertStatusUpdateSuccess, + onAlertStatusUpdateFailure, + }), + [ + apolloClient, + canUserCRUD, + createTimelineCallback, + hasIndexWrite, + filterGroup, + setEventsLoadingCallback, + setEventsDeletedCallback, + updateTimelineIsLoading, + onAlertStatusUpdateSuccess, + onAlertStatusUpdateFailure, + ] + ); + const defaultIndices = useMemo(() => [signalsIndex], [signalsIndex]); + const defaultFiltersMemo = useMemo(() => { + if (isEmpty(defaultFilters)) { + return filterGroup === FILTER_OPEN ? alertsOpenFilters : alertsClosedFilters; + } else if (defaultFilters != null && !isEmpty(defaultFilters)) { + return [ + ...defaultFilters, + ...(filterGroup === FILTER_OPEN ? alertsOpenFilters : alertsClosedFilters), + ]; + } + }, [defaultFilters, filterGroup]); + const { initializeTimeline, setTimelineRowActions } = useManageTimeline(); + + useEffect(() => { + initializeTimeline({ + id: ALERTS_TABLE_TIMELINE_ID, + documentType: i18n.ALERTS_DOCUMENT_TYPE, + footerText: i18n.TOTAL_COUNT_OF_ALERTS, + loadingText: i18n.LOADING_ALERTS, + title: i18n.ALERTS_TABLE_TITLE, + selectAll: canUserCRUD ? selectAll : false, + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + useEffect(() => { + setTimelineRowActions({ + id: ALERTS_TABLE_TIMELINE_ID, + queryFields: requiredFieldsForActions, + timelineRowActions: additionalActions, + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [additionalActions]); + const headerFilterGroup = useMemo( + () => , + [onFilterGroupChangedCallback] + ); + + if (loading || isEmpty(signalsIndex)) { + return ( + + + + + ); + } + + return ( + + ); +}; + +const makeMapStateToProps = () => { + const getTimeline = timelineSelectors.getTimelineByIdSelector(); + const getGlobalInputs = inputsSelectors.globalSelector(); + const mapStateToProps = (state: State) => { + const timeline: TimelineModel = + getTimeline(state, ALERTS_TABLE_TIMELINE_ID) ?? timelineDefaults; + const { deletedEventIds, isSelectAllChecked, loadingEventIds, selectedEventIds } = timeline; + + const globalInputs: inputsModel.InputsRange = getGlobalInputs(state); + const { query, filters } = globalInputs; + return { + globalQuery: query, + globalFilters: filters, + deletedEventIds, + isSelectAllChecked, + loadingEventIds, + selectedEventIds, + }; + }; + return mapStateToProps; +}; + +const mapDispatchToProps = (dispatch: Dispatch) => ({ + clearSelected: ({ id }: { id: string }) => dispatch(timelineActions.clearSelected({ id })), + setEventsLoading: ({ + id, + eventIds, + isLoading, + }: { + id: string; + eventIds: string[]; + isLoading: boolean; + }) => dispatch(timelineActions.setEventsLoading({ id, eventIds, isLoading })), + clearEventsLoading: ({ id }: { id: string }) => + dispatch(timelineActions.clearEventsLoading({ id })), + setEventsDeleted: ({ + id, + eventIds, + isDeleted, + }: { + id: string; + eventIds: string[]; + isDeleted: boolean; + }) => dispatch(timelineActions.setEventsDeleted({ id, eventIds, isDeleted })), + clearEventsDeleted: ({ id }: { id: string }) => + dispatch(timelineActions.clearEventsDeleted({ id })), + updateTimelineIsLoading: ({ id, isLoading }: { id: string; isLoading: boolean }) => + dispatch(timelineActions.updateIsLoading({ id, isLoading })), + updateTimeline: dispatchUpdateTimeline(dispatch), +}); + +const connector = connect(makeMapStateToProps, mapDispatchToProps); + +type PropsFromRedux = ConnectedProps; + +export const AlertsTable = connector(React.memo(AlertsTableComponent)); diff --git a/x-pack/plugins/security_solution/public/alerts/components/alerts_table/translations.ts b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/translations.ts new file mode 100644 index 0000000000000..07cc28681387d --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/translations.ts @@ -0,0 +1,137 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const PAGE_TITLE = i18n.translate('xpack.securitySolution.detectionEngine.pageTitle', { + defaultMessage: 'Detection engine', +}); + +export const ALERTS_TABLE_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.tableTitle', + { + defaultMessage: 'Alert list', + } +); + +export const ALERTS_DOCUMENT_TYPE = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.documentTypeTitle', + { + defaultMessage: 'Alerts', + } +); + +export const OPEN_ALERTS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.openAlertsTitle', + { + defaultMessage: 'Open alerts', + } +); + +export const CLOSED_ALERTS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.closedAlertsTitle', + { + defaultMessage: 'Closed alerts', + } +); + +export const LOADING_ALERTS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.loadingAlertsTitle', + { + defaultMessage: 'Loading Alerts', + } +); + +export const TOTAL_COUNT_OF_ALERTS = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.totalCountOfAlertsTitle', + { + defaultMessage: 'alerts match the search criteria', + } +); + +export const ALERTS_HEADERS_RULE = i18n.translate( + 'xpack.securitySolution.eventsViewer.alerts.defaultHeaders.ruleTitle', + { + defaultMessage: 'Rule', + } +); + +export const ALERTS_HEADERS_VERSION = i18n.translate( + 'xpack.securitySolution.eventsViewer.alerts.defaultHeaders.versionTitle', + { + defaultMessage: 'Version', + } +); + +export const ALERTS_HEADERS_METHOD = i18n.translate( + 'xpack.securitySolution.eventsViewer.alerts.defaultHeaders.methodTitle', + { + defaultMessage: 'Method', + } +); + +export const ALERTS_HEADERS_SEVERITY = i18n.translate( + 'xpack.securitySolution.eventsViewer.alerts.defaultHeaders.severityTitle', + { + defaultMessage: 'Severity', + } +); + +export const ALERTS_HEADERS_RISK_SCORE = i18n.translate( + 'xpack.securitySolution.eventsViewer.alerts.defaultHeaders.riskScoreTitle', + { + defaultMessage: 'Risk Score', + } +); + +export const ACTION_OPEN_ALERT = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.actions.openAlertTitle', + { + defaultMessage: 'Open alert', + } +); + +export const ACTION_CLOSE_ALERT = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.actions.closeAlertTitle', + { + defaultMessage: 'Close alert', + } +); + +export const ACTION_INVESTIGATE_IN_TIMELINE = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.actions.investigateInTimelineTitle', + { + defaultMessage: 'Investigate in timeline', + } +); + +export const CLOSED_ALERT_SUCCESS_TOAST = (totalAlerts: number) => + i18n.translate('xpack.securitySolution.detectionEngine.alerts.closedAlertSuccessToastMessage', { + values: { totalAlerts }, + defaultMessage: + 'Successfully closed {totalAlerts} {totalAlerts, plural, =1 {alert} other {alerts}}.', + }); + +export const OPENED_ALERT_SUCCESS_TOAST = (totalAlerts: number) => + i18n.translate('xpack.securitySolution.detectionEngine.alerts.openedAlertSuccessToastMessage', { + values: { totalAlerts }, + defaultMessage: + 'Successfully opened {totalAlerts} {totalAlerts, plural, =1 {alert} other {alerts}}.', + }); + +export const CLOSED_ALERT_FAILED_TOAST = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.closedAlertFailedToastMessage', + { + defaultMessage: 'Failed to close alert(s).', + } +); + +export const OPENED_ALERT_FAILED_TOAST = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.openedAlertFailedToastMessage', + { + defaultMessage: 'Failed to open alert(s)', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/alerts_table/types.ts b/x-pack/plugins/security_solution/public/alerts/components/alerts_table/types.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/alerts_table/types.ts rename to x-pack/plugins/security_solution/public/alerts/components/alerts_table/types.ts diff --git a/x-pack/plugins/siem/public/alerts/components/detection_engine_header_page/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/detection_engine_header_page/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/detection_engine_header_page/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/detection_engine_header_page/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/detection_engine_header_page/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/detection_engine_header_page/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/detection_engine_header_page/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/detection_engine_header_page/index.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/detection_engine_header_page/translations.ts b/x-pack/plugins/security_solution/public/alerts/components/detection_engine_header_page/translations.ts new file mode 100644 index 0000000000000..f59be16923805 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/detection_engine_header_page/translations.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const PAGE_BADGE_LABEL = i18n.translate( + 'xpack.securitySolution.detectionEngine.headerPage.pageBadgeLabel', + { + defaultMessage: 'Beta', + } +); + +export const PAGE_BADGE_TOOLTIP = i18n.translate( + 'xpack.securitySolution.detectionEngine.headerPage.pageBadgeTooltip', + { + defaultMessage: + 'Alerts is still in beta. Please help us improve by reporting issues or bugs in the Kibana repo.', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/no_api_integration_callout/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/no_api_integration_callout/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/no_api_integration_callout/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/no_api_integration_callout/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/no_api_integration_callout/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/no_api_integration_callout/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/no_api_integration_callout/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/no_api_integration_callout/index.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/no_api_integration_callout/translations.ts b/x-pack/plugins/security_solution/public/alerts/components/no_api_integration_callout/translations.ts new file mode 100644 index 0000000000000..bc08a13c8b5d1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/no_api_integration_callout/translations.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const NO_API_INTEGRATION_KEY_CALLOUT_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.noApiIntegrationKeyCallOutTitle', + { + defaultMessage: 'API integration key required', + } +); + +export const NO_API_INTEGRATION_KEY_CALLOUT_MSG = i18n.translate( + 'xpack.securitySolution.detectionEngine.noApiIntegrationKeyCallOutMsg', + { + defaultMessage: `A new encryption key is generated for saved objects each time you start Kibana. Without a persistent key, you cannot delete or modify rules after Kibana restarts. To set a persistent key, add the xpack.encryptedSavedObjects.encryptionKey setting with any text value of 32 or more characters to the kibana.yml file.`, + } +); + +export const DISMISS_CALLOUT = i18n.translate( + 'xpack.securitySolution.detectionEngine.dismissNoApiIntegrationKeyButton', + { + defaultMessage: 'Dismiss', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/no_write_alerts_callout/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/no_write_alerts_callout/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/no_write_alerts_callout/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/no_write_alerts_callout/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/no_write_alerts_callout/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/no_write_alerts_callout/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/no_write_alerts_callout/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/no_write_alerts_callout/index.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/no_write_alerts_callout/translations.ts b/x-pack/plugins/security_solution/public/alerts/components/no_write_alerts_callout/translations.ts new file mode 100644 index 0000000000000..d036c422b2fb9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/no_write_alerts_callout/translations.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const NO_WRITE_ALERTS_CALLOUT_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.noWriteAlertsCallOutTitle', + { + defaultMessage: 'Alerts index permissions required', + } +); + +export const NO_WRITE_ALERTS_CALLOUT_MSG = i18n.translate( + 'xpack.securitySolution.detectionEngine.noWriteAlertsCallOutMsg', + { + defaultMessage: + 'You are currently missing the required permissions to update alerts. Please contact your administrator for further assistance.', + } +); + +export const DISMISS_CALLOUT = i18n.translate( + 'xpack.securitySolution.detectionEngine.dismissNoWriteAlertButton', + { + defaultMessage: 'Dismiss', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/accordion_title/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/accordion_title/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/accordion_title/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/accordion_title/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/accordion_title/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/accordion_title/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/accordion_title/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/accordion_title/index.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/add_item_form/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/add_item_form/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/add_item_form/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/add_item_form/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/add_item_form/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/add_item_form/index.tsx new file mode 100644 index 0000000000000..b0098d62cc9e5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/add_item_form/index.tsx @@ -0,0 +1,189 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiButtonEmpty, + EuiButtonIcon, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiFieldText, + EuiSpacer, +} from '@elastic/eui'; +import { isEmpty } from 'lodash/fp'; +import React, { ChangeEvent, useCallback, useEffect, useState, useRef } from 'react'; +import styled from 'styled-components'; + +import * as RuleI18n from '../../../pages/detection_engine/rules/translations'; +import { FieldHook, getFieldValidityAndErrorMessage } from '../../../../shared_imports'; + +interface AddItemProps { + addText: string; + field: FieldHook; + dataTestSubj: string; + idAria: string; + isDisabled: boolean; + validate?: (args: unknown) => boolean; +} + +const MyEuiFormRow = styled(EuiFormRow)` + .euiFormRow__labelWrapper { + .euiText { + padding-right: 32px; + } + } +`; + +export const MyAddItemButton = styled(EuiButtonEmpty)` + margin-top: 4px; + + &.euiButtonEmpty--xSmall { + font-size: 12px; + } + + .euiIcon { + width: 12px; + height: 12px; + } +`; + +MyAddItemButton.defaultProps = { + flush: 'left', + iconType: 'plusInCircle', + size: 'xs', +}; + +export const AddItem = ({ + addText, + dataTestSubj, + field, + idAria, + isDisabled, + validate, +}: AddItemProps) => { + const [showValidation, setShowValidation] = useState(false); + const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field); + const [haveBeenKeyboardDeleted, setHaveBeenKeyboardDeleted] = useState(-1); + + const inputsRef = useRef([]); + + const removeItem = useCallback( + (index: number) => { + const values = field.value as string[]; + const newValues = [...values.slice(0, index), ...values.slice(index + 1)]; + field.setValue(newValues.length === 0 ? [''] : newValues); + inputsRef.current = [ + ...inputsRef.current.slice(0, index), + ...inputsRef.current.slice(index + 1), + ]; + inputsRef.current = inputsRef.current.map((ref, i) => { + if (i >= index && inputsRef.current[index] != null) { + ref.value = 're-render'; + } + return ref; + }); + }, + [field] + ); + + const addItem = useCallback(() => { + const values = field.value as string[]; + field.setValue([...values, '']); + }, [field]); + + const updateItem = useCallback( + (event: ChangeEvent, index: number) => { + event.persist(); + const values = field.value as string[]; + const value = event.target.value; + field.setValue([...values.slice(0, index), value, ...values.slice(index + 1)]); + }, + [field] + ); + + const handleLastInputRef = useCallback( + (index: number, element: HTMLInputElement | null) => { + if (element != null) { + inputsRef.current = [ + ...inputsRef.current.slice(0, index), + element, + ...inputsRef.current.slice(index + 1), + ]; + } + }, + [inputsRef] + ); + + useEffect(() => { + if ( + haveBeenKeyboardDeleted !== -1 && + !isEmpty(inputsRef.current) && + inputsRef.current[haveBeenKeyboardDeleted] != null + ) { + inputsRef.current[haveBeenKeyboardDeleted].focus(); + setHaveBeenKeyboardDeleted(-1); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [haveBeenKeyboardDeleted, inputsRef.current]); + + const values = field.value as string[]; + return ( + + <> + {values.map((item, index) => { + const euiFieldProps = { + disabled: isDisabled, + ...(index === values.length - 1 + ? { inputRef: handleLastInputRef.bind(null, index) } + : {}), + ...((inputsRef.current[index] != null && inputsRef.current[index].value !== item) || + inputsRef.current[index] == null + ? { value: item } + : {}), + isInvalid: validate == null ? false : showValidation && validate(item), + }; + return ( +

+ + + setShowValidation(true)} + onChange={(e) => updateItem(e, index)} + fullWidth + {...euiFieldProps} + /> + + + removeItem(index)} + aria-label={RuleI18n.DELETE} + /> + + + + {values.length - 1 !== index && } +
+ ); + })} + + + {addText} + + + + ); +}; diff --git a/x-pack/plugins/siem/public/alerts/components/rules/all_rules_tables/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/all_rules_tables/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/all_rules_tables/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/all_rules_tables/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/all_rules_tables/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/all_rules_tables/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/all_rules_tables/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/all_rules_tables/index.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/anomaly_threshold_slider/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/anomaly_threshold_slider/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/anomaly_threshold_slider/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/anomaly_threshold_slider/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/anomaly_threshold_slider/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/anomaly_threshold_slider/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/anomaly_threshold_slider/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/anomaly_threshold_slider/index.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/description_step/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/description_step/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/alerts/components/rules/description_step/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/alerts/components/rules/description_step/actions_description.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/actions_description.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/description_step/actions_description.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/description_step/actions_description.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/description_step/assets/list_tree_icon.svg b/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/assets/list_tree_icon.svg similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/description_step/assets/list_tree_icon.svg rename to x-pack/plugins/security_solution/public/alerts/components/rules/description_step/assets/list_tree_icon.svg diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/helpers.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/helpers.test.tsx new file mode 100644 index 0000000000000..b82d1c0a36ab2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/helpers.test.tsx @@ -0,0 +1,407 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { shallow } from 'enzyme'; +import { EuiLoadingSpinner } from '@elastic/eui'; + +import { coreMock } from '../../../../../../../../src/core/public/mocks'; +import { + esFilters, + FilterManager, + UI_SETTINGS, +} from '../../../../../../../../src/plugins/data/public'; +import { SeverityBadge } from '../severity_badge'; + +import * as i18n from './translations'; +import { + isNotEmptyArray, + buildQueryBarDescription, + buildThreatDescription, + buildUnorderedListArrayDescription, + buildStringArrayDescription, + buildSeverityDescription, + buildUrlsDescription, + buildNoteDescription, + buildRuleTypeDescription, +} from './helpers'; +import { ListItems } from './types'; + +const setupMock = coreMock.createSetup(); +const uiSettingsMock = (pinnedByDefault: boolean) => (key: string) => { + switch (key) { + case UI_SETTINGS.FILTERS_PINNED_BY_DEFAULT: + return pinnedByDefault; + default: + throw new Error(`Unexpected uiSettings key in FilterManager mock: ${key}`); + } +}; +setupMock.uiSettings.get.mockImplementation(uiSettingsMock(true)); +const mockFilterManager = new FilterManager(setupMock.uiSettings); + +const mockQueryBar = { + query: 'test query', + filters: [ + { + $state: { + store: esFilters.FilterStateStore.GLOBAL_STATE, + }, + meta: { + alias: null, + disabled: false, + key: 'event.category', + negate: false, + params: { + query: 'file', + }, + type: 'phrase', + }, + query: { + match_phrase: { + 'event.category': 'file', + }, + }, + }, + ], + saved_id: 'test123', +}; + +describe('helpers', () => { + describe('isNotEmptyArray', () => { + test('returns false if empty array', () => { + const result = isNotEmptyArray([]); + expect(result).toBeFalsy(); + }); + + test('returns false if array of empty strings', () => { + const result = isNotEmptyArray(['', '']); + expect(result).toBeFalsy(); + }); + + test('returns true if array of string with space', () => { + const result = isNotEmptyArray([' ']); + expect(result).toBeTruthy(); + }); + + test('returns true if array with at least one non-empty string', () => { + const result = isNotEmptyArray(['', 'abc']); + expect(result).toBeTruthy(); + }); + }); + + describe('buildQueryBarDescription', () => { + test('returns empty array if no filters, query or savedId exist', () => { + const emptyMockQueryBar = { + query: '', + filters: [], + saved_id: '', + }; + const result: ListItems[] = buildQueryBarDescription({ + field: 'queryBar', + filters: emptyMockQueryBar.filters, + filterManager: mockFilterManager, + query: emptyMockQueryBar.query, + savedId: emptyMockQueryBar.saved_id, + }); + expect(result).toEqual([]); + }); + + test('returns expected array of ListItems when filters exists, but no indexPatterns passed in', () => { + const mockQueryBarWithFilters = { + ...mockQueryBar, + query: '', + saved_id: '', + }; + const result: ListItems[] = buildQueryBarDescription({ + field: 'queryBar', + filters: mockQueryBarWithFilters.filters, + filterManager: mockFilterManager, + query: mockQueryBarWithFilters.query, + savedId: mockQueryBarWithFilters.saved_id, + }); + const wrapper = shallow(result[0].description as React.ReactElement); + + expect(result[0].title).toEqual(<>{i18n.FILTERS_LABEL} ); + expect(wrapper.find(EuiLoadingSpinner).exists()).toBeTruthy(); + }); + + test('returns expected array of ListItems when filters AND indexPatterns exist', () => { + const mockQueryBarWithFilters = { + ...mockQueryBar, + query: '', + saved_id: '', + }; + const result: ListItems[] = buildQueryBarDescription({ + field: 'queryBar', + filters: mockQueryBarWithFilters.filters, + filterManager: mockFilterManager, + query: mockQueryBarWithFilters.query, + savedId: mockQueryBarWithFilters.saved_id, + indexPatterns: { fields: [{ name: 'test name', type: 'test type' }], title: 'test title' }, + }); + const wrapper = shallow(result[0].description as React.ReactElement); + const filterLabelComponent = wrapper.find(esFilters.FilterLabel).at(0); + + expect(result[0].title).toEqual(<>{i18n.FILTERS_LABEL} ); + expect(filterLabelComponent.prop('valueLabel')).toEqual('file'); + expect(filterLabelComponent.prop('filter')).toEqual(mockQueryBar.filters[0]); + }); + + test('returns expected array of ListItems when "query.query" exists', () => { + const mockQueryBarWithQuery = { + ...mockQueryBar, + filters: [], + saved_id: '', + }; + const result: ListItems[] = buildQueryBarDescription({ + field: 'queryBar', + filters: mockQueryBarWithQuery.filters, + filterManager: mockFilterManager, + query: mockQueryBarWithQuery.query, + savedId: mockQueryBarWithQuery.saved_id, + }); + expect(result[0].title).toEqual(<>{i18n.QUERY_LABEL} ); + expect(result[0].description).toEqual(<>{mockQueryBarWithQuery.query} ); + }); + + test('returns expected array of ListItems when "savedId" exists', () => { + const mockQueryBarWithSavedId = { + ...mockQueryBar, + query: '', + filters: [], + }; + const result: ListItems[] = buildQueryBarDescription({ + field: 'queryBar', + filters: mockQueryBarWithSavedId.filters, + filterManager: mockFilterManager, + query: mockQueryBarWithSavedId.query, + savedId: mockQueryBarWithSavedId.saved_id, + }); + expect(result[0].title).toEqual(<>{i18n.SAVED_ID_LABEL} ); + expect(result[0].description).toEqual(<>{mockQueryBarWithSavedId.saved_id} ); + }); + }); + + describe('buildThreatDescription', () => { + test('returns empty array if no threats', () => { + const result: ListItems[] = buildThreatDescription({ label: 'Mitre Attack', threat: [] }); + expect(result).toHaveLength(0); + }); + + test('returns empty tactic link if no corresponding tactic id found', () => { + const result: ListItems[] = buildThreatDescription({ + label: 'Mitre Attack', + threat: [ + { + framework: 'MITRE ATTACK', + technique: [{ reference: 'https://test.com', name: 'Audio Capture', id: 'T1123' }], + tactic: { reference: 'https://test.com', name: 'Collection', id: 'TA000999' }, + }, + ], + }); + const wrapper = shallow(result[0].description as React.ReactElement); + expect(result[0].title).toEqual('Mitre Attack'); + expect(wrapper.find('[data-test-subj="threatTacticLink"]').text()).toEqual(''); + expect(wrapper.find('[data-test-subj="threatTechniqueLink"]').text()).toEqual( + 'Audio Capture (T1123)' + ); + }); + + test('returns empty technique link if no corresponding technique id found', () => { + const result: ListItems[] = buildThreatDescription({ + label: 'Mitre Attack', + threat: [ + { + framework: 'MITRE ATTACK', + technique: [{ reference: 'https://test.com', name: 'Audio Capture', id: 'T1123456' }], + tactic: { reference: 'https://test.com', name: 'Collection', id: 'TA0009' }, + }, + ], + }); + const wrapper = shallow(result[0].description as React.ReactElement); + expect(result[0].title).toEqual('Mitre Attack'); + expect(wrapper.find('[data-test-subj="threatTacticLink"]').text()).toEqual( + 'Collection (TA0009)' + ); + expect(wrapper.find('[data-test-subj="threatTechniqueLink"]').text()).toEqual(''); + }); + + test('returns with corresponding tactic and technique link text', () => { + const result: ListItems[] = buildThreatDescription({ + label: 'Mitre Attack', + threat: [ + { + framework: 'MITRE ATTACK', + technique: [{ reference: 'https://test.com', name: 'Audio Capture', id: 'T1123' }], + tactic: { reference: 'https://test.com', name: 'Collection', id: 'TA0009' }, + }, + ], + }); + const wrapper = shallow(result[0].description as React.ReactElement); + expect(result[0].title).toEqual('Mitre Attack'); + expect(wrapper.find('[data-test-subj="threatTacticLink"]').text()).toEqual( + 'Collection (TA0009)' + ); + expect(wrapper.find('[data-test-subj="threatTechniqueLink"]').text()).toEqual( + 'Audio Capture (T1123)' + ); + }); + + test('returns corresponding number of tactic and technique links', () => { + const result: ListItems[] = buildThreatDescription({ + label: 'Mitre Attack', + threat: [ + { + framework: 'MITRE ATTACK', + technique: [ + { reference: 'https://test.com', name: 'Audio Capture', id: 'T1123' }, + { reference: 'https://test.com', name: 'Clipboard Data', id: 'T1115' }, + ], + tactic: { reference: 'https://test.com', name: 'Collection', id: 'TA0009' }, + }, + { + framework: 'MITRE ATTACK', + technique: [ + { reference: 'https://test.com', name: 'Automated Collection', id: 'T1119' }, + ], + tactic: { reference: 'https://test.com', name: 'Discovery', id: 'TA0007' }, + }, + ], + }); + const wrapper = shallow(result[0].description as React.ReactElement); + + expect(wrapper.find('[data-test-subj="threatTacticLink"]')).toHaveLength(2); + expect(wrapper.find('[data-test-subj="threatTechniqueLink"]')).toHaveLength(3); + }); + }); + + describe('buildUnorderedListArrayDescription', () => { + test('returns empty array if "values" is empty array', () => { + const result: ListItems[] = buildUnorderedListArrayDescription( + 'Test label', + 'falsePositives', + [] + ); + expect(result).toHaveLength(0); + }); + + test('returns ListItem with corresponding number of valid values items', () => { + const result: ListItems[] = buildUnorderedListArrayDescription( + 'Test label', + 'falsePositives', + ['', 'falsePositive1', 'falsePositive2'] + ); + const wrapper = shallow(result[0].description as React.ReactElement); + + expect(result[0].title).toEqual('Test label'); + expect(wrapper.find('[data-test-subj="unorderedListArrayDescriptionItem"]')).toHaveLength(2); + }); + }); + + describe('buildStringArrayDescription', () => { + test('returns empty array if "values" is empty array', () => { + const result: ListItems[] = buildStringArrayDescription('Test label', 'tags', []); + expect(result).toHaveLength(0); + }); + + test('returns ListItem with corresponding number of valid values items', () => { + const result: ListItems[] = buildStringArrayDescription('Test label', 'tags', [ + '', + 'tag1', + 'tag2', + ]); + const wrapper = shallow(result[0].description as React.ReactElement); + + expect(result[0].title).toEqual('Test label'); + expect(wrapper.find('[data-test-subj="stringArrayDescriptionBadgeItem"]')).toHaveLength(2); + expect( + wrapper.find('[data-test-subj="stringArrayDescriptionBadgeItem"]').first().text() + ).toEqual('tag1'); + expect( + wrapper.find('[data-test-subj="stringArrayDescriptionBadgeItem"]').at(1).text() + ).toEqual('tag2'); + }); + }); + + describe('buildSeverityDescription', () => { + test('returns ListItem with passed in label and SeverityBadge component', () => { + const result: ListItems[] = buildSeverityDescription('Test label', 'Test description value'); + + expect(result[0].title).toEqual('Test label'); + expect(result[0].description).toEqual(); + }); + }); + + describe('buildUrlsDescription', () => { + test('returns empty array if "values" is empty array', () => { + const result: ListItems[] = buildUrlsDescription('Test label', []); + expect(result).toHaveLength(0); + }); + + test('returns ListItem with corresponding number of valid values items', () => { + const result: ListItems[] = buildUrlsDescription('Test label', [ + 'www.test.com', + 'www.test2.com', + ]); + const wrapper = shallow(result[0].description as React.ReactElement); + + expect(result[0].title).toEqual('Test label'); + expect(wrapper.find('[data-test-subj="urlsDescriptionReferenceLinkItem"]')).toHaveLength(2); + expect( + wrapper.find('[data-test-subj="urlsDescriptionReferenceLinkItem"]').first().text() + ).toEqual('www.test.com'); + expect( + wrapper.find('[data-test-subj="urlsDescriptionReferenceLinkItem"]').at(1).text() + ).toEqual('www.test2.com'); + }); + }); + + describe('buildNoteDescription', () => { + test('returns ListItem with passed in label and note content', () => { + const noteSample = + 'Cras mattism. [Pellentesque](https://elastic.co). ### Malesuada adipiscing tristique'; + const result: ListItems[] = buildNoteDescription('Test label', noteSample); + const wrapper = shallow(result[0].description as React.ReactElement); + const noteElement = wrapper.find('[data-test-subj="noteDescriptionItem"]').at(0); + + expect(result[0].title).toEqual('Test label'); + expect(noteElement.exists()).toBeTruthy(); + expect(noteElement.text()).toEqual(noteSample); + }); + + test('returns empty array if passed in note is empty string', () => { + const result: ListItems[] = buildNoteDescription('Test label', ''); + + expect(result).toHaveLength(0); + }); + }); + + describe('buildRuleTypeDescription', () => { + it('returns the label for a machine_learning type', () => { + const [result]: ListItems[] = buildRuleTypeDescription('Test label', 'machine_learning'); + + expect(result.title).toEqual('Test label'); + }); + + it('returns a humanized description for a machine_learning type', () => { + const [result]: ListItems[] = buildRuleTypeDescription('Test label', 'machine_learning'); + + expect(result.description).toEqual('Machine Learning'); + }); + + it('returns the label for a query type', () => { + const [result]: ListItems[] = buildRuleTypeDescription('Test label', 'query'); + + expect(result.title).toEqual('Test label'); + }); + + it('returns a humanized description for a query type', () => { + const [result]: ListItems[] = buildRuleTypeDescription('Test label', 'query'); + + expect(result.description).toEqual('Query'); + }); + }); +}); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/description_step/helpers.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/helpers.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/description_step/helpers.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/description_step/helpers.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/index.test.tsx new file mode 100644 index 0000000000000..b8f81f6d7e5f7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/index.test.tsx @@ -0,0 +1,476 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React from 'react'; +import { shallow } from 'enzyme'; + +import { + StepRuleDescriptionComponent, + addFilterStateIfNotThere, + buildListItems, + getDescriptionItem, +} from '.'; + +import { + esFilters, + Filter, + FilterManager, + UI_SETTINGS, +} from '../../../../../../../../src/plugins/data/public'; +import { + mockAboutStepRule, + mockDefineStepRule, +} from '../../../pages/detection_engine/rules/all/__mocks__/mock'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { coreMock } from '../../../../../../../../src/core/public/mocks'; +import { DEFAULT_TIMELINE_TITLE } from '../../../../timelines/components/timeline/translations'; +import * as i18n from './translations'; + +import { schema } from '../step_about_rule/schema'; +import { ListItems } from './types'; +import { AboutStepRule } from '../../../pages/detection_engine/rules/types'; + +jest.mock('../../../../common/lib/kibana'); + +describe('description_step', () => { + const setupMock = coreMock.createSetup(); + const uiSettingsMock = (pinnedByDefault: boolean) => (key: string) => { + switch (key) { + case UI_SETTINGS.FILTERS_PINNED_BY_DEFAULT: + return pinnedByDefault; + default: + throw new Error(`Unexpected uiSettings key in FilterManager mock: ${key}`); + } + }; + let mockFilterManager: FilterManager; + let mockAboutStep: AboutStepRule; + + beforeEach(() => { + setupMock.uiSettings.get.mockImplementation(uiSettingsMock(true)); + mockFilterManager = new FilterManager(setupMock.uiSettings); + mockAboutStep = mockAboutStepRule(); + }); + + describe('StepRuleDescriptionComponent', () => { + test('renders correctly against snapshot when columns is "multi"', () => { + const wrapper = shallow( + + ); + expect(wrapper).toMatchSnapshot(); + expect(wrapper.find('[data-test-subj="listItemColumnStepRuleDescription"]')).toHaveLength(2); + }); + + test('renders correctly against snapshot when columns is "single"', () => { + const wrapper = shallow( + + ); + expect(wrapper).toMatchSnapshot(); + expect(wrapper.find('[data-test-subj="listItemColumnStepRuleDescription"]')).toHaveLength(1); + }); + + test('renders correctly against snapshot when columns is "singleSplit', () => { + const wrapper = shallow( + + ); + expect(wrapper).toMatchSnapshot(); + expect(wrapper.find('[data-test-subj="listItemColumnStepRuleDescription"]')).toHaveLength(1); + expect( + wrapper.find('[data-test-subj="singleSplitStepRuleDescriptionList"]').at(0).prop('type') + ).toEqual('column'); + }); + }); + + describe('addFilterStateIfNotThere', () => { + test('it does not change the state if it is global', () => { + const filters: Filter[] = [ + { + $state: { + store: esFilters.FilterStateStore.GLOBAL_STATE, + }, + meta: { + alias: null, + disabled: false, + key: 'event.category', + negate: false, + params: { + query: 'file', + }, + type: 'phrase', + }, + query: { + match_phrase: { + 'event.category': 'file', + }, + }, + }, + { + $state: { + store: esFilters.FilterStateStore.GLOBAL_STATE, + }, + meta: { + alias: null, + disabled: false, + key: 'event.category', + negate: false, + params: { + query: 'file', + }, + type: 'phrase', + }, + query: { + match_phrase: { + 'event.category': 'file', + }, + }, + }, + ]; + const output = addFilterStateIfNotThere(filters); + const expected: Filter[] = [ + { + $state: { + store: esFilters.FilterStateStore.GLOBAL_STATE, + }, + meta: { + alias: null, + disabled: false, + key: 'event.category', + negate: false, + params: { + query: 'file', + }, + type: 'phrase', + }, + query: { + match_phrase: { + 'event.category': 'file', + }, + }, + }, + { + $state: { + store: esFilters.FilterStateStore.GLOBAL_STATE, + }, + meta: { + alias: null, + disabled: false, + key: 'event.category', + negate: false, + params: { + query: 'file', + }, + type: 'phrase', + }, + query: { + match_phrase: { + 'event.category': 'file', + }, + }, + }, + ]; + expect(output).toEqual(expected); + }); + + test('it adds the state if it does not exist as local', () => { + const filters: Filter[] = [ + { + meta: { + alias: null, + disabled: false, + key: 'event.category', + negate: false, + params: { + query: 'file', + }, + type: 'phrase', + }, + query: { + match_phrase: { + 'event.category': 'file', + }, + }, + }, + { + meta: { + alias: null, + disabled: false, + key: 'event.category', + negate: false, + params: { + query: 'file', + }, + type: 'phrase', + }, + query: { + match_phrase: { + 'event.category': 'file', + }, + }, + }, + ]; + const output = addFilterStateIfNotThere(filters); + const expected: Filter[] = [ + { + $state: { + store: esFilters.FilterStateStore.APP_STATE, + }, + meta: { + alias: null, + disabled: false, + key: 'event.category', + negate: false, + params: { + query: 'file', + }, + type: 'phrase', + }, + query: { + match_phrase: { + 'event.category': 'file', + }, + }, + }, + { + $state: { + store: esFilters.FilterStateStore.APP_STATE, + }, + meta: { + alias: null, + disabled: false, + key: 'event.category', + negate: false, + params: { + query: 'file', + }, + type: 'phrase', + }, + query: { + match_phrase: { + 'event.category': 'file', + }, + }, + }, + ]; + expect(output).toEqual(expected); + }); + }); + + describe('buildListItems', () => { + test('returns expected ListItems array when given valid inputs', () => { + const result: ListItems[] = buildListItems(mockAboutStep, schema, mockFilterManager); + + expect(result.length).toEqual(9); + }); + }); + + describe('getDescriptionItem', () => { + test('returns ListItem with all values enumerated when value[field] is an array', () => { + const result: ListItems[] = getDescriptionItem( + 'tags', + 'Tags label', + mockAboutStep, + mockFilterManager + ); + + expect(result[0].title).toEqual('Tags label'); + expect(typeof result[0].description).toEqual('object'); + }); + + test('returns ListItem with description of value[field] when value[field] is a string', () => { + const result: ListItems[] = getDescriptionItem( + 'description', + 'Description label', + mockAboutStep, + mockFilterManager + ); + + expect(result[0].title).toEqual('Description label'); + expect(result[0].description).toEqual('24/7'); + }); + + test('returns empty array when "value" is a non-existant property in "field"', () => { + const result: ListItems[] = getDescriptionItem( + 'jibberjabber', + 'JibberJabber label', + mockAboutStep, + mockFilterManager + ); + + expect(result.length).toEqual(0); + }); + + describe('queryBar', () => { + test('returns array of ListItems when queryBar exist', () => { + const mockQueryBar = { + isNew: false, + queryBar: { + query: { + query: 'user.name: root or user.name: admin', + language: 'kuery', + }, + filters: null, + saved_id: null, + }, + }; + const result: ListItems[] = getDescriptionItem( + 'queryBar', + 'Query bar label', + mockQueryBar, + mockFilterManager + ); + + expect(result[0].title).toEqual(<>{i18n.QUERY_LABEL} ); + expect(result[0].description).toEqual(<>{mockQueryBar.queryBar.query.query} ); + }); + }); + + describe('threat', () => { + test('returns array of ListItems when threat exist', () => { + const result: ListItems[] = getDescriptionItem( + 'threat', + 'Threat label', + mockAboutStep, + mockFilterManager + ); + + expect(result[0].title).toEqual('Threat label'); + expect(React.isValidElement(result[0].description)).toBeTruthy(); + }); + + test('filters out threats with tactic.name of "none"', () => { + const mockStep = { + ...mockAboutStep, + threat: [ + { + framework: 'mockFramework', + tactic: { + id: '1234', + name: 'none', + reference: 'reference1', + }, + technique: [ + { + id: '456', + name: 'technique1', + reference: 'technique reference', + }, + ], + }, + ], + }; + const result: ListItems[] = getDescriptionItem( + 'threat', + 'Threat label', + mockStep, + mockFilterManager + ); + + expect(result.length).toEqual(0); + }); + }); + + describe('references', () => { + test('returns array of ListItems when references exist', () => { + const result: ListItems[] = getDescriptionItem( + 'references', + 'Reference label', + mockAboutStep, + mockFilterManager + ); + + expect(result[0].title).toEqual('Reference label'); + expect(React.isValidElement(result[0].description)).toBeTruthy(); + }); + }); + + describe('falsePositives', () => { + test('returns array of ListItems when falsePositives exist', () => { + const result: ListItems[] = getDescriptionItem( + 'falsePositives', + 'False positives label', + mockAboutStep, + mockFilterManager + ); + + expect(result[0].title).toEqual('False positives label'); + expect(React.isValidElement(result[0].description)).toBeTruthy(); + }); + }); + + describe('severity', () => { + test('returns array of ListItems when severity exist', () => { + const result: ListItems[] = getDescriptionItem( + 'severity', + 'Severity label', + mockAboutStep, + mockFilterManager + ); + + expect(result[0].title).toEqual('Severity label'); + expect(React.isValidElement(result[0].description)).toBeTruthy(); + }); + }); + + describe('riskScore', () => { + test('returns array of ListItems when riskScore exist', () => { + const result: ListItems[] = getDescriptionItem( + 'riskScore', + 'Risk score label', + mockAboutStep, + mockFilterManager + ); + + expect(result[0].title).toEqual('Risk score label'); + expect(result[0].description).toEqual(21); + }); + }); + + describe('timeline', () => { + test('returns timeline title if one exists', () => { + const mockDefineStep = mockDefineStepRule(); + const result: ListItems[] = getDescriptionItem( + 'timeline', + 'Timeline label', + mockDefineStep, + mockFilterManager + ); + + expect(result[0].title).toEqual('Timeline label'); + expect(result[0].description).toEqual('Titled timeline'); + }); + + test('returns default timeline title if none exists', () => { + const mockStep = { + ...mockDefineStepRule(), + timeline: { + id: '12345', + }, + }; + const result: ListItems[] = getDescriptionItem( + 'timeline', + 'Timeline label', + mockStep, + mockFilterManager + ); + + expect(result[0].title).toEqual('Timeline label'); + expect(result[0].description).toEqual(DEFAULT_TIMELINE_TITLE); + }); + }); + + describe('note', () => { + test('returns default "note" description', () => { + const result: ListItems[] = getDescriptionItem( + 'note', + 'Investigation guide', + mockAboutStep, + mockFilterManager + ); + + expect(result[0].title).toEqual('Investigation guide'); + expect(React.isValidElement(result[0].description)).toBeTruthy(); + }); + }); + }); +}); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/description_step/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/description_step/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/description_step/index.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/description_step/ml_job_description.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/ml_job_description.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/description_step/ml_job_description.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/description_step/ml_job_description.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/description_step/ml_job_description.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/ml_job_description.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/description_step/ml_job_description.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/description_step/ml_job_description.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/description_step/throttle_description.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/throttle_description.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/description_step/throttle_description.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/description_step/throttle_description.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/translations.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/translations.tsx new file mode 100644 index 0000000000000..3e639ede7a18b --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/translations.tsx @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const FILTERS_LABEL = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.filtersLabel', + { + defaultMessage: 'Filters', + } +); + +export const QUERY_LABEL = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.QueryLabel', + { + defaultMessage: 'Custom query', + } +); + +export const SAVED_ID_LABEL = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.savedIdLabel', + { + defaultMessage: 'Saved query name', + } +); + +export const ML_TYPE_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.mlRuleTypeDescription', + { + defaultMessage: 'Machine Learning', + } +); + +export const QUERY_TYPE_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.queryRuleTypeDescription', + { + defaultMessage: 'Query', + } +); + +export const ML_JOB_STARTED = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleDescription.mlJobStartedDescription', + { + defaultMessage: 'Started', + } +); + +export const ML_JOB_STOPPED = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleDescription.mlJobStoppedDescription', + { + defaultMessage: 'Stopped', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/description_step/types.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/description_step/types.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/description_step/types.ts rename to x-pack/plugins/security_solution/public/alerts/components/rules/description_step/types.ts diff --git a/x-pack/plugins/siem/public/alerts/components/rules/mitre/helpers.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/mitre/helpers.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/mitre/helpers.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/mitre/helpers.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/mitre/helpers.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/mitre/helpers.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/mitre/helpers.ts rename to x-pack/plugins/security_solution/public/alerts/components/rules/mitre/helpers.ts diff --git a/x-pack/plugins/siem/public/alerts/components/rules/mitre/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/mitre/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/mitre/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/mitre/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/mitre/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/mitre/index.tsx new file mode 100644 index 0000000000000..e898a362c7771 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/mitre/index.tsx @@ -0,0 +1,221 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiButtonIcon, + EuiFormRow, + EuiSuperSelect, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiComboBox, + EuiText, +} from '@elastic/eui'; +import { isEmpty, kebabCase, camelCase } from 'lodash/fp'; +import React, { useCallback, useState } from 'react'; +import styled from 'styled-components'; + +import { tacticsOptions, techniquesOptions } from '../../../mitre/mitre_tactics_techniques'; +import * as Rulei18n from '../../../pages/detection_engine/rules/translations'; +import { FieldHook, getFieldValidityAndErrorMessage } from '../../../../shared_imports'; +import { threatDefault } from '../step_about_rule/default_value'; +import { IMitreEnterpriseAttack } from '../../../pages/detection_engine/rules/types'; +import { MyAddItemButton } from '../add_item_form'; +import { isMitreAttackInvalid } from './helpers'; +import * as i18n from './translations'; + +const MitreContainer = styled.div` + margin-top: 16px; +`; +const MyEuiSuperSelect = styled(EuiSuperSelect)` + width: 280px; +`; +interface AddItemProps { + field: FieldHook; + dataTestSubj: string; + idAria: string; + isDisabled: boolean; +} + +export const AddMitreThreat = ({ field, idAria, isDisabled }: AddItemProps) => { + const [showValidation, setShowValidation] = useState(false); + const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field); + + const removeItem = useCallback( + (index: number) => { + const values = field.value as string[]; + const newValues = [...values.slice(0, index), ...values.slice(index + 1)]; + if (isEmpty(newValues)) { + field.setValue(threatDefault); + } else { + field.setValue(newValues); + } + }, + [field] + ); + + const addItem = useCallback(() => { + const values = field.value as IMitreEnterpriseAttack[]; + if (!isEmpty(values[values.length - 1])) { + field.setValue([ + ...values, + { tactic: { id: 'none', name: 'none', reference: 'none' }, technique: [] }, + ]); + } else { + field.setValue([{ tactic: { id: 'none', name: 'none', reference: 'none' }, technique: [] }]); + } + }, [field]); + + const updateTactic = useCallback( + (index: number, value: string) => { + const values = field.value as IMitreEnterpriseAttack[]; + const { id, reference, name } = tacticsOptions.find((t) => t.value === value) || { + id: '', + name: '', + reference: '', + }; + field.setValue([ + ...values.slice(0, index), + { + ...values[index], + tactic: { id, reference, name }, + technique: [], + }, + ...values.slice(index + 1), + ]); + }, + [field] + ); + + const updateTechniques = useCallback( + (index: number, selectedOptions: unknown[]) => { + field.setValue([ + ...values.slice(0, index), + { + ...values[index], + technique: selectedOptions, + }, + ...values.slice(index + 1), + ]); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [field] + ); + + const values = field.value as IMitreEnterpriseAttack[]; + + const getSelectTactic = (tacticName: string, index: number, disabled: boolean) => ( + {i18n.TACTIC_PLACEHOLDER}, + value: 'none', + disabled, + }, + ] + : []), + ...tacticsOptions.map((t) => ({ + inputDisplay: <>{t.text}, + value: t.value, + disabled, + })), + ]} + aria-label="" + onChange={updateTactic.bind(null, index)} + fullWidth={false} + valueOfSelected={camelCase(tacticName)} + data-test-subj="mitreTactic" + /> + ); + + const getSelectTechniques = (item: IMitreEnterpriseAttack, index: number, disabled: boolean) => { + const invalid = isMitreAttackInvalid(item.tactic.name, item.technique); + const options = techniquesOptions.filter((t) => + t.tactics.includes(kebabCase(item.tactic.name)) + ); + const selectedOptions = item.technique.map((technic) => ({ + ...technic, + label: `${technic.name} (${technic.id})`, // API doesn't allow for label field + })); + + return ( + + + setShowValidation(true)} + /> + {showValidation && invalid && ( + +

{errorMessage}

+
+ )} +
+ + removeItem(index)} + aria-label={Rulei18n.DELETE} + /> + +
+ ); + }; + + return ( + + {values.map((item, index) => ( +
+ + + {index === 0 ? ( + + <>{getSelectTactic(item.tactic.name, index, isDisabled)} + + ) : ( + getSelectTactic(item.tactic.name, index, isDisabled) + )} + + + {index === 0 ? ( + + <>{getSelectTechniques(item, index, isDisabled)} + + ) : ( + getSelectTechniques(item, index, isDisabled) + )} + + + {values.length - 1 !== index && } +
+ ))} + + {i18n.ADD_MITRE_ATTACK} + +
+ ); +}; diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/mitre/translations.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/mitre/translations.ts new file mode 100644 index 0000000000000..704f950cfb4b9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/mitre/translations.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const TACTIC = i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttack.tacticsDescription', + { + defaultMessage: 'tactic', + } +); + +export const TECHNIQUE = i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttack.techniquesDescription', + { + defaultMessage: 'techniques', + } +); + +export const ADD_MITRE_ATTACK = i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttack.addTitle', + { + defaultMessage: 'Add MITRE ATT&CK\\u2122 threat', + } +); + +export const TECHNIQUES_PLACEHOLDER = i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttack.techniquesPlaceHolderDescription', + { + defaultMessage: 'Select techniques ...', + } +); + +export const TACTIC_PLACEHOLDER = i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttack.tacticPlaceHolderDescription', + { + defaultMessage: 'Select tactic ...', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/ml_job_select/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/ml_job_select/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/ml_job_select/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/ml_job_select/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/ml_job_select/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/ml_job_select/index.tsx new file mode 100644 index 0000000000000..cb084d4daa782 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/ml_job_select/index.tsx @@ -0,0 +1,140 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback, useMemo } from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiIcon, + EuiLink, + EuiSuperSelect, + EuiText, +} from '@elastic/eui'; + +import styled from 'styled-components'; +import { isJobStarted } from '../../../../../common/machine_learning/helpers'; +import { FieldHook, getFieldValidityAndErrorMessage } from '../../../../shared_imports'; +import { useSiemJobs } from '../../../../common/components/ml_popover/hooks/use_siem_jobs'; +import { useKibana } from '../../../../common/lib/kibana'; +import { + ML_JOB_SELECT_PLACEHOLDER_TEXT, + ENABLE_ML_JOB_WARNING, +} from '../step_define_rule/translations'; + +const HelpTextWarningContainer = styled.div` + margin-top: 10px; +`; + +const MlJobSelectEuiFlexGroup = styled(EuiFlexGroup)` + margin-bottom: 5px; +`; + +const HelpText: React.FC<{ href: string; showEnableWarning: boolean }> = ({ + href, + showEnableWarning = false, +}) => ( + <> + + + + ), + }} + /> + {showEnableWarning && ( + + + + {ENABLE_ML_JOB_WARNING} + + + )} + +); + +const JobDisplay: React.FC<{ title: string; description: string }> = ({ title, description }) => ( + <> + {title} + +

{description}

+
+ +); + +interface MlJobSelectProps { + describedByIds: string[]; + field: FieldHook; +} + +export const MlJobSelect: React.FC = ({ describedByIds = [], field }) => { + const jobId = field.value as string; + const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field); + const [isLoading, siemJobs] = useSiemJobs(false); + const mlUrl = useKibana().services.application.getUrlForApp('ml'); + const handleJobChange = useCallback( + (machineLearningJobId: string) => { + field.setValue(machineLearningJobId); + }, + [field] + ); + const placeholderOption = { + value: 'placeholder', + inputDisplay: ML_JOB_SELECT_PLACEHOLDER_TEXT, + dropdownDisplay: ML_JOB_SELECT_PLACEHOLDER_TEXT, + disabled: true, + }; + + const jobOptions = siemJobs.map((job) => ({ + value: job.id, + inputDisplay: job.id, + dropdownDisplay: , + })); + + const options = [placeholderOption, ...jobOptions]; + + const isJobRunning = useMemo(() => { + // If the selected job is not found in the list, it means the placeholder is selected + // and so we don't want to show the warning, thus isJobRunning will be true when 'job == null' + const job = siemJobs.find((j) => j.id === jobId); + return job == null || isJobStarted(job.jobState, job.datafeedState); + }, [siemJobs, jobId]); + + return ( + + + } + isInvalid={isInvalid} + error={errorMessage} + data-test-subj="mlJobSelect" + describedByIds={describedByIds} + > + + + + + + + + + ); +}; diff --git a/x-pack/plugins/siem/public/alerts/components/rules/next_step/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/alerts/components/rules/next_step/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/next_step/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/alerts/components/rules/next_step/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/alerts/components/rules/next_step/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/next_step/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/next_step/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/next_step/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/next_step/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/next_step/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/next_step/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/next_step/index.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/optional_field_label/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/optional_field_label/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/optional_field_label/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/optional_field_label/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/optional_field_label/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/optional_field_label/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/optional_field_label/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/optional_field_label/index.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/pick_timeline/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/pick_timeline/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/pick_timeline/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/pick_timeline/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/pick_timeline/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/pick_timeline/index.tsx new file mode 100644 index 0000000000000..4b27daf3180ec --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/pick_timeline/index.tsx @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiFormRow } from '@elastic/eui'; +import React, { useCallback, useEffect, useState } from 'react'; + +import { SearchTimelineSuperSelect } from '../../../../timelines/components/timeline/search_super_select'; +import { FieldHook, getFieldValidityAndErrorMessage } from '../../../../shared_imports'; + +export interface FieldValueTimeline { + id: string | null; + title: string | null; +} + +interface QueryBarDefineRuleProps { + dataTestSubj: string; + field: FieldHook; + idAria: string; + isDisabled: boolean; +} + +export const PickTimeline = ({ + dataTestSubj, + field, + idAria, + isDisabled = false, +}: QueryBarDefineRuleProps) => { + const [timelineId, setTimelineId] = useState(null); + const [timelineTitle, setTimelineTitle] = useState(null); + + const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field); + + useEffect(() => { + const { id, title } = field.value as FieldValueTimeline; + if (timelineTitle !== title && timelineId !== id) { + setTimelineId(id); + setTimelineTitle(title); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [field.value]); + + const handleOnTimelineChange = useCallback( + (title: string, id: string | null) => { + if (id === null) { + field.setValue({ id, title: null }); + } else if (timelineTitle !== title && timelineId !== id) { + field.setValue({ id, title }); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [field] + ); + + return ( + + + + ); +}; diff --git a/x-pack/plugins/siem/public/alerts/components/rules/pre_packaged_rules/load_empty_prompt.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/pre_packaged_rules/load_empty_prompt.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/pre_packaged_rules/load_empty_prompt.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/pre_packaged_rules/load_empty_prompt.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/pre_packaged_rules/load_empty_prompt.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/pre_packaged_rules/load_empty_prompt.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/pre_packaged_rules/load_empty_prompt.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/pre_packaged_rules/load_empty_prompt.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/pre_packaged_rules/translations.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/pre_packaged_rules/translations.ts new file mode 100644 index 0000000000000..b43ef8c615003 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/pre_packaged_rules/translations.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const PRE_BUILT_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.prePackagedRules.emptyPromptTitle', + { + defaultMessage: 'Load Elastic prebuilt detection rules', + } +); + +export const PRE_BUILT_MSG = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.prePackagedRules.emptyPromptMessage', + { + defaultMessage: + 'Elastic SIEM comes with prebuilt detection rules that run in the background and create alerts when their conditions are met. By default, all prebuilt rules are disabled and you select which rules you want to activate.', + } +); + +export const PRE_BUILT_ACTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.prePackagedRules.loadPreBuiltButton', + { + defaultMessage: 'Load prebuilt detection rules', + } +); + +export const CREATE_RULE_ACTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.prePackagedRules.createOwnRuletButton', + { + defaultMessage: 'Create your own rules', + } +); + +export const UPDATE_PREPACKAGED_RULES_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesTitle', + { + defaultMessage: 'Update available for Elastic prebuilt rules', + } +); + +export const UPDATE_PREPACKAGED_RULES_MSG = (updateRules: number) => + i18n.translate('xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesMsg', { + values: { updateRules }, + defaultMessage: + 'You can update {updateRules} Elastic prebuilt {updateRules, plural, =1 {rule} other {rules}}. Note that this will reload deleted Elastic prebuilt rules.', + }); + +export const UPDATE_PREPACKAGED_RULES = (updateRules: number) => + i18n.translate('xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesButton', { + values: { updateRules }, + defaultMessage: + 'Update {updateRules} Elastic prebuilt {updateRules, plural, =1 {rule} other {rules}} ', + }); + +export const RELEASE_NOTES_HELP = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.releaseNotesHelp', + { + defaultMessage: 'Release notes', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/pre_packaged_rules/update_callout.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/pre_packaged_rules/update_callout.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/pre_packaged_rules/update_callout.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/pre_packaged_rules/update_callout.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/pre_packaged_rules/update_callout.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/pre_packaged_rules/update_callout.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/pre_packaged_rules/update_callout.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/pre_packaged_rules/update_callout.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/query_bar/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/query_bar/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/query_bar/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/query_bar/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/query_bar/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/query_bar/index.tsx new file mode 100644 index 0000000000000..c53a9ccc22d8b --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/query_bar/index.tsx @@ -0,0 +1,287 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiFormRow, EuiMutationObserver } from '@elastic/eui'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { Subscription } from 'rxjs'; +import styled from 'styled-components'; +import deepEqual from 'fast-deep-equal'; + +import { + Filter, + IIndexPattern, + Query, + FilterManager, + SavedQuery, +} from '../../../../../../../../src/plugins/data/public'; + +import { BrowserFields } from '../../../../common/containers/source'; +import { OpenTimelineModal } from '../../../../timelines/components/open_timeline/open_timeline_modal'; +import { ActionTimelineToShow } from '../../../../timelines/components/open_timeline/types'; +import { QueryBar } from '../../../../common/components/query_bar'; +import { buildGlobalQuery } from '../../../../timelines/components/timeline/helpers'; +import { getDataProviderFilter } from '../../../../timelines/components/timeline/query_bar'; +import { convertKueryToElasticSearchQuery } from '../../../../common/lib/keury'; +import { useKibana } from '../../../../common/lib/kibana'; +import { TimelineModel } from '../../../../timelines/store/timeline/model'; +import { useSavedQueryServices } from '../../../../common/utils/saved_query_services'; +import { FieldHook, getFieldValidityAndErrorMessage } from '../../../../shared_imports'; +import * as i18n from './translations'; + +export interface FieldValueQueryBar { + filters: Filter[]; + query: Query; + saved_id?: string; +} +interface QueryBarDefineRuleProps { + browserFields: BrowserFields; + dataTestSubj: string; + field: FieldHook; + idAria: string; + isLoading: boolean; + indexPattern: IIndexPattern; + onCloseTimelineSearch: () => void; + openTimelineSearch: boolean; + resizeParentContainer?: (height: number) => void; +} + +const StyledEuiFormRow = styled(EuiFormRow)` + .kbnTypeahead__items { + max-height: 45vh !important; + } + .globalQueryBar { + padding: 4px 0px 0px 0px; + .kbnQueryBar { + & > div:first-child { + margin: 0px 0px 0px 4px; + } + } + } +`; + +// TODO need to add disabled in the SearchBar + +export const QueryBarDefineRule = ({ + browserFields, + dataTestSubj, + field, + idAria, + indexPattern, + isLoading = false, + onCloseTimelineSearch, + openTimelineSearch = false, + resizeParentContainer, +}: QueryBarDefineRuleProps) => { + const [originalHeight, setOriginalHeight] = useState(-1); + const [loadingTimeline, setLoadingTimeline] = useState(false); + const [savedQuery, setSavedQuery] = useState(null); + const [queryDraft, setQueryDraft] = useState({ query: '', language: 'kuery' }); + const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field); + + const kibana = useKibana(); + const [filterManager] = useState(new FilterManager(kibana.services.uiSettings)); + + const savedQueryServices = useSavedQueryServices(); + + useEffect(() => { + let isSubscribed = true; + const subscriptions = new Subscription(); + filterManager.setFilters([]); + + subscriptions.add( + filterManager.getUpdates$().subscribe({ + next: () => { + if (isSubscribed) { + const newFilters = filterManager.getFilters(); + const { filters } = field.value as FieldValueQueryBar; + + if (!deepEqual(filters, newFilters)) { + field.setValue({ ...(field.value as FieldValueQueryBar), filters: newFilters }); + } + } + }, + }) + ); + + return () => { + isSubscribed = false; + subscriptions.unsubscribe(); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [field.value]); + + useEffect(() => { + let isSubscribed = true; + async function updateFilterQueryFromValue() { + const { filters, query, saved_id: savedId } = field.value as FieldValueQueryBar; + if (!deepEqual(query, queryDraft)) { + setQueryDraft(query); + } + if (!deepEqual(filters, filterManager.getFilters())) { + filterManager.setFilters(filters); + } + if ( + (savedId != null && savedQuery != null && savedId !== savedQuery.id) || + (savedId != null && savedQuery == null) + ) { + try { + const mySavedQuery = await savedQueryServices.getSavedQuery(savedId); + if (isSubscribed && mySavedQuery != null) { + setSavedQuery(mySavedQuery); + } + } catch { + setSavedQuery(null); + } + } else if (savedId == null && savedQuery != null) { + setSavedQuery(null); + } + } + updateFilterQueryFromValue(); + return () => { + isSubscribed = false; + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [field.value]); + + const onSubmitQuery = useCallback( + (newQuery: Query) => { + const { query } = field.value as FieldValueQueryBar; + if (!deepEqual(query, newQuery)) { + field.setValue({ ...(field.value as FieldValueQueryBar), query: newQuery }); + } + }, + [field] + ); + + const onChangedQuery = useCallback( + (newQuery: Query) => { + const { query } = field.value as FieldValueQueryBar; + if (!deepEqual(query, newQuery)) { + field.setValue({ ...(field.value as FieldValueQueryBar), query: newQuery }); + } + }, + [field] + ); + + const onSavedQuery = useCallback( + (newSavedQuery: SavedQuery | null) => { + if (newSavedQuery != null) { + const { saved_id: savedId } = field.value as FieldValueQueryBar; + if (newSavedQuery.id !== savedId) { + setSavedQuery(newSavedQuery); + field.setValue({ + filters: newSavedQuery.attributes.filters, + query: newSavedQuery.attributes.query, + saved_id: newSavedQuery.id, + }); + } + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [field.value] + ); + + const onCloseTimelineModal = useCallback(() => { + setLoadingTimeline(true); + onCloseTimelineSearch(); + }, [onCloseTimelineSearch]); + + const onOpenTimeline = useCallback( + (timeline: TimelineModel) => { + setLoadingTimeline(false); + const newQuery = { + query: timeline.kqlQuery.filterQuery?.kuery?.expression ?? '', + language: timeline.kqlQuery.filterQuery?.kuery?.kind ?? 'kuery', + }; + const dataProvidersDsl = + timeline.dataProviders != null && timeline.dataProviders.length > 0 + ? convertKueryToElasticSearchQuery( + buildGlobalQuery(timeline.dataProviders, browserFields), + indexPattern + ) + : ''; + const newFilters = timeline.filters ?? []; + field.setValue({ + filters: + dataProvidersDsl !== '' + ? [...newFilters, getDataProviderFilter(dataProvidersDsl)] + : newFilters, + query: newQuery, + saved_id: undefined, + }); + }, + [browserFields, field, indexPattern] + ); + + const onMutation = () => { + if (resizeParentContainer != null) { + const suggestionContainer = document.getElementById('kbnTypeahead__items'); + if (suggestionContainer != null) { + const box = suggestionContainer.getBoundingClientRect(); + const accordionContainer = document.getElementById('define-rule'); + if (accordionContainer != null) { + const accordionBox = accordionContainer.getBoundingClientRect(); + if (originalHeight === -1 || accordionBox.height < originalHeight + box.height) { + resizeParentContainer(originalHeight + box.height - 100); + } + if (originalHeight === -1) { + setOriginalHeight(accordionBox.height); + } + } + } else { + resizeParentContainer(-1); + } + } + }; + + const actionTimelineToHide = useMemo(() => ['duplicate'], []); + + return ( + <> + + + {(mutationRef) => ( +
+ +
+ )} +
+
+ {openTimelineSearch ? ( + + ) : null} + + ); +}; diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/query_bar/translations.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/query_bar/translations.tsx new file mode 100644 index 0000000000000..756b0c05f435a --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/query_bar/translations.tsx @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const IMPORT_TIMELINE_MODAL = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.importTimelineModalTitle', + { + defaultMessage: 'Import query from saved timeline', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/read_only_callout/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/read_only_callout/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/read_only_callout/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/read_only_callout/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/read_only_callout/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/read_only_callout/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/read_only_callout/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/read_only_callout/index.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/read_only_callout/translations.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/read_only_callout/translations.ts new file mode 100644 index 0000000000000..26b6bb83a145d --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/read_only_callout/translations.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const READ_ONLY_CALLOUT_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.readOnlyCallOutTitle', + { + defaultMessage: 'Rule permissions required', + } +); + +export const READ_ONLY_CALLOUT_MSG = i18n.translate( + 'xpack.securitySolution.detectionEngine.readOnlyCallOutMsg', + { + defaultMessage: + 'You are currently missing the required permissions to create/edit detection engine rule. Please contact your administrator for further assistance.', + } +); + +export const DISMISS_CALLOUT = i18n.translate( + 'xpack.securitySolution.detectionEngine.dismissButton', + { + defaultMessage: 'Dismiss', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/rule_actions_field/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/rule_actions_field/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/index.tsx new file mode 100644 index 0000000000000..c6ff25f311d9c --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/index.tsx @@ -0,0 +1,143 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { isEmpty } from 'lodash/fp'; +import { EuiSpacer, EuiCallOut } from '@elastic/eui'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import deepMerge from 'deepmerge'; +import ReactMarkdown from 'react-markdown'; +import styled from 'styled-components'; + +import { NOTIFICATION_SUPPORTED_ACTION_TYPES_IDS } from '../../../../../common/constants'; +import { SelectField } from '../../../../shared_imports'; +import { + ActionForm, + ActionType, + loadActionTypes, +} from '../../../../../../triggers_actions_ui/public'; +import { AlertAction } from '../../../../../../alerts/common'; +import { useKibana } from '../../../../common/lib/kibana'; +import { FORM_ERRORS_TITLE } from './translations'; + +type ThrottleSelectField = typeof SelectField; + +const DEFAULT_ACTION_GROUP_ID = 'default'; +const DEFAULT_ACTION_MESSAGE = + 'Rule {{context.rule.name}} generated {{state.signals_count}} alerts'; + +const FieldErrorsContainer = styled.div` + p { + margin-bottom: 0; + } +`; + +export const RuleActionsField: ThrottleSelectField = ({ field, messageVariables }) => { + const [fieldErrors, setFieldErrors] = useState(null); + const [supportedActionTypes, setSupportedActionTypes] = useState(); + const { + http, + triggers_actions_ui: { actionTypeRegistry }, + notifications, + docLinks, + application: { capabilities }, + } = useKibana().services; + + const actions: AlertAction[] = useMemo( + () => (!isEmpty(field.value) ? (field.value as AlertAction[]) : []), + [field.value] + ); + + const setActionIdByIndex = useCallback( + (id: string, index: number) => { + const updatedActions = [...(actions as Array>)]; + updatedActions[index] = deepMerge(updatedActions[index], { id }); + field.setValue(updatedActions); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [field.setValue, actions] + ); + + const setAlertProperty = useCallback( + (updatedActions: AlertAction[]) => field.setValue(updatedActions), + [field] + ); + + const setActionParamsProperty = useCallback( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (key: string, value: any, index: number) => { + const updatedActions = [...actions]; + updatedActions[index].params[key] = value; + field.setValue(updatedActions); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [field.setValue, actions] + ); + + useEffect(() => { + (async function () { + const actionTypes = await loadActionTypes({ http }); + const supportedTypes = actionTypes.filter((actionType) => + NOTIFICATION_SUPPORTED_ACTION_TYPES_IDS.includes(actionType.id) + ); + setSupportedActionTypes(supportedTypes); + })(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + if (field.form.isSubmitting || !field.errors.length) { + return setFieldErrors(null); + } + if ( + field.form.isSubmitted && + !field.form.isSubmitting && + field.form.isValid === false && + field.errors.length + ) { + const errorsString = field.errors.map(({ message }) => message).join('\n'); + return setFieldErrors(errorsString); + } + }, [ + field.form.isSubmitted, + field.form.isSubmitting, + field.isChangingValue, + field.form.isValid, + field.errors, + setFieldErrors, + ]); + + if (!supportedActionTypes) return <>; + + return ( + <> + {fieldErrors ? ( + <> + + + + + + + + ) : null} + + + ); +}; diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/translations.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/translations.tsx new file mode 100644 index 0000000000000..8e467307cb6da --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/translations.tsx @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const FORM_ERRORS_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.ruleActionsField.ruleActionsFormErrorsTitle', + { + defaultMessage: 'Please fix issues listed below', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/rule_actions_overflow/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_overflow/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/rule_actions_overflow/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_overflow/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/alerts/components/rules/rule_actions_overflow/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_overflow/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/rule_actions_overflow/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_overflow/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_overflow/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_overflow/index.tsx new file mode 100644 index 0000000000000..66f04c9bc6add --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_overflow/index.tsx @@ -0,0 +1,159 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiButtonIcon, + EuiContextMenuItem, + EuiContextMenuPanel, + EuiPopover, + EuiToolTip, +} from '@elastic/eui'; +import React, { useCallback, useMemo, useState } from 'react'; +import styled from 'styled-components'; + +import { noop } from 'lodash/fp'; +import { useHistory } from 'react-router-dom'; +import { Rule, exportRules } from '../../../../alerts/containers/detection_engine/rules'; +import * as i18n from './translations'; +import * as i18nActions from '../../../pages/detection_engine/rules/translations'; +import { displaySuccessToast, useStateToaster } from '../../../../common/components/toasters'; +import { + deleteRulesAction, + duplicateRulesAction, +} from '../../../pages/detection_engine/rules/all/actions'; +import { GenericDownloader } from '../../../../common/components/generic_downloader'; +import { DETECTION_ENGINE_PAGE_NAME } from '../../../../common/components/link_to/redirect_to_detection_engine'; + +const MyEuiButtonIcon = styled(EuiButtonIcon)` + &.euiButtonIcon { + svg { + transform: rotate(90deg); + } + border: 1px solid  ${({ theme }) => theme.euiColorPrimary}; + width: 40px; + height: 40px; + } +`; + +interface RuleActionsOverflowComponentProps { + rule: Rule | null; + userHasNoPermissions: boolean; +} + +/** + * Overflow Actions for a Rule + */ +const RuleActionsOverflowComponent = ({ + rule, + userHasNoPermissions, +}: RuleActionsOverflowComponentProps) => { + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const [rulesToExport, setRulesToExport] = useState([]); + const history = useHistory(); + const [, dispatchToaster] = useStateToaster(); + + const onRuleDeletedCallback = useCallback(() => { + history.push(`/${DETECTION_ENGINE_PAGE_NAME}/rules`); + }, [history]); + + const actions = useMemo( + () => + rule != null + ? [ + { + setIsPopoverOpen(false); + await duplicateRulesAction([rule], [rule.id], noop, dispatchToaster); + }} + > + {i18nActions.DUPLICATE_RULE} + , + { + setIsPopoverOpen(false); + setRulesToExport([rule.rule_id]); + }} + > + {i18nActions.EXPORT_RULE} + , + { + setIsPopoverOpen(false); + await deleteRulesAction([rule.id], noop, dispatchToaster, onRuleDeletedCallback); + }} + > + {i18nActions.DELETE_RULE} + , + ] + : [], + // eslint-disable-next-line react-hooks/exhaustive-deps + [rule, userHasNoPermissions] + ); + + const handlePopoverOpen = useCallback(() => { + setIsPopoverOpen(!isPopoverOpen); + }, [setIsPopoverOpen, isPopoverOpen]); + + const button = useMemo( + () => ( + + + + ), + [handlePopoverOpen, userHasNoPermissions] + ); + + return ( + <> + setIsPopoverOpen(false)} + id="ruleActionsOverflow" + isOpen={isPopoverOpen} + data-test-subj="rules-details-popover" + ownFocus={true} + panelPaddingSize="none" + > + + + { + displaySuccessToast( + i18nActions.SUCCESSFULLY_EXPORTED_RULES(exportCount), + dispatchToaster + ); + }} + /> + + ); +}; + +export const RuleActionsOverflow = React.memo(RuleActionsOverflowComponent); + +RuleActionsOverflow.displayName = 'RuleActionsOverflow'; diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_overflow/translations.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_overflow/translations.ts new file mode 100644 index 0000000000000..862d78936e9d5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_overflow/translations.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const ALL_ACTIONS = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.components.ruleActionsOverflow.allActionsTitle', + { + defaultMessage: 'All actions', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/rule_status/helpers.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_status/helpers.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/rule_status/helpers.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/rule_status/helpers.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/rule_status/helpers.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_status/helpers.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/rule_status/helpers.ts rename to x-pack/plugins/security_solution/public/alerts/components/rules/rule_status/helpers.ts diff --git a/x-pack/plugins/siem/public/alerts/components/rules/rule_status/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_status/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/rule_status/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/rule_status/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/rule_status/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_status/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/rule_status/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/rule_status/index.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/rule_status/translations.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_status/translations.ts new file mode 100644 index 0000000000000..30a352a83a324 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_status/translations.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const STATUS = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleStatus.statusDescription', + { + defaultMessage: 'Last response', + } +); + +export const STATUS_AT = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleStatus.statusAtDescription', + { + defaultMessage: 'at', + } +); + +export const STATUS_DATE = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleStatus.statusDateDescription', + { + defaultMessage: 'Status date', + } +); + +export const REFRESH = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleStatus.refreshButton', + { + defaultMessage: 'Refresh', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/rule_switch/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_switch/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/rule_switch/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/alerts/components/rules/rule_switch/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/alerts/components/rules/rule_switch/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_switch/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/rule_switch/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/rule_switch/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/rule_switch/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_switch/index.tsx new file mode 100644 index 0000000000000..c85676ce51052 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_switch/index.tsx @@ -0,0 +1,137 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiFlexGroup, + EuiFlexItem, + EuiLoadingSpinner, + EuiSwitch, + EuiSwitchEvent, +} from '@elastic/eui'; +import { isEmpty } from 'lodash/fp'; +import styled from 'styled-components'; +import React, { useCallback, useState, useEffect } from 'react'; + +import * as i18n from '../../../pages/detection_engine/rules/translations'; +import { enableRules } from '../../../../alerts/containers/detection_engine/rules'; +import { enableRulesAction } from '../../../pages/detection_engine/rules/all/actions'; +import { Action } from '../../../pages/detection_engine/rules/all/reducer'; +import { useStateToaster, displayErrorToast } from '../../../../common/components/toasters'; +import { bucketRulesResponse } from '../../../pages/detection_engine/rules/all/helpers'; + +const StaticSwitch = styled(EuiSwitch)` + .euiSwitch__thumb, + .euiSwitch__icon { + transition: none; + } +`; + +StaticSwitch.displayName = 'StaticSwitch'; + +export interface RuleSwitchProps { + dispatch?: React.Dispatch; + id: string; + enabled: boolean; + isDisabled?: boolean; + isLoading?: boolean; + optionLabel?: string; + onChange?: (enabled: boolean) => void; +} + +/** + * Basic switch component for displaying loader when enabled/disabled + */ +export const RuleSwitchComponent = ({ + dispatch, + id, + isDisabled, + isLoading, + enabled, + optionLabel, + onChange, +}: RuleSwitchProps) => { + const [myIsLoading, setMyIsLoading] = useState(false); + const [myEnabled, setMyEnabled] = useState(enabled ?? false); + const [, dispatchToaster] = useStateToaster(); + + const onRuleStateChange = useCallback( + async (event: EuiSwitchEvent) => { + setMyIsLoading(true); + if (dispatch != null) { + await enableRulesAction([id], event.target.checked!, dispatch, dispatchToaster); + } else { + try { + const enabling = event.target.checked!; + const response = await enableRules({ + ids: [id], + enabled: enabling, + }); + const { rules, errors } = bucketRulesResponse(response); + + if (errors.length > 0) { + setMyIsLoading(false); + const title = enabling + ? i18n.BATCH_ACTION_ACTIVATE_SELECTED_ERROR(1) + : i18n.BATCH_ACTION_DEACTIVATE_SELECTED_ERROR(1); + displayErrorToast( + title, + errors.map((e) => e.error.message), + dispatchToaster + ); + } else { + const [rule] = rules; + setMyEnabled(rule.enabled); + if (onChange != null) { + onChange(rule.enabled); + } + } + } catch { + setMyIsLoading(false); + } + } + setMyIsLoading(false); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [dispatch, id] + ); + + useEffect(() => { + if (myEnabled !== enabled) { + setMyEnabled(enabled); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [enabled]); + + useEffect(() => { + if (myIsLoading !== isLoading) { + setMyIsLoading(isLoading ?? false); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isLoading]); + + return ( + + + {myIsLoading ? ( + + ) : ( + + )} + + + ); +}; + +export const RuleSwitch = React.memo(RuleSwitchComponent); + +RuleSwitch.displayName = 'RuleSwitch'; diff --git a/x-pack/plugins/siem/public/alerts/components/rules/schedule_item_form/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/schedule_item_form/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/schedule_item_form/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/schedule_item_form/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/schedule_item_form/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/schedule_item_form/index.tsx new file mode 100644 index 0000000000000..bb33767f4f5d5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/schedule_item_form/index.tsx @@ -0,0 +1,166 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiFlexGroup, + EuiFlexItem, + EuiFieldNumber, + EuiFormRow, + EuiSelect, + EuiFormControlLayout, +} from '@elastic/eui'; +import { isEmpty } from 'lodash/fp'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import styled from 'styled-components'; + +import { FieldHook, getFieldValidityAndErrorMessage } from '../../../../shared_imports'; + +import * as I18n from './translations'; + +interface ScheduleItemProps { + field: FieldHook; + dataTestSubj: string; + idAria: string; + isDisabled: boolean; + minimumValue?: number; +} + +const timeTypeOptions = [ + { value: 's', text: I18n.SECONDS }, + { value: 'm', text: I18n.MINUTES }, + { value: 'h', text: I18n.HOURS }, +]; + +// move optional label to the end of input +const StyledLabelAppend = styled(EuiFlexItem)` + &.euiFlexItem.euiFlexItem--flexGrowZero { + margin-left: 31px; + } +`; + +const StyledEuiFormRow = styled(EuiFormRow)` + max-width: none; + + .euiFormControlLayout { + max-width: 200px !important; + } + + .euiFormControlLayout__childrenWrapper > *:first-child { + box-shadow: none; + height: 38px; + } + + .euiFormControlLayout:not(:first-child) { + border-left: 1px solid ${({ theme }) => theme.eui.euiColorLightShade}; + } +`; + +const MyEuiSelect = styled(EuiSelect)` + width: auto; +`; + +export const ScheduleItem = ({ + dataTestSubj, + field, + idAria, + isDisabled, + minimumValue = 0, +}: ScheduleItemProps) => { + const [timeType, setTimeType] = useState('s'); + const [timeVal, setTimeVal] = useState(0); + const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field); + + const onChangeTimeType = useCallback( + (e) => { + setTimeType(e.target.value); + field.setValue(`${timeVal}${e.target.value}`); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [timeVal] + ); + + const onChangeTimeVal = useCallback( + (e) => { + const sanitizedValue: number = parseInt(e.target.value, 10); + setTimeVal(sanitizedValue); + field.setValue(`${sanitizedValue}${timeType}`); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [timeType] + ); + + useEffect(() => { + if (field.value !== `${timeVal}${timeType}`) { + const filterTimeVal = (field.value as string).match(/\d+/g); + const filterTimeType = (field.value as string).match(/[a-zA-Z]+/g); + if ( + !isEmpty(filterTimeVal) && + filterTimeVal != null && + !isNaN(Number(filterTimeVal[0])) && + Number(filterTimeVal[0]) !== Number(timeVal) + ) { + setTimeVal(Number(filterTimeVal[0])); + } + if ( + !isEmpty(filterTimeType) && + filterTimeType != null && + ['s', 'm', 'h'].includes(filterTimeType[0]) && + filterTimeType[0] !== timeType + ) { + setTimeType(filterTimeType[0]); + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [field.value]); + + // EUI missing some props + const rest = { disabled: isDisabled }; + const label = useMemo( + () => ( + + + {field.label} + + + {field.labelAppend} + + + ), + [field.label, field.labelAppend] + ); + + return ( + + + } + > + + + + ); +}; diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/schedule_item_form/translations.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/schedule_item_form/translations.ts new file mode 100644 index 0000000000000..66bc6ea900925 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/schedule_item_form/translations.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const SECONDS = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepScheduleRuleForm.secondsOptionDescription', + { + defaultMessage: 'Seconds', + } +); + +export const MINUTES = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepScheduleRuleForm.minutesOptionDescription', + { + defaultMessage: 'Minutes', + } +); + +export const HOURS = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepScheduleRuleForm.hoursOptionDescription', + { + defaultMessage: 'Hours', + } +); + +export const INVALID_TIME = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepScheduleRuleForm.invalidTimeMessageDescription', + { + defaultMessage: 'A time is required.', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/select_rule_type/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/select_rule_type/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/select_rule_type/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/select_rule_type/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/select_rule_type/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/select_rule_type/index.tsx new file mode 100644 index 0000000000000..3dad53f532a5b --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/select_rule_type/index.tsx @@ -0,0 +1,123 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback } from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { + EuiCard, + EuiFlexGrid, + EuiFlexItem, + EuiFormRow, + EuiIcon, + EuiLink, + EuiText, +} from '@elastic/eui'; + +import { isMlRule } from '../../../../../common/machine_learning/helpers'; +import { RuleType } from '../../../../../common/detection_engine/types'; +import { FieldHook } from '../../../../shared_imports'; +import { useKibana } from '../../../../common/lib/kibana'; +import * as i18n from './translations'; + +const MlCardDescription = ({ + subscriptionUrl, + hasValidLicense = false, +}: { + subscriptionUrl: string; + hasValidLicense?: boolean; +}) => ( + + {hasValidLicense ? ( + i18n.ML_TYPE_DESCRIPTION + ) : ( + + + + ), + }} + /> + )} + +); + +interface SelectRuleTypeProps { + describedByIds?: string[]; + field: FieldHook; + hasValidLicense?: boolean; + isMlAdmin?: boolean; + isReadOnly?: boolean; +} + +export const SelectRuleType: React.FC = ({ + describedByIds = [], + field, + isReadOnly = false, + hasValidLicense = false, + isMlAdmin = false, +}) => { + const ruleType = field.value as RuleType; + const setType = useCallback( + (type: RuleType) => { + field.setValue(type); + }, + [field] + ); + const setMl = useCallback(() => setType('machine_learning'), [setType]); + const setQuery = useCallback(() => setType('query'), [setType]); + const mlCardDisabled = isReadOnly || !hasValidLicense || !isMlAdmin; + const licensingUrl = useKibana().services.application.getUrlForApp('kibana', { + path: '#/management/stack/license_management', + }); + + return ( + + + + } + selectable={{ + isDisabled: isReadOnly, + onClick: setQuery, + isSelected: !isMlRule(ruleType), + }} + /> + + + + } + icon={} + isDisabled={mlCardDisabled} + selectable={{ + isDisabled: mlCardDisabled, + onClick: setMl, + isSelected: isMlRule(ruleType), + }} + /> + + + + ); +}; diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/select_rule_type/translations.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/select_rule_type/translations.ts new file mode 100644 index 0000000000000..8b92d20616f7c --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/select_rule_type/translations.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const QUERY_TYPE_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.queryTypeTitle', + { + defaultMessage: 'Custom query', + } +); + +export const QUERY_TYPE_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.queryTypeDescription', + { + defaultMessage: 'Use KQL or Lucene to detect issues across indices.', + } +); + +export const ML_TYPE_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.mlTypeTitle', + { + defaultMessage: 'Machine Learning', + } +); + +export const ML_TYPE_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.mlTypeDescription', + { + defaultMessage: 'Select ML job to detect anomalous activity.', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/severity_badge/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/severity_badge/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/severity_badge/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/severity_badge/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/severity_badge/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/severity_badge/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/severity_badge/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/severity_badge/index.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/status_icon/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/status_icon/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/status_icon/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/status_icon/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/status_icon/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/status_icon/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/status_icon/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/status_icon/index.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_about_rule/data.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/data.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/step_about_rule/data.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/data.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_about_rule/default_value.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/default_value.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/step_about_rule/default_value.ts rename to x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/default_value.ts diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/index.test.tsx new file mode 100644 index 0000000000000..5a08b0a20d1fc --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/index.test.tsx @@ -0,0 +1,238 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React from 'react'; +import { mount, shallow } from 'enzyme'; +import { ThemeProvider } from 'styled-components'; +import euiDarkVars from '@elastic/eui/dist/eui_theme_light.json'; + +import { StepAboutRule } from '.'; + +import { mockAboutStepRule } from '../../../pages/detection_engine/rules/all/__mocks__/mock'; +import { StepRuleDescription } from '../description_step'; +import { stepAboutDefaultValue } from './default_value'; +import { wait } from '@testing-library/react'; +import { AboutStepRule } from '../../../pages/detection_engine/rules/types'; + +const theme = () => ({ eui: euiDarkVars, darkMode: true }); + +/* eslint-disable no-console */ +// Silence until enzyme fixed to use ReactTestUtils.act() +const originalError = console.error; +beforeAll(() => { + console.error = jest.fn(); +}); +afterAll(() => { + console.error = originalError; +}); +/* eslint-enable no-console */ + +describe('StepAboutRuleComponent', () => { + test('it renders StepRuleDescription if isReadOnlyView is true and "name" property exists', () => { + const wrapper = shallow( + + ); + + expect(wrapper.find(StepRuleDescription).exists()).toBeTruthy(); + }); + + test('it prevents user from clicking continue if no "description" defined', () => { + const wrapper = mount( + + + + ); + + wrapper + .find('[data-test-subj="detectionEngineStepAboutRuleName"] input') + .first() + .simulate('change', { target: { value: 'Test name text' } }); + + const descriptionInput = wrapper + .find('[data-test-subj="detectionEngineStepAboutRuleDescription"] textarea') + .first(); + wrapper.find('button[data-test-subj="about-continue"]').first().simulate('click'); + + expect( + wrapper.find('[data-test-subj="detectionEngineStepAboutRuleName"] input').first().props() + .value + ).toEqual('Test name text'); + expect(descriptionInput.props().value).toEqual(''); + expect( + wrapper + .find('[data-test-subj="detectionEngineStepAboutRuleDescription"] label') + .first() + .hasClass('euiFormLabel-isInvalid') + ).toBeTruthy(); + expect( + wrapper + .find('[data-test-subj="detectionEngineStepAboutRuleDescription"] EuiTextArea') + .first() + .prop('isInvalid') + ).toBeTruthy(); + }); + + test('it prevents user from clicking continue if no "name" defined', () => { + const wrapper = mount( + + + + ); + + wrapper + .find('[data-test-subj="detectionEngineStepAboutRuleDescription"] textarea') + .first() + .simulate('change', { target: { value: 'Test description text' } }); + + const nameInput = wrapper + .find('[data-test-subj="detectionEngineStepAboutRuleName"] input') + .first(); + + wrapper.find('button[data-test-subj="about-continue"]').first().simulate('click'); + + expect( + wrapper + .find('[data-test-subj="detectionEngineStepAboutRuleDescription"] textarea') + .first() + .props().value + ).toEqual('Test description text'); + expect(nameInput.props().value).toEqual(''); + expect( + wrapper + .find('[data-test-subj="detectionEngineStepAboutRuleName"] label') + .first() + .hasClass('euiFormLabel-isInvalid') + ).toBeTruthy(); + expect( + wrapper + .find('[data-test-subj="detectionEngineStepAboutRuleName"] EuiFieldText') + .first() + .prop('isInvalid') + ).toBeTruthy(); + }); + + test('it allows user to click continue if "name" and "description" are defined', async () => { + const stepDataMock = jest.fn(); + const wrapper = mount( + + + + ); + + wrapper + .find('[data-test-subj="detectionEngineStepAboutRuleDescription"] textarea') + .first() + .simulate('change', { target: { value: 'Test description text' } }); + + wrapper + .find('[data-test-subj="detectionEngineStepAboutRuleName"] input') + .first() + .simulate('change', { target: { value: 'Test name text' } }); + + wrapper.find('button[data-test-subj="about-continue"]').first().simulate('click').update(); + await wait(); + const expected: Omit = { + description: 'Test description text', + falsePositives: [''], + name: 'Test name text', + note: '', + references: [''], + riskScore: 50, + severity: 'low', + tags: [], + threat: [ + { + framework: 'MITRE ATT&CK', + tactic: { id: 'none', name: 'none', reference: 'none' }, + technique: [], + }, + ], + }; + expect(stepDataMock.mock.calls[1][1]).toEqual(expected); + }); + + test('it allows user to set the risk score as a number (and not a string)', async () => { + const stepDataMock = jest.fn(); + const wrapper = mount( + + + + ); + + wrapper + .find('[data-test-subj="detectionEngineStepAboutRuleName"] input') + .first() + .simulate('change', { target: { value: 'Test name text' } }); + + wrapper + .find('[data-test-subj="detectionEngineStepAboutRuleDescription"] textarea') + .first() + .simulate('change', { target: { value: 'Test description text' } }); + + wrapper + .find('[data-test-subj="detectionEngineStepAboutRuleRiskScore"] input') + .first() + .simulate('change', { target: { value: '80' } }); + + wrapper.find('[data-test-subj="about-continue"]').first().simulate('click').update(); + await wait(); + const expected: Omit = { + description: 'Test description text', + falsePositives: [''], + name: 'Test name text', + note: '', + references: [''], + riskScore: 80, + severity: 'low', + tags: [], + threat: [ + { + framework: 'MITRE ATT&CK', + tactic: { id: 'none', name: 'none', reference: 'none' }, + technique: [], + }, + ], + }; + expect(stepDataMock.mock.calls[1][1]).toEqual(expected); + }); +}); diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/index.tsx new file mode 100644 index 0000000000000..f23c51e019f24 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/index.tsx @@ -0,0 +1,286 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiAccordion, EuiFlexItem, EuiSpacer, EuiButtonEmpty } from '@elastic/eui'; +import React, { FC, memo, useCallback, useEffect, useState } from 'react'; +import styled from 'styled-components'; +import deepEqual from 'fast-deep-equal'; + +import { + RuleStepProps, + RuleStep, + AboutStepRule, +} from '../../../pages/detection_engine/rules/types'; +import { AddItem } from '../add_item_form'; +import { StepRuleDescription } from '../description_step'; +import { AddMitreThreat } from '../mitre'; +import { + Field, + Form, + FormDataProvider, + getUseField, + UseField, + useForm, +} from '../../../../shared_imports'; + +import { defaultRiskScoreBySeverity, severityOptions, SeverityValue } from './data'; +import { stepAboutDefaultValue } from './default_value'; +import { isUrlInvalid } from '../../../../common/utils/validators'; +import { schema } from './schema'; +import * as I18n from './translations'; +import { StepContentWrapper } from '../step_content_wrapper'; +import { NextStep } from '../next_step'; +import { MarkdownEditorForm } from '../../../../common/components/markdown_editor/form'; +import { setFieldValue } from '../../../pages/detection_engine/rules/helpers'; + +const CommonUseField = getUseField({ component: Field }); + +interface StepAboutRuleProps extends RuleStepProps { + defaultValues?: AboutStepRule | null; +} + +const ThreeQuartersContainer = styled.div` + max-width: 740px; +`; + +ThreeQuartersContainer.displayName = 'ThreeQuartersContainer'; + +const TagContainer = styled.div` + margin-top: 16px; +`; + +TagContainer.displayName = 'TagContainer'; + +const AdvancedSettingsAccordion = styled(EuiAccordion)` + .euiAccordion__iconWrapper { + display: none; + } + + .euiAccordion__childWrapper { + transition-duration: 1ms; /* hack to fire Step accordion to set proper content's height */ + } + + &.euiAccordion-isOpen .euiButtonEmpty__content > svg { + transform: rotate(90deg); + } +`; + +const AdvancedSettingsAccordionButton = ( + + {I18n.ADVANCED_SETTINGS} + +); + +const StepAboutRuleComponent: FC = ({ + addPadding = false, + defaultValues, + descriptionColumns = 'singleSplit', + isReadOnlyView, + isUpdateView = false, + isLoading, + setForm, + setStepData, +}) => { + const [myStepData, setMyStepData] = useState(stepAboutDefaultValue); + + const { form } = useForm({ + defaultValue: myStepData, + options: { stripEmptyFields: false }, + schema, + }); + + const onSubmit = useCallback(async () => { + if (setStepData) { + setStepData(RuleStep.aboutRule, null, false); + const { isValid, data } = await form.submit(); + if (isValid) { + setStepData(RuleStep.aboutRule, data, isValid); + setMyStepData({ ...data, isNew: false } as AboutStepRule); + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [form]); + + useEffect(() => { + const { isNew, ...initDefaultValue } = myStepData; + if (defaultValues != null && !deepEqual(initDefaultValue, defaultValues)) { + const myDefaultValues = { + ...defaultValues, + isNew: false, + }; + setMyStepData(myDefaultValues); + setFieldValue(form, schema, myDefaultValues); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [defaultValues]); + + useEffect(() => { + if (setForm != null) { + setForm(RuleStep.aboutRule, form); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [form]); + + return isReadOnlyView && myStepData.name != null ? ( + + + + ) : ( + <> + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {({ severity }) => { + const newRiskScore = defaultRiskScoreBySeverity[severity as SeverityValue]; + const severityField = form.getFields().severity; + const riskScoreField = form.getFields().riskScore; + if ( + severityField.value !== severity && + newRiskScore != null && + riskScoreField.value !== newRiskScore + ) { + riskScoreField.setValue(newRiskScore); + } + return null; + }} + + +
+ + {!isUpdateView && ( + + )} + + ); +}; + +export const StepAboutRule = memo(StepAboutRuleComponent); diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/schema.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/schema.tsx new file mode 100644 index 0000000000000..59ecebaeb9e4e --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/schema.tsx @@ -0,0 +1,203 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +import { + FIELD_TYPES, + fieldValidators, + FormSchema, + ValidationFunc, + ERROR_CODE, +} from '../../../../shared_imports'; +import { IMitreEnterpriseAttack } from '../../../pages/detection_engine/rules/types'; +import { isMitreAttackInvalid } from '../mitre/helpers'; +import { OptionalFieldLabel } from '../optional_field_label'; +import { isUrlInvalid } from '../../../../common/utils/validators'; +import * as I18n from './translations'; + +const { emptyField } = fieldValidators; + +export const schema: FormSchema = { + name: { + type: FIELD_TYPES.TEXT, + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldNameLabel', + { + defaultMessage: 'Name', + } + ), + validations: [ + { + validator: emptyField( + i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.nameFieldRequiredError', + { + defaultMessage: 'A name is required.', + } + ) + ), + }, + ], + }, + description: { + type: FIELD_TYPES.TEXTAREA, + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldDescriptionLabel', + { + defaultMessage: 'Description', + } + ), + validations: [ + { + validator: emptyField( + i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.descriptionFieldRequiredError', + { + defaultMessage: 'A description is required.', + } + ) + ), + }, + ], + }, + severity: { + type: FIELD_TYPES.SUPER_SELECT, + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldSeverityLabel', + { + defaultMessage: 'Severity', + } + ), + validations: [ + { + validator: emptyField( + i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.severityFieldRequiredError', + { + defaultMessage: 'A severity is required.', + } + ) + ), + }, + ], + }, + riskScore: { + type: FIELD_TYPES.RANGE, + serializer: (input: string) => Number(input), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldRiskScoreLabel', + { + defaultMessage: 'Risk score', + } + ), + }, + references: { + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldReferenceUrlsLabel', + { + defaultMessage: 'Reference URLs', + } + ), + labelAppend: OptionalFieldLabel, + validations: [ + { + validator: ( + ...args: Parameters + ): ReturnType> | undefined => { + const [{ value, path }] = args; + let hasError = false; + (value as string[]).forEach((url) => { + if (isUrlInvalid(url)) { + hasError = true; + } + }); + return hasError + ? { + code: 'ERR_FIELD_FORMAT', + path, + message: I18n.URL_FORMAT_INVALID, + } + : undefined; + }, + }, + ], + }, + falsePositives: { + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldFalsePositiveLabel', + { + defaultMessage: 'False positive examples', + } + ), + labelAppend: OptionalFieldLabel, + }, + threat: { + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldMitreThreatLabel', + { + defaultMessage: 'MITRE ATT&CK\\u2122', + } + ), + labelAppend: OptionalFieldLabel, + validations: [ + { + validator: ( + ...args: Parameters + ): ReturnType> | undefined => { + const [{ value, path }] = args; + let hasError = false; + (value as IMitreEnterpriseAttack[]).forEach((v) => { + if (isMitreAttackInvalid(v.tactic.name, v.technique)) { + hasError = true; + } + }); + return hasError + ? { + code: 'ERR_FIELD_MISSING', + path, + message: I18n.CUSTOM_MITRE_ATTACK_TECHNIQUES_REQUIRED, + } + : undefined; + }, + }, + ], + }, + tags: { + type: FIELD_TYPES.COMBO_BOX, + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTagsLabel', + { + defaultMessage: 'Tags', + } + ), + helpText: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTagsHelpText', + { + defaultMessage: + 'Type one or more custom identifying tags for this rule. Press enter after each tag to begin a new one.', + } + ), + labelAppend: OptionalFieldLabel, + }, + note: { + type: FIELD_TYPES.TEXTAREA, + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.guideLabel', + { + defaultMessage: 'Investigation guide', + } + ), + helpText: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.guideHelpText', + { + defaultMessage: + 'Provide helpful information for analysts that are performing a signal investigation. This guide will appear on both the rule details page and in timelines created from alerts generated by this rule.', + } + ), + labelAppend: OptionalFieldLabel, + }, +}; diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/translations.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/translations.ts new file mode 100644 index 0000000000000..c179128c56d92 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule/translations.ts @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const ADVANCED_SETTINGS = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.advancedSettingsButton', + { + defaultMessage: 'Advanced settings', + } +); + +export const ADD_REFERENCE = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.addReferenceDescription', + { + defaultMessage: 'Add reference URL', + } +); + +export const ADD_FALSE_POSITIVE = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.addFalsePositiveDescription', + { + defaultMessage: 'Add false positive example', + } +); + +export const LOW = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.severityOptionLowDescription', + { + defaultMessage: 'Low', + } +); + +export const MEDIUM = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.severityOptionMediumDescription', + { + defaultMessage: 'Medium', + } +); + +export const HIGH = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.severityOptionHighDescription', + { + defaultMessage: 'High', + } +); + +export const CRITICAL = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.severityOptionCriticalDescription', + { + defaultMessage: 'Critical', + } +); + +export const CUSTOM_MITRE_ATTACK_TECHNIQUES_REQUIRED = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.customMitreAttackTechniquesFieldRequiredError', + { + defaultMessage: 'At least one Technique is required with a Tactic.', + } +); + +export const URL_FORMAT_INVALID = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.referencesUrlInvalidError', + { + defaultMessage: 'Url is invalid format', + } +); + +export const ADD_RULE_NOTE_HELP_TEXT = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutrule.noteHelpText', + { + defaultMessage: 'Add rule investigation guide...', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_about_rule_details/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule_details/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/step_about_rule_details/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule_details/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_about_rule_details/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule_details/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/step_about_rule_details/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule_details/index.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule_details/translations.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule_details/translations.ts new file mode 100644 index 0000000000000..e1b89b1ec8ce2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/step_about_rule_details/translations.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { i18n } from '@kbn/i18n'; + +export const ABOUT_PANEL_DETAILS_TAB = i18n.translate( + 'xpack.securitySolution.detectionEngine.details.stepAboutRule.detailsLabel', + { + defaultMessage: 'Details', + } +); + +export const ABOUT_TEXT = i18n.translate( + 'xpack.securitySolution.detectionEngine.details.stepAboutRule.aboutText', + { + defaultMessage: 'About', + } +); + +export const ABOUT_PANEL_NOTES_TAB = i18n.translate( + 'xpack.securitySolution.detectionEngine.details.stepAboutRule.investigationGuideLabel', + { + defaultMessage: 'Investigation guide', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_content_wrapper/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_content_wrapper/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/step_content_wrapper/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/step_content_wrapper/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_content_wrapper/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_content_wrapper/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/step_content_wrapper/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/step_content_wrapper/index.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_define_rule/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_define_rule/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/step_define_rule/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/step_define_rule/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/step_define_rule/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_define_rule/index.tsx new file mode 100644 index 0000000000000..b56e1794eef63 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/step_define_rule/index.tsx @@ -0,0 +1,289 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiButtonEmpty, EuiFormRow } from '@elastic/eui'; +import React, { FC, memo, useCallback, useState, useEffect } from 'react'; +import styled from 'styled-components'; +import deepEqual from 'fast-deep-equal'; + +import { DEFAULT_INDEX_KEY } from '../../../../../common/constants'; +import { isMlRule } from '../../../../../common/machine_learning/helpers'; +import { hasMlAdminPermissions } from '../../../../../common/machine_learning/has_ml_admin_permissions'; +import { IIndexPattern } from '../../../../../../../../src/plugins/data/public'; +import { useFetchIndexPatterns } from '../../../../alerts/containers/detection_engine/rules'; +import { DEFAULT_TIMELINE_TITLE } from '../../../../timelines/components/timeline/translations'; +import { useMlCapabilities } from '../../../../common/components/ml_popover/hooks/use_ml_capabilities'; +import { useUiSetting$ } from '../../../../common/lib/kibana'; +import { setFieldValue } from '../../../pages/detection_engine/rules/helpers'; +import { + filterRuleFieldsForType, + RuleFields, +} from '../../../pages/detection_engine/rules/create/helpers'; +import { + DefineStepRule, + RuleStep, + RuleStepProps, +} from '../../../pages/detection_engine/rules/types'; +import { StepRuleDescription } from '../description_step'; +import { QueryBarDefineRule } from '../query_bar'; +import { SelectRuleType } from '../select_rule_type'; +import { AnomalyThresholdSlider } from '../anomaly_threshold_slider'; +import { MlJobSelect } from '../ml_job_select'; +import { PickTimeline } from '../pick_timeline'; +import { StepContentWrapper } from '../step_content_wrapper'; +import { NextStep } from '../next_step'; +import { + Field, + Form, + FormDataProvider, + getUseField, + UseField, + useForm, + FormSchema, +} from '../../../../shared_imports'; +import { schema } from './schema'; +import * as i18n from './translations'; + +const CommonUseField = getUseField({ component: Field }); + +interface StepDefineRuleProps extends RuleStepProps { + defaultValues?: DefineStepRule | null; +} + +const stepDefineDefaultValue: DefineStepRule = { + anomalyThreshold: 50, + index: [], + isNew: true, + machineLearningJobId: '', + ruleType: 'query', + queryBar: { + query: { query: '', language: 'kuery' }, + filters: [], + saved_id: undefined, + }, + timeline: { + id: null, + title: DEFAULT_TIMELINE_TITLE, + }, +}; + +const MyLabelButton = styled(EuiButtonEmpty)` + height: 18px; + font-size: 12px; + + .euiIcon { + width: 14px; + height: 14px; + } +`; + +MyLabelButton.defaultProps = { + flush: 'right', +}; + +const StepDefineRuleComponent: FC = ({ + addPadding = false, + defaultValues, + descriptionColumns = 'singleSplit', + isReadOnlyView, + isLoading, + isUpdateView = false, + setForm, + setStepData, +}) => { + const mlCapabilities = useMlCapabilities(); + const [openTimelineSearch, setOpenTimelineSearch] = useState(false); + const [indexModified, setIndexModified] = useState(false); + const [localIsMlRule, setIsMlRule] = useState(false); + const [indicesConfig] = useUiSetting$(DEFAULT_INDEX_KEY); + const [myStepData, setMyStepData] = useState({ + ...stepDefineDefaultValue, + index: indicesConfig ?? [], + }); + const [ + { browserFields, indexPatterns: indexPatternQueryBar, isLoading: indexPatternLoadingQueryBar }, + ] = useFetchIndexPatterns(myStepData.index); + + const { form } = useForm({ + defaultValue: myStepData, + options: { stripEmptyFields: false }, + schema, + }); + const clearErrors = useCallback(() => form.reset({ resetValues: false }), [form]); + + const onSubmit = useCallback(async () => { + if (setStepData) { + setStepData(RuleStep.defineRule, null, false); + const { isValid, data } = await form.submit(); + if (isValid && setStepData) { + setStepData(RuleStep.defineRule, data, isValid); + setMyStepData({ ...data, isNew: false } as DefineStepRule); + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [form]); + + useEffect(() => { + const { isNew, ...values } = myStepData; + if (defaultValues != null && !deepEqual(values, defaultValues)) { + const newValues = { ...values, ...defaultValues, isNew: false }; + setMyStepData(newValues); + setFieldValue(form, schema, newValues); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [defaultValues, setMyStepData, setFieldValue]); + + useEffect(() => { + if (setForm != null) { + setForm(RuleStep.defineRule, form); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [form]); + + const handleResetIndices = useCallback(() => { + const indexField = form.getFields().index; + indexField.setValue(indicesConfig); + }, [form, indicesConfig]); + + const handleOpenTimelineSearch = useCallback(() => { + setOpenTimelineSearch(true); + }, []); + + const handleCloseTimelineSearch = useCallback(() => { + setOpenTimelineSearch(false); + }, []); + + return isReadOnlyView ? ( + + + + ) : ( + <> + +
+ + + <> + + {i18n.RESET_DEFAULT_INDEX} + + ) : null, + }} + componentProps={{ + idAria: 'detectionEngineStepDefineRuleIndices', + 'data-test-subj': 'detectionEngineStepDefineRuleIndices', + euiFieldProps: { + fullWidth: true, + isDisabled: isLoading, + placeholder: '', + }, + }} + /> + + {i18n.IMPORT_TIMELINE_QUERY} + + ), + }} + component={QueryBarDefineRule} + componentProps={{ + browserFields, + idAria: 'detectionEngineStepDefineRuleQueryBar', + indexPattern: indexPatternQueryBar, + isDisabled: isLoading, + isLoading: indexPatternLoadingQueryBar, + dataTestSubj: 'detectionEngineStepDefineRuleQueryBar', + openTimelineSearch, + onCloseTimelineSearch: handleCloseTimelineSearch, + }} + /> + + + + <> + + + + + + + {({ index, ruleType }) => { + if (index != null) { + if (deepEqual(index, indicesConfig) && indexModified) { + setIndexModified(false); + } else if (!deepEqual(index, indicesConfig) && !indexModified) { + setIndexModified(true); + } + } + + if (isMlRule(ruleType) && !localIsMlRule) { + setIsMlRule(true); + clearErrors(); + } else if (!isMlRule(ruleType) && localIsMlRule) { + setIsMlRule(false); + clearErrors(); + } + + return null; + }} + + +
+ + {!isUpdateView && ( + + )} + + ); +}; + +export const StepDefineRule = memo(StepDefineRuleComponent); diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/step_define_rule/schema.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_define_rule/schema.tsx new file mode 100644 index 0000000000000..190d4484b156b --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/step_define_rule/schema.tsx @@ -0,0 +1,175 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; +import { EuiText } from '@elastic/eui'; +import { isEmpty } from 'lodash/fp'; +import React from 'react'; + +import { isMlRule } from '../../../../../common/machine_learning/helpers'; +import { esKuery } from '../../../../../../../../src/plugins/data/public'; +import { FieldValueQueryBar } from '../query_bar'; +import { + ERROR_CODE, + FIELD_TYPES, + fieldValidators, + FormSchema, + ValidationFunc, +} from '../../../../shared_imports'; +import { CUSTOM_QUERY_REQUIRED, INVALID_CUSTOM_QUERY, INDEX_HELPER_TEXT } from './translations'; + +export const schema: FormSchema = { + index: { + type: FIELD_TYPES.COMBO_BOX, + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fiedIndexPatternsLabel', + { + defaultMessage: 'Index patterns', + } + ), + helpText: {INDEX_HELPER_TEXT}, + validations: [ + { + validator: ( + ...args: Parameters + ): ReturnType> | undefined => { + const [{ formData }] = args; + const needsValidation = !isMlRule(formData.ruleType); + + if (!needsValidation) { + return; + } + + return fieldValidators.emptyField( + i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.outputIndiceNameFieldRequiredError', + { + defaultMessage: 'A minimum of one index pattern is required.', + } + ) + )(...args); + }, + }, + ], + }, + queryBar: { + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.fieldQuerBarLabel', + { + defaultMessage: 'Custom query', + } + ), + validations: [ + { + validator: ( + ...args: Parameters + ): ReturnType> | undefined => { + const [{ value, path, formData }] = args; + const { query, filters } = value as FieldValueQueryBar; + const needsValidation = !isMlRule(formData.ruleType); + if (!needsValidation) { + return; + } + + return isEmpty(query.query as string) && isEmpty(filters) + ? { + code: 'ERR_FIELD_MISSING', + path, + message: CUSTOM_QUERY_REQUIRED, + } + : undefined; + }, + }, + { + validator: ( + ...args: Parameters + ): ReturnType> | undefined => { + const [{ value, path, formData }] = args; + const { query } = value as FieldValueQueryBar; + const needsValidation = !isMlRule(formData.ruleType); + if (!needsValidation) { + return; + } + + if (!isEmpty(query.query as string) && query.language === 'kuery') { + try { + esKuery.fromKueryExpression(query.query); + } catch (err) { + return { + code: 'ERR_FIELD_FORMAT', + path, + message: INVALID_CUSTOM_QUERY, + }; + } + } + }, + }, + ], + }, + ruleType: { + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.fieldRuleTypeLabel', + { + defaultMessage: 'Rule type', + } + ), + validations: [], + }, + anomalyThreshold: { + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.fieldAnomalyThresholdLabel', + { + defaultMessage: 'Anomaly score threshold', + } + ), + validations: [], + }, + machineLearningJobId: { + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.fieldMachineLearningJobIdLabel', + { + defaultMessage: 'Machine Learning job', + } + ), + validations: [ + { + validator: ( + ...args: Parameters + ): ReturnType> | undefined => { + const [{ formData }] = args; + const needsValidation = isMlRule(formData.ruleType); + + if (!needsValidation) { + return; + } + + return fieldValidators.emptyField( + i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.machineLearningJobIdRequired', + { + defaultMessage: 'A Machine Learning job is required.', + } + ) + )(...args); + }, + }, + ], + }, + timeline: { + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTimelineTemplateLabel', + { + defaultMessage: 'Timeline template', + } + ), + helpText: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTimelineTemplateHelpText', + { + defaultMessage: 'Select which timeline to use when investigating generated alerts.', + } + ), + }, +}; diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/step_define_rule/translations.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_define_rule/translations.tsx new file mode 100644 index 0000000000000..a371db72d2ee1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/step_define_rule/translations.tsx @@ -0,0 +1,72 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const CUSTOM_QUERY_REQUIRED = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.customQueryFieldRequiredError', + { + defaultMessage: 'A custom query is required.', + } +); + +export const INVALID_CUSTOM_QUERY = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.customQueryFieldInvalidError', + { + defaultMessage: 'The KQL is invalid', + } +); + +export const CONFIG_INDICES = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.indicesFromConfigDescription', + { + defaultMessage: 'Use Elasticsearch indices from SIEM advanced settings', + } +); + +export const CUSTOM_INDICES = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.indicesCustomDescription', + { + defaultMessage: 'Provide custom list of indices', + } +); + +export const INDEX_HELPER_TEXT = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.indicesHelperDescription', + { + defaultMessage: + 'Enter the pattern of Elasticsearch indices where you would like this rule to run. By default, these will include index patterns defined in SIEM advanced settings.', + } +); + +export const RESET_DEFAULT_INDEX = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.resetDefaultIndicesButton', + { + defaultMessage: 'Reset to default index patterns', + } +); + +export const IMPORT_TIMELINE_QUERY = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.importTimelineQueryButton', + { + defaultMessage: 'Import query from saved timeline', + } +); + +export const ML_JOB_SELECT_PLACEHOLDER_TEXT = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.mlJobSelectPlaceholderText', + { + defaultMessage: 'Select a job', + } +); + +export const ENABLE_ML_JOB_WARNING = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.mlEnableJobWarningTitle', + { + defaultMessage: + 'This ML job is not currently running. Please set this job to run via "ML job settings" before activating this rule.', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_define_rule/types.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/step_define_rule/types.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/step_define_rule/types.ts rename to x-pack/plugins/security_solution/public/alerts/components/rules/step_define_rule/types.ts diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_panel/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_panel/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/step_panel/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/step_panel/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_panel/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_panel/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/step_panel/index.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/step_panel/index.tsx diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/index.tsx new file mode 100644 index 0000000000000..9334bd59bebf5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/index.tsx @@ -0,0 +1,232 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiHorizontalRule, + EuiForm, + EuiFlexGroup, + EuiFlexItem, + EuiButton, + EuiSpacer, +} from '@elastic/eui'; +import { findIndex } from 'lodash/fp'; +import React, { FC, memo, useCallback, useEffect, useMemo, useState } from 'react'; +import deepEqual from 'fast-deep-equal'; + +import { setFieldValue } from '../../../pages/detection_engine/rules/helpers'; +import { + RuleStep, + RuleStepProps, + ActionsStepRule, +} from '../../../pages/detection_engine/rules/types'; +import { StepRuleDescription } from '../description_step'; +import { Form, UseField, useForm } from '../../../../shared_imports'; +import { StepContentWrapper } from '../step_content_wrapper'; +import { + ThrottleSelectField, + THROTTLE_OPTIONS, + DEFAULT_THROTTLE_OPTION, +} from '../throttle_select_field'; +import { RuleActionsField } from '../rule_actions_field'; +import { useKibana } from '../../../../common/lib/kibana'; +import { getSchema } from './schema'; +import * as I18n from './translations'; + +interface StepRuleActionsProps extends RuleStepProps { + defaultValues?: ActionsStepRule | null; + actionMessageParams: string[]; +} + +const stepActionsDefaultValue = { + enabled: true, + isNew: true, + actions: [], + kibanaSiemAppUrl: '', + throttle: DEFAULT_THROTTLE_OPTION.value, +}; + +const GhostFormField = () => <>; + +const getThrottleOptions = (throttle?: string | null) => { + // Add support for throttle options set by the API + if (throttle && findIndex(['value', throttle], THROTTLE_OPTIONS) < 0) { + return [...THROTTLE_OPTIONS, { value: throttle, text: throttle }]; + } + + return THROTTLE_OPTIONS; +}; + +const StepRuleActionsComponent: FC = ({ + addPadding = false, + defaultValues, + isReadOnlyView, + isLoading, + isUpdateView = false, + setStepData, + setForm, + actionMessageParams, +}) => { + const [myStepData, setMyStepData] = useState(stepActionsDefaultValue); + const { + services: { + application, + triggers_actions_ui: { actionTypeRegistry }, + }, + } = useKibana(); + const schema = useMemo(() => getSchema({ actionTypeRegistry }), [actionTypeRegistry]); + + const { form } = useForm({ + defaultValue: myStepData, + options: { stripEmptyFields: false }, + schema, + }); + + const kibanaAbsoluteUrl = useMemo(() => application.getUrlForApp('siem', { absolute: true }), [ + application, + ]); + + const onSubmit = useCallback( + async (enabled: boolean) => { + if (setStepData) { + setStepData(RuleStep.ruleActions, null, false); + const { isValid: newIsValid, data } = await form.submit(); + if (newIsValid) { + setStepData(RuleStep.ruleActions, { ...data, enabled }, newIsValid); + setMyStepData({ ...data, isNew: false } as ActionsStepRule); + } + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [form] + ); + + useEffect(() => { + const { isNew, ...initDefaultValue } = myStepData; + if (defaultValues != null && !deepEqual(initDefaultValue, defaultValues)) { + const myDefaultValues = { + ...defaultValues, + isNew: false, + }; + setMyStepData(myDefaultValues); + setFieldValue(form, schema, myDefaultValues); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [defaultValues]); + + useEffect(() => { + if (setForm != null) { + setForm(RuleStep.ruleActions, form); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [form]); + + const updateThrottle = useCallback((throttle) => setMyStepData({ ...myStepData, throttle }), [ + myStepData, + setMyStepData, + ]); + + const throttleOptions = useMemo(() => { + const throttle = myStepData.throttle; + + return getThrottleOptions(throttle); + }, [myStepData]); + + const throttleFieldComponentProps = useMemo( + () => ({ + idAria: 'detectionEngineStepRuleActionsThrottle', + isDisabled: isLoading, + dataTestSubj: 'detectionEngineStepRuleActionsThrottle', + hasNoInitialSelection: false, + handleChange: updateThrottle, + euiFieldProps: { + options: throttleOptions, + }, + }), + // eslint-disable-next-line react-hooks/exhaustive-deps + [isLoading, updateThrottle] + ); + + return isReadOnlyView && myStepData != null ? ( + + + + ) : ( + <> + +
+ + + {myStepData.throttle !== stepActionsDefaultValue.throttle ? ( + <> + + + + ) : ( + + )} + + + +
+
+ + {!isUpdateView && ( + <> + + + + + {I18n.COMPLETE_WITHOUT_ACTIVATING} + + + + + {I18n.COMPLETE_WITH_ACTIVATING} + + + + + )} + + ); +}; + +export const StepRuleActions = memo(StepRuleActionsComponent); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/schema.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/schema.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/schema.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/schema.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/schema.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/schema.tsx new file mode 100644 index 0000000000000..a093f991afaf7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/schema.tsx @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/* istanbul ignore file */ + +import { i18n } from '@kbn/i18n'; + +import { + AlertAction, + ActionTypeRegistryContract, +} from '../../../../../../triggers_actions_ui/public'; +import { FormSchema, FormData, ValidationFunc, ERROR_CODE } from '../../../../shared_imports'; +import * as I18n from './translations'; +import { isUuidv4, getActionTypeName, validateMustache, validateActionParams } from './utils'; + +export const validateSingleAction = ( + actionItem: AlertAction, + actionTypeRegistry: ActionTypeRegistryContract +): string[] => { + if (!isUuidv4(actionItem.id)) { + return [I18n.NO_CONNECTOR_SELECTED]; + } + + const actionParamsErrors = validateActionParams(actionItem, actionTypeRegistry); + const mustacheErrors = validateMustache(actionItem.params); + + return [...actionParamsErrors, ...mustacheErrors]; +}; + +export const validateRuleActionsField = (actionTypeRegistry: ActionTypeRegistryContract) => ( + ...data: Parameters +): ReturnType> | undefined => { + const [{ value, path }] = data as [{ value: AlertAction[]; path: string }]; + + const errors = value.reduce((acc, actionItem) => { + const errorsArray = validateSingleAction(actionItem, actionTypeRegistry); + + if (errorsArray.length) { + const actionTypeName = getActionTypeName(actionItem.actionTypeId); + const errorsListItems = errorsArray.map((error) => `* ${error}\n`); + + return [...acc, `\n**${actionTypeName}:**\n${errorsListItems.join('')}`]; + } + + return acc; + }, [] as string[]); + + if (errors.length) { + return { + code: 'ERR_FIELD_FORMAT', + path, + message: `${errors.join('\n')}`, + }; + } +}; + +export const getSchema = ({ + actionTypeRegistry, +}: { + actionTypeRegistry: ActionTypeRegistryContract; +}): FormSchema => ({ + actions: { + validations: [ + { + validator: validateRuleActionsField(actionTypeRegistry), + }, + ], + }, + enabled: {}, + kibanaSiemAppUrl: {}, + throttle: { + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepRuleActions.fieldThrottleLabel', + { + defaultMessage: 'Actions frequency', + } + ), + helpText: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepRuleActions.fieldThrottleHelpText', + { + defaultMessage: + 'Select when automated actions should be performed if a rule evaluates as true.', + } + ), + }, +}); diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/translations.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/translations.tsx new file mode 100644 index 0000000000000..a276cb17e95f5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/translations.tsx @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; +import { startCase } from 'lodash/fp'; + +export const COMPLETE_WITHOUT_ACTIVATING = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.completeWithoutActivatingTitle', + { + defaultMessage: 'Create rule without activating it', + } +); + +export const COMPLETE_WITH_ACTIVATING = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.completeWithActivatingTitle', + { + defaultMessage: 'Create & activate rule', + } +); + +export const NO_CONNECTOR_SELECTED = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepRuleActions.noConnectorSelectedErrorMessage', + { + defaultMessage: 'No connector selected', + } +); + +export const INVALID_MUSTACHE_TEMPLATE = (paramKey: string) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepRuleActions.invalidMustacheTemplateErrorMessage', + { + defaultMessage: '{key} is not valid mustache template', + values: { + key: startCase(paramKey), + }, + } + ); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/utils.test.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/utils.test.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/utils.test.ts rename to x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/utils.test.ts diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/utils.ts b/x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/utils.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/step_rule_actions/utils.ts rename to x-pack/plugins/security_solution/public/alerts/components/rules/step_rule_actions/utils.ts diff --git a/x-pack/plugins/siem/public/alerts/components/rules/step_schedule_rule/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_schedule_rule/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/step_schedule_rule/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/step_schedule_rule/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/step_schedule_rule/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_schedule_rule/index.tsx new file mode 100644 index 0000000000000..60855bc5fa25f --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/step_schedule_rule/index.tsx @@ -0,0 +1,129 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, memo, useCallback, useEffect, useState } from 'react'; +import deepEqual from 'fast-deep-equal'; +import styled from 'styled-components'; + +import { setFieldValue } from '../../../pages/detection_engine/rules/helpers'; +import { + RuleStep, + RuleStepProps, + ScheduleStepRule, +} from '../../../pages/detection_engine/rules/types'; +import { StepRuleDescription } from '../description_step'; +import { ScheduleItem } from '../schedule_item_form'; +import { Form, UseField, useForm } from '../../../../shared_imports'; +import { StepContentWrapper } from '../step_content_wrapper'; +import { NextStep } from '../next_step'; +import { schema } from './schema'; + +interface StepScheduleRuleProps extends RuleStepProps { + defaultValues?: ScheduleStepRule | null; +} + +const RestrictedWidthContainer = styled.div` + max-width: 300px; +`; + +const stepScheduleDefaultValue = { + interval: '5m', + isNew: true, + from: '1m', +}; + +const StepScheduleRuleComponent: FC = ({ + addPadding = false, + defaultValues, + descriptionColumns = 'singleSplit', + isReadOnlyView, + isLoading, + isUpdateView = false, + setStepData, + setForm, +}) => { + const [myStepData, setMyStepData] = useState(stepScheduleDefaultValue); + + const { form } = useForm({ + defaultValue: myStepData, + options: { stripEmptyFields: false }, + schema, + }); + + const onSubmit = useCallback(async () => { + if (setStepData) { + setStepData(RuleStep.scheduleRule, null, false); + const { isValid: newIsValid, data } = await form.submit(); + if (newIsValid) { + setStepData(RuleStep.scheduleRule, { ...data }, newIsValid); + setMyStepData({ ...data, isNew: false } as ScheduleStepRule); + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [form]); + + useEffect(() => { + const { isNew, ...initDefaultValue } = myStepData; + if (defaultValues != null && !deepEqual(initDefaultValue, defaultValues)) { + const myDefaultValues = { + ...defaultValues, + isNew: false, + }; + setMyStepData(myDefaultValues); + setFieldValue(form, schema, myDefaultValues); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [defaultValues]); + + useEffect(() => { + if (setForm != null) { + setForm(RuleStep.scheduleRule, form); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [form]); + + return isReadOnlyView && myStepData != null ? ( + + + + ) : ( + <> + +
+ + + + + + +
+
+ + {!isUpdateView && ( + + )} + + ); +}; + +export const StepScheduleRule = memo(StepScheduleRuleComponent); diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/step_schedule_rule/schema.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_schedule_rule/schema.tsx new file mode 100644 index 0000000000000..f4c371a2364f6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/step_schedule_rule/schema.tsx @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/* istanbul ignore file */ + +import { i18n } from '@kbn/i18n'; + +import { OptionalFieldLabel } from '../optional_field_label'; +import { FormSchema } from '../../../../shared_imports'; + +export const schema: FormSchema = { + interval: { + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldIntervalLabel', + { + defaultMessage: 'Runs every', + } + ), + helpText: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldIntervalHelpText', + { + defaultMessage: 'Rules run periodically and detect alerts within the specified time frame.', + } + ), + }, + from: { + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldAdditionalLookBackLabel', + { + defaultMessage: 'Additional look-back time', + } + ), + labelAppend: OptionalFieldLabel, + helpText: i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldAdditionalLookBackHelpText', + { + defaultMessage: 'Adds time to the look-back period to prevent missed alerts.', + } + ), + }, +}; diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/step_schedule_rule/translations.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/step_schedule_rule/translations.tsx new file mode 100644 index 0000000000000..d49e7396f4c87 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/step_schedule_rule/translations.tsx @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const COMPLETE_WITHOUT_ACTIVATING = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule. stepScheduleRule.completeWithoutActivatingTitle', + { + defaultMessage: 'Create rule without activating it', + } +); + +export const COMPLETE_WITH_ACTIVATING = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule. stepScheduleRule.completeWithActivatingTitle', + { + defaultMessage: 'Create & activate rule', + } +); diff --git a/x-pack/plugins/siem/public/alerts/components/rules/throttle_select_field/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/throttle_select_field/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/components/rules/throttle_select_field/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/components/rules/throttle_select_field/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/throttle_select_field/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/throttle_select_field/index.tsx new file mode 100644 index 0000000000000..bf3498b28cd45 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/throttle_select_field/index.tsx @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback } from 'react'; + +import { + NOTIFICATION_THROTTLE_RULE, + NOTIFICATION_THROTTLE_NO_ACTIONS, +} from '../../../../../common/constants'; +import { SelectField } from '../../../../shared_imports'; + +export const THROTTLE_OPTIONS = [ + { value: NOTIFICATION_THROTTLE_NO_ACTIONS, text: 'Perform no actions' }, + { value: NOTIFICATION_THROTTLE_RULE, text: 'On each rule execution' }, + { value: '1h', text: 'Hourly' }, + { value: '1d', text: 'Daily' }, + { value: '7d', text: 'Weekly' }, +]; + +export const DEFAULT_THROTTLE_OPTION = THROTTLE_OPTIONS[0]; + +type ThrottleSelectField = typeof SelectField; + +export const ThrottleSelectField: ThrottleSelectField = (props) => { + const onChange = useCallback( + (e) => { + const throttle = e.target.value; + props.field.setValue(throttle); + props.handleChange(throttle); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [props.field.setValue, props.handleChange] + ); + const newEuiFieldProps = { ...props.euiFieldProps, onChange }; + return ; +}; diff --git a/x-pack/plugins/security_solution/public/alerts/components/user_info/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/components/user_info/index.test.tsx new file mode 100644 index 0000000000000..1d0f0e2e24f77 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/user_info/index.test.tsx @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { renderHook } from '@testing-library/react-hooks'; +import { useUserInfo } from './index'; + +import { usePrivilegeUser } from '../../containers/detection_engine/alerts/use_privilege_user'; +import { useSignalIndex } from '../../containers/detection_engine/alerts/use_signal_index'; +import { useKibana } from '../../../common/lib/kibana'; +jest.mock('../../containers/detection_engine/alerts/use_privilege_user'); +jest.mock('../../containers/detection_engine/alerts/use_signal_index'); +jest.mock('../../../common/lib/kibana'); + +describe('useUserInfo', () => { + beforeAll(() => { + (usePrivilegeUser as jest.Mock).mockReturnValue({}); + (useSignalIndex as jest.Mock).mockReturnValue({}); + (useKibana as jest.Mock).mockReturnValue({ + services: { + application: { + capabilities: { + securitySolution: { + crud: true, + }, + }, + }, + }, + }); + }); + it('returns default state', () => { + const { result } = renderHook(() => useUserInfo()); + + expect(result).toEqual({ + current: { + canUserCRUD: null, + hasEncryptionKey: null, + hasIndexManage: null, + hasIndexWrite: null, + isAuthenticated: null, + isSignalIndexExists: null, + loading: true, + signalIndexName: null, + }, + error: undefined, + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/alerts/components/user_info/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/user_info/index.tsx new file mode 100644 index 0000000000000..fc3fec7c29c1f --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/components/user_info/index.tsx @@ -0,0 +1,253 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { noop } from 'lodash/fp'; +import React, { useEffect, useReducer, Dispatch, createContext, useContext } from 'react'; + +import { usePrivilegeUser } from '../../containers/detection_engine/alerts/use_privilege_user'; +import { useSignalIndex } from '../../containers/detection_engine/alerts/use_signal_index'; +import { useKibana } from '../../../common/lib/kibana'; + +export interface State { + canUserCRUD: boolean | null; + hasIndexManage: boolean | null; + hasIndexWrite: boolean | null; + isSignalIndexExists: boolean | null; + isAuthenticated: boolean | null; + hasEncryptionKey: boolean | null; + loading: boolean; + signalIndexName: string | null; +} + +const initialState: State = { + canUserCRUD: null, + hasIndexManage: null, + hasIndexWrite: null, + isSignalIndexExists: null, + isAuthenticated: null, + hasEncryptionKey: null, + loading: true, + signalIndexName: null, +}; + +export type Action = + | { type: 'updateLoading'; loading: boolean } + | { + type: 'updateHasIndexManage'; + hasIndexManage: boolean | null; + } + | { + type: 'updateHasIndexWrite'; + hasIndexWrite: boolean | null; + } + | { + type: 'updateIsSignalIndexExists'; + isSignalIndexExists: boolean | null; + } + | { + type: 'updateIsAuthenticated'; + isAuthenticated: boolean | null; + } + | { + type: 'updateHasEncryptionKey'; + hasEncryptionKey: boolean | null; + } + | { + type: 'updateCanUserCRUD'; + canUserCRUD: boolean | null; + } + | { + type: 'updateSignalIndexName'; + signalIndexName: string | null; + }; + +export const userInfoReducer = (state: State, action: Action): State => { + switch (action.type) { + case 'updateLoading': { + return { + ...state, + loading: action.loading, + }; + } + case 'updateHasIndexManage': { + return { + ...state, + hasIndexManage: action.hasIndexManage, + }; + } + case 'updateHasIndexWrite': { + return { + ...state, + hasIndexWrite: action.hasIndexWrite, + }; + } + case 'updateIsSignalIndexExists': { + return { + ...state, + isSignalIndexExists: action.isSignalIndexExists, + }; + } + case 'updateIsAuthenticated': { + return { + ...state, + isAuthenticated: action.isAuthenticated, + }; + } + case 'updateHasEncryptionKey': { + return { + ...state, + hasEncryptionKey: action.hasEncryptionKey, + }; + } + case 'updateCanUserCRUD': { + return { + ...state, + canUserCRUD: action.canUserCRUD, + }; + } + case 'updateSignalIndexName': { + return { + ...state, + signalIndexName: action.signalIndexName, + }; + } + default: + return state; + } +}; + +const StateUserInfoContext = createContext<[State, Dispatch]>([initialState, () => noop]); + +const useUserData = () => useContext(StateUserInfoContext); + +interface ManageUserInfoProps { + children: React.ReactNode; +} + +export const ManageUserInfo = ({ children }: ManageUserInfoProps) => ( + + {children} + +); + +export const useUserInfo = (): State => { + const [ + { + canUserCRUD, + hasIndexManage, + hasIndexWrite, + isSignalIndexExists, + isAuthenticated, + hasEncryptionKey, + loading, + signalIndexName, + }, + dispatch, + ] = useUserData(); + const { + loading: privilegeLoading, + isAuthenticated: isApiAuthenticated, + hasEncryptionKey: isApiEncryptionKey, + hasIndexManage: hasApiIndexManage, + hasIndexWrite: hasApiIndexWrite, + } = usePrivilegeUser(); + const { + loading: indexNameLoading, + signalIndexExists: isApiSignalIndexExists, + signalIndexName: apiSignalIndexName, + createDeSignalIndex: createSignalIndex, + } = useSignalIndex(); + + const uiCapabilities = useKibana().services.application.capabilities; + const capabilitiesCanUserCRUD: boolean = + typeof uiCapabilities.securitySolution.crud === 'boolean' + ? uiCapabilities.securitySolution.crud + : false; + + useEffect(() => { + if (loading !== privilegeLoading || indexNameLoading) { + dispatch({ type: 'updateLoading', loading: privilegeLoading || indexNameLoading }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [loading, privilegeLoading, indexNameLoading]); + + useEffect(() => { + if (!loading && hasIndexManage !== hasApiIndexManage && hasApiIndexManage != null) { + dispatch({ type: 'updateHasIndexManage', hasIndexManage: hasApiIndexManage }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [loading, hasIndexManage, hasApiIndexManage]); + + useEffect(() => { + if (!loading && hasIndexWrite !== hasApiIndexWrite && hasApiIndexWrite != null) { + dispatch({ type: 'updateHasIndexWrite', hasIndexWrite: hasApiIndexWrite }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [loading, hasIndexWrite, hasApiIndexWrite]); + + useEffect(() => { + if ( + !loading && + isSignalIndexExists !== isApiSignalIndexExists && + isApiSignalIndexExists != null + ) { + dispatch({ type: 'updateIsSignalIndexExists', isSignalIndexExists: isApiSignalIndexExists }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [loading, isSignalIndexExists, isApiSignalIndexExists]); + + useEffect(() => { + if (!loading && isAuthenticated !== isApiAuthenticated && isApiAuthenticated != null) { + dispatch({ type: 'updateIsAuthenticated', isAuthenticated: isApiAuthenticated }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [loading, isAuthenticated, isApiAuthenticated]); + + useEffect(() => { + if (!loading && hasEncryptionKey !== isApiEncryptionKey && isApiEncryptionKey != null) { + dispatch({ type: 'updateHasEncryptionKey', hasEncryptionKey: isApiEncryptionKey }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [loading, hasEncryptionKey, isApiEncryptionKey]); + + useEffect(() => { + if (!loading && canUserCRUD !== capabilitiesCanUserCRUD && capabilitiesCanUserCRUD != null) { + dispatch({ type: 'updateCanUserCRUD', canUserCRUD: capabilitiesCanUserCRUD }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [loading, canUserCRUD, capabilitiesCanUserCRUD]); + + useEffect(() => { + if (!loading && signalIndexName !== apiSignalIndexName && apiSignalIndexName != null) { + dispatch({ type: 'updateSignalIndexName', signalIndexName: apiSignalIndexName }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [loading, signalIndexName, apiSignalIndexName]); + + useEffect(() => { + if ( + isAuthenticated && + hasEncryptionKey && + hasIndexManage && + isSignalIndexExists != null && + !isSignalIndexExists && + createSignalIndex != null + ) { + createSignalIndex(); + } + }, [createSignalIndex, isAuthenticated, hasEncryptionKey, isSignalIndexExists, hasIndexManage]); + + return { + loading, + isSignalIndexExists, + isAuthenticated, + hasEncryptionKey, + canUserCRUD, + hasIndexManage, + hasIndexWrite, + signalIndexName, + }; +}; diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/__mocks__/api.ts b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/__mocks__/api.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/__mocks__/api.ts rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/__mocks__/api.ts diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/api.test.ts b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/api.test.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/api.test.ts rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/api.test.ts diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/api.ts b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/api.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/api.ts rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/api.ts diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/mock.ts b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/mock.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/mock.ts rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/mock.ts diff --git a/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/translations.ts b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/translations.ts new file mode 100644 index 0000000000000..41f6a129d1b5e --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/translations.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const ALERT_FETCH_FAILURE = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.alerts.errorFetchingAlertsDescription', + { + defaultMessage: 'Failed to query alerts', + } +); + +export const PRIVILEGE_FETCH_FAILURE = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.alerts.errorFetchingAlertsDescription', + { + defaultMessage: 'Failed to query alerts', + } +); + +export const SIGNAL_GET_NAME_FAILURE = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.alerts.errorGetAlertDescription', + { + defaultMessage: 'Failed to get signal index name', + } +); + +export const SIGNAL_POST_FAILURE = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.alerts.errorPostAlertDescription', + { + defaultMessage: 'Failed to create signal index', + } +); diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/types.ts b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/types.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/types.ts rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/types.ts diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/use_privilege_user.test.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/use_privilege_user.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/use_privilege_user.test.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/use_privilege_user.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/use_privilege_user.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/use_privilege_user.tsx similarity index 97% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/use_privilege_user.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/use_privilege_user.tsx index e67afd686a7ca..dda9b50239cde 100644 --- a/x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/use_privilege_user.tsx +++ b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/use_privilege_user.tsx @@ -83,6 +83,7 @@ export const usePrivilegeUser = (): ReturnPrivilegeUser => { isSubscribed = false; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return { loading, ...privilegeUser }; diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/use_query.test.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/use_query.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/use_query.test.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/use_query.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/use_query.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/use_query.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/use_query.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/use_query.tsx diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/use_signal_index.test.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/use_signal_index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/use_signal_index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/use_signal_index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/use_signal_index.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/use_signal_index.tsx similarity index 98% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/use_signal_index.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/use_signal_index.tsx index 6c428bd9354ee..65a2721013b5e 100644 --- a/x-pack/plugins/siem/public/alerts/containers/detection_engine/alerts/use_signal_index.tsx +++ b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/alerts/use_signal_index.tsx @@ -103,6 +103,7 @@ export const useSignalIndex = (): ReturnSignalIndex => { isSubscribed = false; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return { loading, ...signalIndex }; diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/__mocks__/api.ts b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/__mocks__/api.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/__mocks__/api.ts rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/__mocks__/api.ts diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/api.test.ts b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/api.test.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/api.test.ts rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/api.test.ts diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/api.ts b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/api.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/api.ts rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/api.ts diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/fetch_index_patterns.test.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/fetch_index_patterns.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/fetch_index_patterns.test.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/fetch_index_patterns.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/fetch_index_patterns.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/fetch_index_patterns.tsx similarity index 98% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/fetch_index_patterns.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/fetch_index_patterns.tsx index 157f1490971f1..640d6f9a17fd1 100644 --- a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/fetch_index_patterns.tsx +++ b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/fetch_index_patterns.tsx @@ -94,6 +94,7 @@ export const useFetchIndexPatterns = (defaultIndices: string[] = []): Return => isSubscribed = false; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [indices]); return [{ browserFields, isLoading, indices, indicesExists, indexPatterns }, setIndices]; diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/index.ts b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/index.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/index.ts rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/index.ts diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/mock.ts b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/mock.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/mock.ts rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/mock.ts diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/persist_rule.test.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/persist_rule.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/persist_rule.test.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/persist_rule.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/persist_rule.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/persist_rule.tsx similarity index 96% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/persist_rule.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/persist_rule.tsx index 03080bf68cbf5..fd139d59c0a27 100644 --- a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/persist_rule.tsx +++ b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/persist_rule.tsx @@ -53,6 +53,7 @@ export const usePersistRule = (): ReturnPersistRule => { isSubscribed = false; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [rule]); return [{ isLoading, isSaved }, setRule]; diff --git a/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/translations.ts b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/translations.ts new file mode 100644 index 0000000000000..2b4b32bce9c7b --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/translations.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const RULE_FETCH_FAILURE = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.rules', + { + defaultMessage: 'Failed to fetch Rules', + } +); + +export const RULE_ADD_FAILURE = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.addRuleFailDescription', + { + defaultMessage: 'Failed to add Rule', + } +); + +export const RULE_PREPACKAGED_FAILURE = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.createPrePackagedRuleFailDescription', + { + defaultMessage: 'Failed to installed pre-packaged rules from elastic', + } +); + +export const RULE_PREPACKAGED_SUCCESS = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.createPrePackagedRuleSuccesDescription', + { + defaultMessage: 'Installed pre-packaged rules from elastic', + } +); + +export const TAG_FETCH_FAILURE = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.tagFetchFailDescription', + { + defaultMessage: 'Failed to fetch Tags', + } +); diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/types.ts b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/types.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/types.ts rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/types.ts diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_pre_packaged_rules.test.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_pre_packaged_rules.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_pre_packaged_rules.test.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_pre_packaged_rules.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_pre_packaged_rules.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_pre_packaged_rules.tsx similarity index 99% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_pre_packaged_rules.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_pre_packaged_rules.tsx index de4037ce7134c..5f5ee53c29caf 100644 --- a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_pre_packaged_rules.tsx +++ b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_pre_packaged_rules.tsx @@ -185,6 +185,7 @@ export const usePrePackagedRules = ({ isSubscribed = false; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [canUserCRUD, hasIndexWrite, isAuthenticated, hasEncryptionKey, isSignalIndexExists]); return { diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_rule.test.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_rule.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_rule.test.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_rule.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_rule.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_rule.tsx similarity index 96% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_rule.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_rule.tsx index 6ae5da3e56ff6..3256273fb8425 100644 --- a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_rule.tsx +++ b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_rule.tsx @@ -55,6 +55,7 @@ export const useRule = (id: string | undefined): ReturnRule => { isSubscribed = false; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [id]); return [loading, rule]; diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_rule_status.test.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_rule_status.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_rule_status.test.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_rule_status.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_rule_status.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_rule_status.tsx similarity index 96% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_rule_status.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_rule_status.tsx index b9f5e1f152c21..ec1da29de4ba8 100644 --- a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_rule_status.tsx +++ b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_rule_status.tsx @@ -64,6 +64,7 @@ export const useRuleStatus = (id: string | undefined | null): ReturnRuleStatus = isSubscribed = false; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [id]); return [loading, ruleStatus, fetchRuleStatus.current]; @@ -119,6 +120,7 @@ export const useRulesStatuses = (rules: Rules): ReturnRulesStatuses => { isSubscribed = false; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [rules]); return { loading, rulesStatuses }; diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_rules.test.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_rules.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_rules.test.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_rules.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_rules.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_rules.tsx similarity index 94% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_rules.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_rules.tsx index 3a074f2bc3785..1a1dbc6e2b368 100644 --- a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_rules.tsx +++ b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_rules.tsx @@ -46,7 +46,7 @@ export const useRules = ({ let isSubscribed = true; const abortCtrl = new AbortController(); - async function fetchData(forceReload: boolean = false) { + async function fetchData() { try { setLoading(true); const fetchRulesResult = await fetchRules({ @@ -80,7 +80,7 @@ export const useRules = ({ fetchData(); reFetchRules.current = (refreshPrePackagedRule: boolean = false) => { - fetchData(true); + fetchData(); if (refreshPrePackagedRule && refetchPrePackagedRulesStatus != null) { refetchPrePackagedRulesStatus(); } @@ -89,12 +89,14 @@ export const useRules = ({ isSubscribed = false; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [ pagination.page, pagination.perPage, filterOptions.filter, filterOptions.sortField, filterOptions.sortOrder, + // eslint-disable-next-line react-hooks/exhaustive-deps filterOptions.tags?.sort().join(), filterOptions.showCustomRules, filterOptions.showElasticRules, diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_tags.test.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_tags.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_tags.test.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_tags.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_tags.tsx b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_tags.tsx similarity index 96% rename from x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_tags.tsx rename to x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_tags.tsx index ebfe73f2f0863..038f974e1394e 100644 --- a/x-pack/plugins/siem/public/alerts/containers/detection_engine/rules/use_tags.tsx +++ b/x-pack/plugins/security_solution/public/alerts/containers/detection_engine/rules/use_tags.tsx @@ -53,6 +53,7 @@ export const useTags = (): ReturnTags => { isSubscribed = false; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return [loading, tags, reFetchTags.current]; diff --git a/x-pack/plugins/siem/public/alerts/index.ts b/x-pack/plugins/security_solution/public/alerts/index.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/index.ts rename to x-pack/plugins/security_solution/public/alerts/index.ts diff --git a/x-pack/plugins/siem/public/alerts/mitre/mitre_tactics_techniques.ts b/x-pack/plugins/security_solution/public/alerts/mitre/mitre_tactics_techniques.ts similarity index 79% rename from x-pack/plugins/siem/public/alerts/mitre/mitre_tactics_techniques.ts rename to x-pack/plugins/security_solution/public/alerts/mitre/mitre_tactics_techniques.ts index 16ab73365222b..fb8deeec8309c 100644 --- a/x-pack/plugins/siem/public/alerts/mitre/mitre_tactics_techniques.ts +++ b/x-pack/plugins/security_solution/public/alerts/mitre/mitre_tactics_techniques.ts @@ -76,9 +76,12 @@ export const tacticsOptions: MitreTacticsOptions[] = [ id: 'TA0009', name: 'Collection', reference: 'https://attack.mitre.org/tactics/TA0009', - text: i18n.translate('xpack.siem.detectionEngine.mitreAttackTactics.collectionDescription', { - defaultMessage: 'Collection (TA0009)', - }), + text: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTactics.collectionDescription', + { + defaultMessage: 'Collection (TA0009)', + } + ), value: 'collection', }, { @@ -86,7 +89,7 @@ export const tacticsOptions: MitreTacticsOptions[] = [ name: 'Command and Control', reference: 'https://attack.mitre.org/tactics/TA0011', text: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTactics.commandAndControlDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTactics.commandAndControlDescription', { defaultMessage: 'Command and Control (TA0011)' } ), value: 'commandAndControl', @@ -96,7 +99,7 @@ export const tacticsOptions: MitreTacticsOptions[] = [ name: 'Credential Access', reference: 'https://attack.mitre.org/tactics/TA0006', text: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTactics.credentialAccessDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTactics.credentialAccessDescription', { defaultMessage: 'Credential Access (TA0006)' } ), value: 'credentialAccess', @@ -106,7 +109,7 @@ export const tacticsOptions: MitreTacticsOptions[] = [ name: 'Defense Evasion', reference: 'https://attack.mitre.org/tactics/TA0005', text: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTactics.defenseEvasionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTactics.defenseEvasionDescription', { defaultMessage: 'Defense Evasion (TA0005)' } ), value: 'defenseEvasion', @@ -115,45 +118,60 @@ export const tacticsOptions: MitreTacticsOptions[] = [ id: 'TA0007', name: 'Discovery', reference: 'https://attack.mitre.org/tactics/TA0007', - text: i18n.translate('xpack.siem.detectionEngine.mitreAttackTactics.discoveryDescription', { - defaultMessage: 'Discovery (TA0007)', - }), + text: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTactics.discoveryDescription', + { + defaultMessage: 'Discovery (TA0007)', + } + ), value: 'discovery', }, { id: 'TA0002', name: 'Execution', reference: 'https://attack.mitre.org/tactics/TA0002', - text: i18n.translate('xpack.siem.detectionEngine.mitreAttackTactics.executionDescription', { - defaultMessage: 'Execution (TA0002)', - }), + text: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTactics.executionDescription', + { + defaultMessage: 'Execution (TA0002)', + } + ), value: 'execution', }, { id: 'TA0010', name: 'Exfiltration', reference: 'https://attack.mitre.org/tactics/TA0010', - text: i18n.translate('xpack.siem.detectionEngine.mitreAttackTactics.exfiltrationDescription', { - defaultMessage: 'Exfiltration (TA0010)', - }), + text: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTactics.exfiltrationDescription', + { + defaultMessage: 'Exfiltration (TA0010)', + } + ), value: 'exfiltration', }, { id: 'TA0040', name: 'Impact', reference: 'https://attack.mitre.org/tactics/TA0040', - text: i18n.translate('xpack.siem.detectionEngine.mitreAttackTactics.impactDescription', { - defaultMessage: 'Impact (TA0040)', - }), + text: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTactics.impactDescription', + { + defaultMessage: 'Impact (TA0040)', + } + ), value: 'impact', }, { id: 'TA0001', name: 'Initial Access', reference: 'https://attack.mitre.org/tactics/TA0001', - text: i18n.translate('xpack.siem.detectionEngine.mitreAttackTactics.initialAccessDescription', { - defaultMessage: 'Initial Access (TA0001)', - }), + text: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTactics.initialAccessDescription', + { + defaultMessage: 'Initial Access (TA0001)', + } + ), value: 'initialAccess', }, { @@ -161,7 +179,7 @@ export const tacticsOptions: MitreTacticsOptions[] = [ name: 'Lateral Movement', reference: 'https://attack.mitre.org/tactics/TA0008', text: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTactics.lateralMovementDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTactics.lateralMovementDescription', { defaultMessage: 'Lateral Movement (TA0008)' } ), value: 'lateralMovement', @@ -170,9 +188,12 @@ export const tacticsOptions: MitreTacticsOptions[] = [ id: 'TA0003', name: 'Persistence', reference: 'https://attack.mitre.org/tactics/TA0003', - text: i18n.translate('xpack.siem.detectionEngine.mitreAttackTactics.persistenceDescription', { - defaultMessage: 'Persistence (TA0003)', - }), + text: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTactics.persistenceDescription', + { + defaultMessage: 'Persistence (TA0003)', + } + ), value: 'persistence', }, { @@ -180,7 +201,7 @@ export const tacticsOptions: MitreTacticsOptions[] = [ name: 'Privilege Escalation', reference: 'https://attack.mitre.org/tactics/TA0004', text: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTactics.privilegeEscalationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTactics.privilegeEscalationDescription', { defaultMessage: 'Privilege Escalation (TA0004)' } ), value: 'privilegeEscalation', @@ -1789,7 +1810,7 @@ export const technique = [ export const techniquesOptions: MitreTechniquesOptions[] = [ { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.bashProfileAndBashrcDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.bashProfileAndBashrcDescription', { defaultMessage: '.bash_profile and .bashrc (T1156)' } ), id: 'T1156', @@ -1800,7 +1821,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.accessTokenManipulationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.accessTokenManipulationDescription', { defaultMessage: 'Access Token Manipulation (T1134)' } ), id: 'T1134', @@ -1811,7 +1832,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.accessibilityFeaturesDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.accessibilityFeaturesDescription', { defaultMessage: 'Accessibility Features (T1015)' } ), id: 'T1015', @@ -1822,7 +1843,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.accountAccessRemovalDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.accountAccessRemovalDescription', { defaultMessage: 'Account Access Removal (T1531)' } ), id: 'T1531', @@ -1833,7 +1854,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.accountDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.accountDiscoveryDescription', { defaultMessage: 'Account Discovery (T1087)' } ), id: 'T1087', @@ -1844,7 +1865,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.accountManipulationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.accountManipulationDescription', { defaultMessage: 'Account Manipulation (T1098)' } ), id: 'T1098', @@ -1855,7 +1876,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.appCertDlLsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.appCertDlLsDescription', { defaultMessage: 'AppCert DLLs (T1182)' } ), id: 'T1182', @@ -1866,7 +1887,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.appInitDlLsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.appInitDlLsDescription', { defaultMessage: 'AppInit DLLs (T1103)' } ), id: 'T1103', @@ -1877,7 +1898,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.appleScriptDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.appleScriptDescription', { defaultMessage: 'AppleScript (T1155)' } ), id: 'T1155', @@ -1888,7 +1909,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.applicationAccessTokenDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.applicationAccessTokenDescription', { defaultMessage: 'Application Access Token (T1527)' } ), id: 'T1527', @@ -1899,7 +1920,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.applicationDeploymentSoftwareDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.applicationDeploymentSoftwareDescription', { defaultMessage: 'Application Deployment Software (T1017)' } ), id: 'T1017', @@ -1910,7 +1931,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.applicationShimmingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.applicationShimmingDescription', { defaultMessage: 'Application Shimming (T1138)' } ), id: 'T1138', @@ -1921,7 +1942,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.applicationWindowDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.applicationWindowDiscoveryDescription', { defaultMessage: 'Application Window Discovery (T1010)' } ), id: 'T1010', @@ -1932,7 +1953,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.audioCaptureDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.audioCaptureDescription', { defaultMessage: 'Audio Capture (T1123)' } ), id: 'T1123', @@ -1943,7 +1964,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.authenticationPackageDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.authenticationPackageDescription', { defaultMessage: 'Authentication Package (T1131)' } ), id: 'T1131', @@ -1954,7 +1975,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.automatedCollectionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.automatedCollectionDescription', { defaultMessage: 'Automated Collection (T1119)' } ), id: 'T1119', @@ -1965,7 +1986,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.automatedExfiltrationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.automatedExfiltrationDescription', { defaultMessage: 'Automated Exfiltration (T1020)' } ), id: 'T1020', @@ -1975,9 +1996,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'automatedExfiltration', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.bitsJobsDescription', { - defaultMessage: 'BITS Jobs (T1197)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.bitsJobsDescription', + { + defaultMessage: 'BITS Jobs (T1197)', + } + ), id: 'T1197', name: 'BITS Jobs', reference: 'https://attack.mitre.org/techniques/T1197', @@ -1986,7 +2010,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.bashHistoryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.bashHistoryDescription', { defaultMessage: 'Bash History (T1139)' } ), id: 'T1139', @@ -1997,7 +2021,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.binaryPaddingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.binaryPaddingDescription', { defaultMessage: 'Binary Padding (T1009)' } ), id: 'T1009', @@ -2007,9 +2031,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'binaryPadding', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.bootkitDescription', { - defaultMessage: 'Bootkit (T1067)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.bootkitDescription', + { + defaultMessage: 'Bootkit (T1067)', + } + ), id: 'T1067', name: 'Bootkit', reference: 'https://attack.mitre.org/techniques/T1067', @@ -2018,7 +2045,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.browserBookmarkDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.browserBookmarkDiscoveryDescription', { defaultMessage: 'Browser Bookmark Discovery (T1217)' } ), id: 'T1217', @@ -2029,7 +2056,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.browserExtensionsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.browserExtensionsDescription', { defaultMessage: 'Browser Extensions (T1176)' } ), id: 'T1176', @@ -2040,7 +2067,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.bruteForceDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.bruteForceDescription', { defaultMessage: 'Brute Force (T1110)' } ), id: 'T1110', @@ -2051,7 +2078,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.bypassUserAccountControlDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.bypassUserAccountControlDescription', { defaultMessage: 'Bypass User Account Control (T1088)' } ), id: 'T1088', @@ -2061,9 +2088,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'bypassUserAccountControl', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.cmstpDescription', { - defaultMessage: 'CMSTP (T1191)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.cmstpDescription', + { + defaultMessage: 'CMSTP (T1191)', + } + ), id: 'T1191', name: 'CMSTP', reference: 'https://attack.mitre.org/techniques/T1191', @@ -2072,7 +2102,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.changeDefaultFileAssociationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.changeDefaultFileAssociationDescription', { defaultMessage: 'Change Default File Association (T1042)' } ), id: 'T1042', @@ -2083,7 +2113,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.clearCommandHistoryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.clearCommandHistoryDescription', { defaultMessage: 'Clear Command History (T1146)' } ), id: 'T1146', @@ -2094,7 +2124,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.clipboardDataDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.clipboardDataDescription', { defaultMessage: 'Clipboard Data (T1115)' } ), id: 'T1115', @@ -2105,7 +2135,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.cloudInstanceMetadataApiDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.cloudInstanceMetadataApiDescription', { defaultMessage: 'Cloud Instance Metadata API (T1522)' } ), id: 'T1522', @@ -2116,7 +2146,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.cloudServiceDashboardDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.cloudServiceDashboardDescription', { defaultMessage: 'Cloud Service Dashboard (T1538)' } ), id: 'T1538', @@ -2127,7 +2157,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.cloudServiceDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.cloudServiceDiscoveryDescription', { defaultMessage: 'Cloud Service Discovery (T1526)' } ), id: 'T1526', @@ -2138,7 +2168,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.codeSigningDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.codeSigningDescription', { defaultMessage: 'Code Signing (T1116)' } ), id: 'T1116', @@ -2149,7 +2179,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.commandLineInterfaceDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.commandLineInterfaceDescription', { defaultMessage: 'Command-Line Interface (T1059)' } ), id: 'T1059', @@ -2160,7 +2190,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.commonlyUsedPortDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.commonlyUsedPortDescription', { defaultMessage: 'Commonly Used Port (T1043)' } ), id: 'T1043', @@ -2171,7 +2201,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.communicationThroughRemovableMediaDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.communicationThroughRemovableMediaDescription', { defaultMessage: 'Communication Through Removable Media (T1092)' } ), id: 'T1092', @@ -2182,7 +2212,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.compileAfterDeliveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.compileAfterDeliveryDescription', { defaultMessage: 'Compile After Delivery (T1500)' } ), id: 'T1500', @@ -2193,7 +2223,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.compiledHtmlFileDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.compiledHtmlFileDescription', { defaultMessage: 'Compiled HTML File (T1223)' } ), id: 'T1223', @@ -2204,7 +2234,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.componentFirmwareDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.componentFirmwareDescription', { defaultMessage: 'Component Firmware (T1109)' } ), id: 'T1109', @@ -2215,7 +2245,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.componentObjectModelHijackingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.componentObjectModelHijackingDescription', { defaultMessage: 'Component Object Model Hijacking (T1122)' } ), id: 'T1122', @@ -2226,7 +2256,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.componentObjectModelAndDistributedComDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.componentObjectModelAndDistributedComDescription', { defaultMessage: 'Component Object Model and Distributed COM (T1175)' } ), id: 'T1175', @@ -2237,7 +2267,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.connectionProxyDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.connectionProxyDescription', { defaultMessage: 'Connection Proxy (T1090)' } ), id: 'T1090', @@ -2248,7 +2278,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.controlPanelItemsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.controlPanelItemsDescription', { defaultMessage: 'Control Panel Items (T1196)' } ), id: 'T1196', @@ -2259,7 +2289,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.createAccountDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.createAccountDescription', { defaultMessage: 'Create Account (T1136)' } ), id: 'T1136', @@ -2270,7 +2300,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.credentialDumpingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.credentialDumpingDescription', { defaultMessage: 'Credential Dumping (T1003)' } ), id: 'T1003', @@ -2281,7 +2311,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.credentialsFromWebBrowsersDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.credentialsFromWebBrowsersDescription', { defaultMessage: 'Credentials from Web Browsers (T1503)' } ), id: 'T1503', @@ -2292,7 +2322,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.credentialsInFilesDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.credentialsInFilesDescription', { defaultMessage: 'Credentials in Files (T1081)' } ), id: 'T1081', @@ -2303,7 +2333,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.credentialsInRegistryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.credentialsInRegistryDescription', { defaultMessage: 'Credentials in Registry (T1214)' } ), id: 'T1214', @@ -2314,7 +2344,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.customCommandAndControlProtocolDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.customCommandAndControlProtocolDescription', { defaultMessage: 'Custom Command and Control Protocol (T1094)' } ), id: 'T1094', @@ -2325,7 +2355,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.customCryptographicProtocolDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.customCryptographicProtocolDescription', { defaultMessage: 'Custom Cryptographic Protocol (T1024)' } ), id: 'T1024', @@ -2335,9 +2365,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'customCryptographicProtocol', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.dcShadowDescription', { - defaultMessage: 'DCShadow (T1207)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dcShadowDescription', + { + defaultMessage: 'DCShadow (T1207)', + } + ), id: 'T1207', name: 'DCShadow', reference: 'https://attack.mitre.org/techniques/T1207', @@ -2346,7 +2379,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dllSearchOrderHijackingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dllSearchOrderHijackingDescription', { defaultMessage: 'DLL Search Order Hijacking (T1038)' } ), id: 'T1038', @@ -2357,7 +2390,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dllSideLoadingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dllSideLoadingDescription', { defaultMessage: 'DLL Side-Loading (T1073)' } ), id: 'T1073', @@ -2368,7 +2401,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dataCompressedDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dataCompressedDescription', { defaultMessage: 'Data Compressed (T1002)' } ), id: 'T1002', @@ -2379,7 +2412,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dataDestructionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dataDestructionDescription', { defaultMessage: 'Data Destruction (T1485)' } ), id: 'T1485', @@ -2390,7 +2423,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dataEncodingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dataEncodingDescription', { defaultMessage: 'Data Encoding (T1132)' } ), id: 'T1132', @@ -2401,7 +2434,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dataEncryptedDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dataEncryptedDescription', { defaultMessage: 'Data Encrypted (T1022)' } ), id: 'T1022', @@ -2412,7 +2445,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dataEncryptedForImpactDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dataEncryptedForImpactDescription', { defaultMessage: 'Data Encrypted for Impact (T1486)' } ), id: 'T1486', @@ -2423,7 +2456,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dataObfuscationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dataObfuscationDescription', { defaultMessage: 'Data Obfuscation (T1001)' } ), id: 'T1001', @@ -2434,7 +2467,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dataStagedDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dataStagedDescription', { defaultMessage: 'Data Staged (T1074)' } ), id: 'T1074', @@ -2445,7 +2478,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dataTransferSizeLimitsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dataTransferSizeLimitsDescription', { defaultMessage: 'Data Transfer Size Limits (T1030)' } ), id: 'T1030', @@ -2456,7 +2489,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dataFromCloudStorageObjectDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dataFromCloudStorageObjectDescription', { defaultMessage: 'Data from Cloud Storage Object (T1530)' } ), id: 'T1530', @@ -2467,7 +2500,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dataFromInformationRepositoriesDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dataFromInformationRepositoriesDescription', { defaultMessage: 'Data from Information Repositories (T1213)' } ), id: 'T1213', @@ -2478,7 +2511,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dataFromLocalSystemDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dataFromLocalSystemDescription', { defaultMessage: 'Data from Local System (T1005)' } ), id: 'T1005', @@ -2489,7 +2522,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dataFromNetworkSharedDriveDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dataFromNetworkSharedDriveDescription', { defaultMessage: 'Data from Network Shared Drive (T1039)' } ), id: 'T1039', @@ -2500,7 +2533,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dataFromRemovableMediaDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dataFromRemovableMediaDescription', { defaultMessage: 'Data from Removable Media (T1025)' } ), id: 'T1025', @@ -2511,7 +2544,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.defacementDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.defacementDescription', { defaultMessage: 'Defacement (T1491)' } ), id: 'T1491', @@ -2522,7 +2555,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.deobfuscateDecodeFilesOrInformationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.deobfuscateDecodeFilesOrInformationDescription', { defaultMessage: 'Deobfuscate/Decode Files or Information (T1140)' } ), id: 'T1140', @@ -2533,7 +2566,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.disablingSecurityToolsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.disablingSecurityToolsDescription', { defaultMessage: 'Disabling Security Tools (T1089)' } ), id: 'T1089', @@ -2544,7 +2577,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.diskContentWipeDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.diskContentWipeDescription', { defaultMessage: 'Disk Content Wipe (T1488)' } ), id: 'T1488', @@ -2555,7 +2588,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.diskStructureWipeDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.diskStructureWipeDescription', { defaultMessage: 'Disk Structure Wipe (T1487)' } ), id: 'T1487', @@ -2566,7 +2599,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.domainFrontingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.domainFrontingDescription', { defaultMessage: 'Domain Fronting (T1172)' } ), id: 'T1172', @@ -2577,7 +2610,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.domainGenerationAlgorithmsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.domainGenerationAlgorithmsDescription', { defaultMessage: 'Domain Generation Algorithms (T1483)' } ), id: 'T1483', @@ -2588,7 +2621,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.domainTrustDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.domainTrustDiscoveryDescription', { defaultMessage: 'Domain Trust Discovery (T1482)' } ), id: 'T1482', @@ -2599,7 +2632,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.driveByCompromiseDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.driveByCompromiseDescription', { defaultMessage: 'Drive-by Compromise (T1189)' } ), id: 'T1189', @@ -2610,7 +2643,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dylibHijackingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dylibHijackingDescription', { defaultMessage: 'Dylib Hijacking (T1157)' } ), id: 'T1157', @@ -2621,7 +2654,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.dynamicDataExchangeDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.dynamicDataExchangeDescription', { defaultMessage: 'Dynamic Data Exchange (T1173)' } ), id: 'T1173', @@ -2632,7 +2665,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.elevatedExecutionWithPromptDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.elevatedExecutionWithPromptDescription', { defaultMessage: 'Elevated Execution with Prompt (T1514)' } ), id: 'T1514', @@ -2643,7 +2676,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.emailCollectionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.emailCollectionDescription', { defaultMessage: 'Email Collection (T1114)' } ), id: 'T1114', @@ -2653,9 +2686,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'emailCollection', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.emondDescription', { - defaultMessage: 'Emond (T1519)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.emondDescription', + { + defaultMessage: 'Emond (T1519)', + } + ), id: 'T1519', name: 'Emond', reference: 'https://attack.mitre.org/techniques/T1519', @@ -2664,7 +2700,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.endpointDenialOfServiceDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.endpointDenialOfServiceDescription', { defaultMessage: 'Endpoint Denial of Service (T1499)' } ), id: 'T1499', @@ -2675,7 +2711,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.executionGuardrailsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.executionGuardrailsDescription', { defaultMessage: 'Execution Guardrails (T1480)' } ), id: 'T1480', @@ -2686,7 +2722,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.executionThroughApiDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.executionThroughApiDescription', { defaultMessage: 'Execution through API (T1106)' } ), id: 'T1106', @@ -2697,7 +2733,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.executionThroughModuleLoadDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.executionThroughModuleLoadDescription', { defaultMessage: 'Execution through Module Load (T1129)' } ), id: 'T1129', @@ -2708,7 +2744,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.exfiltrationOverAlternativeProtocolDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.exfiltrationOverAlternativeProtocolDescription', { defaultMessage: 'Exfiltration Over Alternative Protocol (T1048)' } ), id: 'T1048', @@ -2719,7 +2755,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.exfiltrationOverCommandAndControlChannelDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.exfiltrationOverCommandAndControlChannelDescription', { defaultMessage: 'Exfiltration Over Command and Control Channel (T1041)' } ), id: 'T1041', @@ -2730,7 +2766,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.exfiltrationOverOtherNetworkMediumDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.exfiltrationOverOtherNetworkMediumDescription', { defaultMessage: 'Exfiltration Over Other Network Medium (T1011)' } ), id: 'T1011', @@ -2741,7 +2777,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.exfiltrationOverPhysicalMediumDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.exfiltrationOverPhysicalMediumDescription', { defaultMessage: 'Exfiltration Over Physical Medium (T1052)' } ), id: 'T1052', @@ -2752,7 +2788,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.exploitPublicFacingApplicationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.exploitPublicFacingApplicationDescription', { defaultMessage: 'Exploit Public-Facing Application (T1190)' } ), id: 'T1190', @@ -2763,7 +2799,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.exploitationForClientExecutionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.exploitationForClientExecutionDescription', { defaultMessage: 'Exploitation for Client Execution (T1203)' } ), id: 'T1203', @@ -2774,7 +2810,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.exploitationForCredentialAccessDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.exploitationForCredentialAccessDescription', { defaultMessage: 'Exploitation for Credential Access (T1212)' } ), id: 'T1212', @@ -2785,7 +2821,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.exploitationForDefenseEvasionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.exploitationForDefenseEvasionDescription', { defaultMessage: 'Exploitation for Defense Evasion (T1211)' } ), id: 'T1211', @@ -2796,7 +2832,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.exploitationForPrivilegeEscalationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.exploitationForPrivilegeEscalationDescription', { defaultMessage: 'Exploitation for Privilege Escalation (T1068)' } ), id: 'T1068', @@ -2807,7 +2843,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.exploitationOfRemoteServicesDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.exploitationOfRemoteServicesDescription', { defaultMessage: 'Exploitation of Remote Services (T1210)' } ), id: 'T1210', @@ -2818,7 +2854,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.externalRemoteServicesDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.externalRemoteServicesDescription', { defaultMessage: 'External Remote Services (T1133)' } ), id: 'T1133', @@ -2829,7 +2865,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.extraWindowMemoryInjectionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.extraWindowMemoryInjectionDescription', { defaultMessage: 'Extra Window Memory Injection (T1181)' } ), id: 'T1181', @@ -2840,7 +2876,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.fallbackChannelsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.fallbackChannelsDescription', { defaultMessage: 'Fallback Channels (T1008)' } ), id: 'T1008', @@ -2851,7 +2887,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.fileDeletionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.fileDeletionDescription', { defaultMessage: 'File Deletion (T1107)' } ), id: 'T1107', @@ -2862,7 +2898,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.fileSystemLogicalOffsetsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.fileSystemLogicalOffsetsDescription', { defaultMessage: 'File System Logical Offsets (T1006)' } ), id: 'T1006', @@ -2873,7 +2909,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.fileSystemPermissionsWeaknessDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.fileSystemPermissionsWeaknessDescription', { defaultMessage: 'File System Permissions Weakness (T1044)' } ), id: 'T1044', @@ -2884,7 +2920,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.fileAndDirectoryDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.fileAndDirectoryDiscoveryDescription', { defaultMessage: 'File and Directory Discovery (T1083)' } ), id: 'T1083', @@ -2895,7 +2931,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.fileAndDirectoryPermissionsModificationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.fileAndDirectoryPermissionsModificationDescription', { defaultMessage: 'File and Directory Permissions Modification (T1222)' } ), id: 'T1222', @@ -2906,7 +2942,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.firmwareCorruptionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.firmwareCorruptionDescription', { defaultMessage: 'Firmware Corruption (T1495)' } ), id: 'T1495', @@ -2917,7 +2953,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.forcedAuthenticationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.forcedAuthenticationDescription', { defaultMessage: 'Forced Authentication (T1187)' } ), id: 'T1187', @@ -2928,7 +2964,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.gatekeeperBypassDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.gatekeeperBypassDescription', { defaultMessage: 'Gatekeeper Bypass (T1144)' } ), id: 'T1144', @@ -2939,7 +2975,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.graphicalUserInterfaceDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.graphicalUserInterfaceDescription', { defaultMessage: 'Graphical User Interface (T1061)' } ), id: 'T1061', @@ -2950,7 +2986,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.groupPolicyModificationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.groupPolicyModificationDescription', { defaultMessage: 'Group Policy Modification (T1484)' } ), id: 'T1484', @@ -2961,7 +2997,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.histcontrolDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.histcontrolDescription', { defaultMessage: 'HISTCONTROL (T1148)' } ), id: 'T1148', @@ -2972,7 +3008,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.hardwareAdditionsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.hardwareAdditionsDescription', { defaultMessage: 'Hardware Additions (T1200)' } ), id: 'T1200', @@ -2983,7 +3019,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.hiddenFilesAndDirectoriesDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.hiddenFilesAndDirectoriesDescription', { defaultMessage: 'Hidden Files and Directories (T1158)' } ), id: 'T1158', @@ -2994,7 +3030,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.hiddenUsersDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.hiddenUsersDescription', { defaultMessage: 'Hidden Users (T1147)' } ), id: 'T1147', @@ -3005,7 +3041,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.hiddenWindowDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.hiddenWindowDescription', { defaultMessage: 'Hidden Window (T1143)' } ), id: 'T1143', @@ -3015,9 +3051,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'hiddenWindow', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.hookingDescription', { - defaultMessage: 'Hooking (T1179)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.hookingDescription', + { + defaultMessage: 'Hooking (T1179)', + } + ), id: 'T1179', name: 'Hooking', reference: 'https://attack.mitre.org/techniques/T1179', @@ -3026,7 +3065,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.hypervisorDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.hypervisorDescription', { defaultMessage: 'Hypervisor (T1062)' } ), id: 'T1062', @@ -3037,7 +3076,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.imageFileExecutionOptionsInjectionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.imageFileExecutionOptionsInjectionDescription', { defaultMessage: 'Image File Execution Options Injection (T1183)' } ), id: 'T1183', @@ -3048,7 +3087,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.implantContainerImageDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.implantContainerImageDescription', { defaultMessage: 'Implant Container Image (T1525)' } ), id: 'T1525', @@ -3059,7 +3098,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.indicatorBlockingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.indicatorBlockingDescription', { defaultMessage: 'Indicator Blocking (T1054)' } ), id: 'T1054', @@ -3070,7 +3109,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.indicatorRemovalFromToolsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.indicatorRemovalFromToolsDescription', { defaultMessage: 'Indicator Removal from Tools (T1066)' } ), id: 'T1066', @@ -3081,7 +3120,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.indicatorRemovalOnHostDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.indicatorRemovalOnHostDescription', { defaultMessage: 'Indicator Removal on Host (T1070)' } ), id: 'T1070', @@ -3092,7 +3131,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.indirectCommandExecutionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.indirectCommandExecutionDescription', { defaultMessage: 'Indirect Command Execution (T1202)' } ), id: 'T1202', @@ -3103,7 +3142,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.inhibitSystemRecoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.inhibitSystemRecoveryDescription', { defaultMessage: 'Inhibit System Recovery (T1490)' } ), id: 'T1490', @@ -3114,7 +3153,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.inputCaptureDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.inputCaptureDescription', { defaultMessage: 'Input Capture (T1056)' } ), id: 'T1056', @@ -3125,7 +3164,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.inputPromptDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.inputPromptDescription', { defaultMessage: 'Input Prompt (T1141)' } ), id: 'T1141', @@ -3136,7 +3175,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.installRootCertificateDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.installRootCertificateDescription', { defaultMessage: 'Install Root Certificate (T1130)' } ), id: 'T1130', @@ -3147,7 +3186,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.installUtilDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.installUtilDescription', { defaultMessage: 'InstallUtil (T1118)' } ), id: 'T1118', @@ -3158,7 +3197,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.internalSpearphishingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.internalSpearphishingDescription', { defaultMessage: 'Internal Spearphishing (T1534)' } ), id: 'T1534', @@ -3169,7 +3208,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.kerberoastingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.kerberoastingDescription', { defaultMessage: 'Kerberoasting (T1208)' } ), id: 'T1208', @@ -3180,7 +3219,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.kernelModulesAndExtensionsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.kernelModulesAndExtensionsDescription', { defaultMessage: 'Kernel Modules and Extensions (T1215)' } ), id: 'T1215', @@ -3190,9 +3229,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'kernelModulesAndExtensions', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.keychainDescription', { - defaultMessage: 'Keychain (T1142)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.keychainDescription', + { + defaultMessage: 'Keychain (T1142)', + } + ), id: 'T1142', name: 'Keychain', reference: 'https://attack.mitre.org/techniques/T1142', @@ -3201,7 +3243,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.lcLoadDylibAdditionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.lcLoadDylibAdditionDescription', { defaultMessage: 'LC_LOAD_DYLIB Addition (T1161)' } ), id: 'T1161', @@ -3212,7 +3254,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.lcMainHijackingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.lcMainHijackingDescription', { defaultMessage: 'LC_MAIN Hijacking (T1149)' } ), id: 'T1149', @@ -3223,7 +3265,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.llmnrNbtNsPoisoningAndRelayDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.llmnrNbtNsPoisoningAndRelayDescription', { defaultMessage: 'LLMNR/NBT-NS Poisoning and Relay (T1171)' } ), id: 'T1171', @@ -3234,7 +3276,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.lsassDriverDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.lsassDriverDescription', { defaultMessage: 'LSASS Driver (T1177)' } ), id: 'T1177', @@ -3245,7 +3287,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.launchAgentDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.launchAgentDescription', { defaultMessage: 'Launch Agent (T1159)' } ), id: 'T1159', @@ -3256,7 +3298,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.launchDaemonDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.launchDaemonDescription', { defaultMessage: 'Launch Daemon (T1160)' } ), id: 'T1160', @@ -3266,9 +3308,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'launchDaemon', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.launchctlDescription', { - defaultMessage: 'Launchctl (T1152)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.launchctlDescription', + { + defaultMessage: 'Launchctl (T1152)', + } + ), id: 'T1152', name: 'Launchctl', reference: 'https://attack.mitre.org/techniques/T1152', @@ -3277,7 +3322,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.localJobSchedulingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.localJobSchedulingDescription', { defaultMessage: 'Local Job Scheduling (T1168)' } ), id: 'T1168', @@ -3287,9 +3332,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'localJobScheduling', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.loginItemDescription', { - defaultMessage: 'Login Item (T1162)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.loginItemDescription', + { + defaultMessage: 'Login Item (T1162)', + } + ), id: 'T1162', name: 'Login Item', reference: 'https://attack.mitre.org/techniques/T1162', @@ -3298,7 +3346,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.logonScriptsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.logonScriptsDescription', { defaultMessage: 'Logon Scripts (T1037)' } ), id: 'T1037', @@ -3309,7 +3357,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.manInTheBrowserDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.manInTheBrowserDescription', { defaultMessage: 'Man in the Browser (T1185)' } ), id: 'T1185', @@ -3320,7 +3368,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.masqueradingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.masqueradingDescription', { defaultMessage: 'Masquerading (T1036)' } ), id: 'T1036', @@ -3331,7 +3379,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.modifyExistingServiceDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.modifyExistingServiceDescription', { defaultMessage: 'Modify Existing Service (T1031)' } ), id: 'T1031', @@ -3342,7 +3390,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.modifyRegistryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.modifyRegistryDescription', { defaultMessage: 'Modify Registry (T1112)' } ), id: 'T1112', @@ -3352,9 +3400,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'modifyRegistry', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.mshtaDescription', { - defaultMessage: 'Mshta (T1170)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.mshtaDescription', + { + defaultMessage: 'Mshta (T1170)', + } + ), id: 'T1170', name: 'Mshta', reference: 'https://attack.mitre.org/techniques/T1170', @@ -3363,7 +3414,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.multiStageChannelsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.multiStageChannelsDescription', { defaultMessage: 'Multi-Stage Channels (T1104)' } ), id: 'T1104', @@ -3374,7 +3425,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.multiHopProxyDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.multiHopProxyDescription', { defaultMessage: 'Multi-hop Proxy (T1188)' } ), id: 'T1188', @@ -3385,7 +3436,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.multibandCommunicationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.multibandCommunicationDescription', { defaultMessage: 'Multiband Communication (T1026)' } ), id: 'T1026', @@ -3396,7 +3447,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.multilayerEncryptionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.multilayerEncryptionDescription', { defaultMessage: 'Multilayer Encryption (T1079)' } ), id: 'T1079', @@ -3407,7 +3458,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.ntfsFileAttributesDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.ntfsFileAttributesDescription', { defaultMessage: 'NTFS File Attributes (T1096)' } ), id: 'T1096', @@ -3418,7 +3469,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.netshHelperDllDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.netshHelperDllDescription', { defaultMessage: 'Netsh Helper DLL (T1128)' } ), id: 'T1128', @@ -3429,7 +3480,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.networkDenialOfServiceDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.networkDenialOfServiceDescription', { defaultMessage: 'Network Denial of Service (T1498)' } ), id: 'T1498', @@ -3440,7 +3491,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.networkServiceScanningDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.networkServiceScanningDescription', { defaultMessage: 'Network Service Scanning (T1046)' } ), id: 'T1046', @@ -3451,7 +3502,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.networkShareConnectionRemovalDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.networkShareConnectionRemovalDescription', { defaultMessage: 'Network Share Connection Removal (T1126)' } ), id: 'T1126', @@ -3462,7 +3513,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.networkShareDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.networkShareDiscoveryDescription', { defaultMessage: 'Network Share Discovery (T1135)' } ), id: 'T1135', @@ -3473,7 +3524,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.networkSniffingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.networkSniffingDescription', { defaultMessage: 'Network Sniffing (T1040)' } ), id: 'T1040', @@ -3484,7 +3535,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.newServiceDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.newServiceDescription', { defaultMessage: 'New Service (T1050)' } ), id: 'T1050', @@ -3495,7 +3546,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.obfuscatedFilesOrInformationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.obfuscatedFilesOrInformationDescription', { defaultMessage: 'Obfuscated Files or Information (T1027)' } ), id: 'T1027', @@ -3506,7 +3557,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.officeApplicationStartupDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.officeApplicationStartupDescription', { defaultMessage: 'Office Application Startup (T1137)' } ), id: 'T1137', @@ -3517,7 +3568,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.parentPidSpoofingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.parentPidSpoofingDescription', { defaultMessage: 'Parent PID Spoofing (T1502)' } ), id: 'T1502', @@ -3528,7 +3579,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.passTheHashDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.passTheHashDescription', { defaultMessage: 'Pass the Hash (T1075)' } ), id: 'T1075', @@ -3539,7 +3590,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.passTheTicketDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.passTheTicketDescription', { defaultMessage: 'Pass the Ticket (T1097)' } ), id: 'T1097', @@ -3550,7 +3601,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.passwordFilterDllDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.passwordFilterDllDescription', { defaultMessage: 'Password Filter DLL (T1174)' } ), id: 'T1174', @@ -3561,7 +3612,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.passwordPolicyDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.passwordPolicyDiscoveryDescription', { defaultMessage: 'Password Policy Discovery (T1201)' } ), id: 'T1201', @@ -3572,7 +3623,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.pathInterceptionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.pathInterceptionDescription', { defaultMessage: 'Path Interception (T1034)' } ), id: 'T1034', @@ -3583,7 +3634,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.peripheralDeviceDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.peripheralDeviceDiscoveryDescription', { defaultMessage: 'Peripheral Device Discovery (T1120)' } ), id: 'T1120', @@ -3594,7 +3645,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.permissionGroupsDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.permissionGroupsDiscoveryDescription', { defaultMessage: 'Permission Groups Discovery (T1069)' } ), id: 'T1069', @@ -3605,7 +3656,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.plistModificationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.plistModificationDescription', { defaultMessage: 'Plist Modification (T1150)' } ), id: 'T1150', @@ -3616,7 +3667,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.portKnockingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.portKnockingDescription', { defaultMessage: 'Port Knocking (T1205)' } ), id: 'T1205', @@ -3627,7 +3678,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.portMonitorsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.portMonitorsDescription', { defaultMessage: 'Port Monitors (T1013)' } ), id: 'T1013', @@ -3638,7 +3689,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.powerShellDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.powerShellDescription', { defaultMessage: 'PowerShell (T1086)' } ), id: 'T1086', @@ -3649,7 +3700,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.powerShellProfileDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.powerShellProfileDescription', { defaultMessage: 'PowerShell Profile (T1504)' } ), id: 'T1504', @@ -3660,7 +3711,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.privateKeysDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.privateKeysDescription', { defaultMessage: 'Private Keys (T1145)' } ), id: 'T1145', @@ -3671,7 +3722,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.processDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.processDiscoveryDescription', { defaultMessage: 'Process Discovery (T1057)' } ), id: 'T1057', @@ -3682,7 +3733,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.processDoppelgangingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.processDoppelgangingDescription', { defaultMessage: 'Process Doppelgänging (T1186)' } ), id: 'T1186', @@ -3693,7 +3744,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.processHollowingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.processHollowingDescription', { defaultMessage: 'Process Hollowing (T1093)' } ), id: 'T1093', @@ -3704,7 +3755,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.processInjectionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.processInjectionDescription', { defaultMessage: 'Process Injection (T1055)' } ), id: 'T1055', @@ -3715,7 +3766,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.queryRegistryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.queryRegistryDescription', { defaultMessage: 'Query Registry (T1012)' } ), id: 'T1012', @@ -3725,9 +3776,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'queryRegistry', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.rcCommonDescription', { - defaultMessage: 'Rc.common (T1163)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.rcCommonDescription', + { + defaultMessage: 'Rc.common (T1163)', + } + ), id: 'T1163', name: 'Rc.common', reference: 'https://attack.mitre.org/techniques/T1163', @@ -3736,7 +3790,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.reOpenedApplicationsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.reOpenedApplicationsDescription', { defaultMessage: 'Re-opened Applications (T1164)' } ), id: 'T1164', @@ -3747,7 +3801,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.redundantAccessDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.redundantAccessDescription', { defaultMessage: 'Redundant Access (T1108)' } ), id: 'T1108', @@ -3758,7 +3812,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.registryRunKeysStartupFolderDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.registryRunKeysStartupFolderDescription', { defaultMessage: 'Registry Run Keys / Startup Folder (T1060)' } ), id: 'T1060', @@ -3769,7 +3823,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.regsvcsRegasmDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.regsvcsRegasmDescription', { defaultMessage: 'Regsvcs/Regasm (T1121)' } ), id: 'T1121', @@ -3779,9 +3833,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'regsvcsRegasm', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.regsvr32Description', { - defaultMessage: 'Regsvr32 (T1117)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.regsvr32Description', + { + defaultMessage: 'Regsvr32 (T1117)', + } + ), id: 'T1117', name: 'Regsvr32', reference: 'https://attack.mitre.org/techniques/T1117', @@ -3790,7 +3847,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.remoteAccessToolsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.remoteAccessToolsDescription', { defaultMessage: 'Remote Access Tools (T1219)' } ), id: 'T1219', @@ -3801,7 +3858,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.remoteDesktopProtocolDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.remoteDesktopProtocolDescription', { defaultMessage: 'Remote Desktop Protocol (T1076)' } ), id: 'T1076', @@ -3812,7 +3869,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.remoteFileCopyDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.remoteFileCopyDescription', { defaultMessage: 'Remote File Copy (T1105)' } ), id: 'T1105', @@ -3823,7 +3880,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.remoteServicesDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.remoteServicesDescription', { defaultMessage: 'Remote Services (T1021)' } ), id: 'T1021', @@ -3834,7 +3891,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.remoteSystemDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.remoteSystemDiscoveryDescription', { defaultMessage: 'Remote System Discovery (T1018)' } ), id: 'T1018', @@ -3845,7 +3902,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.replicationThroughRemovableMediaDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.replicationThroughRemovableMediaDescription', { defaultMessage: 'Replication Through Removable Media (T1091)' } ), id: 'T1091', @@ -3856,7 +3913,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.resourceHijackingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.resourceHijackingDescription', { defaultMessage: 'Resource Hijacking (T1496)' } ), id: 'T1496', @@ -3867,7 +3924,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.revertCloudInstanceDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.revertCloudInstanceDescription', { defaultMessage: 'Revert Cloud Instance (T1536)' } ), id: 'T1536', @@ -3877,9 +3934,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'revertCloudInstance', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.rootkitDescription', { - defaultMessage: 'Rootkit (T1014)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.rootkitDescription', + { + defaultMessage: 'Rootkit (T1014)', + } + ), id: 'T1014', name: 'Rootkit', reference: 'https://attack.mitre.org/techniques/T1014', @@ -3887,9 +3947,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'rootkit', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.rundll32Description', { - defaultMessage: 'Rundll32 (T1085)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.rundll32Description', + { + defaultMessage: 'Rundll32 (T1085)', + } + ), id: 'T1085', name: 'Rundll32', reference: 'https://attack.mitre.org/techniques/T1085', @@ -3898,7 +3961,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.runtimeDataManipulationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.runtimeDataManipulationDescription', { defaultMessage: 'Runtime Data Manipulation (T1494)' } ), id: 'T1494', @@ -3909,7 +3972,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.sidHistoryInjectionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.sidHistoryInjectionDescription', { defaultMessage: 'SID-History Injection (T1178)' } ), id: 'T1178', @@ -3920,7 +3983,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.sipAndTrustProviderHijackingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.sipAndTrustProviderHijackingDescription', { defaultMessage: 'SIP and Trust Provider Hijacking (T1198)' } ), id: 'T1198', @@ -3931,7 +3994,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.sshHijackingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.sshHijackingDescription', { defaultMessage: 'SSH Hijacking (T1184)' } ), id: 'T1184', @@ -3942,7 +4005,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.scheduledTaskDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.scheduledTaskDescription', { defaultMessage: 'Scheduled Task (T1053)' } ), id: 'T1053', @@ -3953,7 +4016,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.scheduledTransferDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.scheduledTransferDescription', { defaultMessage: 'Scheduled Transfer (T1029)' } ), id: 'T1029', @@ -3964,7 +4027,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.screenCaptureDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.screenCaptureDescription', { defaultMessage: 'Screen Capture (T1113)' } ), id: 'T1113', @@ -3975,7 +4038,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.screensaverDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.screensaverDescription', { defaultMessage: 'Screensaver (T1180)' } ), id: 'T1180', @@ -3985,9 +4048,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'screensaver', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.scriptingDescription', { - defaultMessage: 'Scripting (T1064)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.scriptingDescription', + { + defaultMessage: 'Scripting (T1064)', + } + ), id: 'T1064', name: 'Scripting', reference: 'https://attack.mitre.org/techniques/T1064', @@ -3996,7 +4062,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.securitySoftwareDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.securitySoftwareDiscoveryDescription', { defaultMessage: 'Security Software Discovery (T1063)' } ), id: 'T1063', @@ -4007,7 +4073,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.securitySupportProviderDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.securitySupportProviderDescription', { defaultMessage: 'Security Support Provider (T1101)' } ), id: 'T1101', @@ -4018,7 +4084,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.securitydMemoryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.securitydMemoryDescription', { defaultMessage: 'Securityd Memory (T1167)' } ), id: 'T1167', @@ -4029,7 +4095,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.serverSoftwareComponentDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.serverSoftwareComponentDescription', { defaultMessage: 'Server Software Component (T1505)' } ), id: 'T1505', @@ -4040,7 +4106,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.serviceExecutionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.serviceExecutionDescription', { defaultMessage: 'Service Execution (T1035)' } ), id: 'T1035', @@ -4051,7 +4117,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.serviceRegistryPermissionsWeaknessDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.serviceRegistryPermissionsWeaknessDescription', { defaultMessage: 'Service Registry Permissions Weakness (T1058)' } ), id: 'T1058', @@ -4062,7 +4128,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.serviceStopDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.serviceStopDescription', { defaultMessage: 'Service Stop (T1489)' } ), id: 'T1489', @@ -4073,7 +4139,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.setuidAndSetgidDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.setuidAndSetgidDescription', { defaultMessage: 'Setuid and Setgid (T1166)' } ), id: 'T1166', @@ -4084,7 +4150,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.sharedWebrootDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.sharedWebrootDescription', { defaultMessage: 'Shared Webroot (T1051)' } ), id: 'T1051', @@ -4095,7 +4161,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.shortcutModificationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.shortcutModificationDescription', { defaultMessage: 'Shortcut Modification (T1023)' } ), id: 'T1023', @@ -4106,7 +4172,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.signedBinaryProxyExecutionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.signedBinaryProxyExecutionDescription', { defaultMessage: 'Signed Binary Proxy Execution (T1218)' } ), id: 'T1218', @@ -4117,7 +4183,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.signedScriptProxyExecutionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.signedScriptProxyExecutionDescription', { defaultMessage: 'Signed Script Proxy Execution (T1216)' } ), id: 'T1216', @@ -4128,7 +4194,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.softwareDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.softwareDiscoveryDescription', { defaultMessage: 'Software Discovery (T1518)' } ), id: 'T1518', @@ -4139,7 +4205,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.softwarePackingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.softwarePackingDescription', { defaultMessage: 'Software Packing (T1045)' } ), id: 'T1045', @@ -4149,9 +4215,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'softwarePacking', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.sourceDescription', { - defaultMessage: 'Source (T1153)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.sourceDescription', + { + defaultMessage: 'Source (T1153)', + } + ), id: 'T1153', name: 'Source', reference: 'https://attack.mitre.org/techniques/T1153', @@ -4160,7 +4229,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.spaceAfterFilenameDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.spaceAfterFilenameDescription', { defaultMessage: 'Space after Filename (T1151)' } ), id: 'T1151', @@ -4171,7 +4240,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.spearphishingAttachmentDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.spearphishingAttachmentDescription', { defaultMessage: 'Spearphishing Attachment (T1193)' } ), id: 'T1193', @@ -4182,7 +4251,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.spearphishingLinkDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.spearphishingLinkDescription', { defaultMessage: 'Spearphishing Link (T1192)' } ), id: 'T1192', @@ -4193,7 +4262,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.spearphishingViaServiceDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.spearphishingViaServiceDescription', { defaultMessage: 'Spearphishing via Service (T1194)' } ), id: 'T1194', @@ -4204,7 +4273,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.standardApplicationLayerProtocolDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.standardApplicationLayerProtocolDescription', { defaultMessage: 'Standard Application Layer Protocol (T1071)' } ), id: 'T1071', @@ -4215,7 +4284,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.standardCryptographicProtocolDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.standardCryptographicProtocolDescription', { defaultMessage: 'Standard Cryptographic Protocol (T1032)' } ), id: 'T1032', @@ -4226,7 +4295,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.standardNonApplicationLayerProtocolDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.standardNonApplicationLayerProtocolDescription', { defaultMessage: 'Standard Non-Application Layer Protocol (T1095)' } ), id: 'T1095', @@ -4237,7 +4306,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.startupItemsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.startupItemsDescription', { defaultMessage: 'Startup Items (T1165)' } ), id: 'T1165', @@ -4248,7 +4317,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.stealApplicationAccessTokenDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.stealApplicationAccessTokenDescription', { defaultMessage: 'Steal Application Access Token (T1528)' } ), id: 'T1528', @@ -4259,7 +4328,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.stealWebSessionCookieDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.stealWebSessionCookieDescription', { defaultMessage: 'Steal Web Session Cookie (T1539)' } ), id: 'T1539', @@ -4270,7 +4339,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.storedDataManipulationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.storedDataManipulationDescription', { defaultMessage: 'Stored Data Manipulation (T1492)' } ), id: 'T1492', @@ -4280,9 +4349,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'storedDataManipulation', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.sudoDescription', { - defaultMessage: 'Sudo (T1169)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.sudoDescription', + { + defaultMessage: 'Sudo (T1169)', + } + ), id: 'T1169', name: 'Sudo', reference: 'https://attack.mitre.org/techniques/T1169', @@ -4291,7 +4363,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.sudoCachingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.sudoCachingDescription', { defaultMessage: 'Sudo Caching (T1206)' } ), id: 'T1206', @@ -4302,7 +4374,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.supplyChainCompromiseDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.supplyChainCompromiseDescription', { defaultMessage: 'Supply Chain Compromise (T1195)' } ), id: 'T1195', @@ -4313,7 +4385,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.systemFirmwareDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.systemFirmwareDescription', { defaultMessage: 'System Firmware (T1019)' } ), id: 'T1019', @@ -4324,7 +4396,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.systemInformationDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.systemInformationDiscoveryDescription', { defaultMessage: 'System Information Discovery (T1082)' } ), id: 'T1082', @@ -4335,7 +4407,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.systemNetworkConfigurationDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.systemNetworkConfigurationDiscoveryDescription', { defaultMessage: 'System Network Configuration Discovery (T1016)' } ), id: 'T1016', @@ -4346,7 +4418,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.systemNetworkConnectionsDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.systemNetworkConnectionsDiscoveryDescription', { defaultMessage: 'System Network Connections Discovery (T1049)' } ), id: 'T1049', @@ -4357,7 +4429,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.systemOwnerUserDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.systemOwnerUserDiscoveryDescription', { defaultMessage: 'System Owner/User Discovery (T1033)' } ), id: 'T1033', @@ -4368,7 +4440,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.systemServiceDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.systemServiceDiscoveryDescription', { defaultMessage: 'System Service Discovery (T1007)' } ), id: 'T1007', @@ -4379,7 +4451,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.systemShutdownRebootDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.systemShutdownRebootDescription', { defaultMessage: 'System Shutdown/Reboot (T1529)' } ), id: 'T1529', @@ -4390,7 +4462,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.systemTimeDiscoveryDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.systemTimeDiscoveryDescription', { defaultMessage: 'System Time Discovery (T1124)' } ), id: 'T1124', @@ -4401,7 +4473,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.systemdServiceDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.systemdServiceDescription', { defaultMessage: 'Systemd Service (T1501)' } ), id: 'T1501', @@ -4412,7 +4484,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.taintSharedContentDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.taintSharedContentDescription', { defaultMessage: 'Taint Shared Content (T1080)' } ), id: 'T1080', @@ -4423,7 +4495,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.templateInjectionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.templateInjectionDescription', { defaultMessage: 'Template Injection (T1221)' } ), id: 'T1221', @@ -4434,7 +4506,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.thirdPartySoftwareDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.thirdPartySoftwareDescription', { defaultMessage: 'Third-party Software (T1072)' } ), id: 'T1072', @@ -4445,7 +4517,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.timeProvidersDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.timeProvidersDescription', { defaultMessage: 'Time Providers (T1209)' } ), id: 'T1209', @@ -4455,9 +4527,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'timeProviders', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.timestompDescription', { - defaultMessage: 'Timestomp (T1099)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.timestompDescription', + { + defaultMessage: 'Timestomp (T1099)', + } + ), id: 'T1099', name: 'Timestomp', reference: 'https://attack.mitre.org/techniques/T1099', @@ -4466,7 +4541,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.transferDataToCloudAccountDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.transferDataToCloudAccountDescription', { defaultMessage: 'Transfer Data to Cloud Account (T1537)' } ), id: 'T1537', @@ -4477,7 +4552,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.transmittedDataManipulationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.transmittedDataManipulationDescription', { defaultMessage: 'Transmitted Data Manipulation (T1493)' } ), id: 'T1493', @@ -4487,9 +4562,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'transmittedDataManipulation', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.trapDescription', { - defaultMessage: 'Trap (T1154)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.trapDescription', + { + defaultMessage: 'Trap (T1154)', + } + ), id: 'T1154', name: 'Trap', reference: 'https://attack.mitre.org/techniques/T1154', @@ -4498,7 +4576,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.trustedDeveloperUtilitiesDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.trustedDeveloperUtilitiesDescription', { defaultMessage: 'Trusted Developer Utilities (T1127)' } ), id: 'T1127', @@ -4509,7 +4587,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.trustedRelationshipDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.trustedRelationshipDescription', { defaultMessage: 'Trusted Relationship (T1199)' } ), id: 'T1199', @@ -4520,7 +4598,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.twoFactorAuthenticationInterceptionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.twoFactorAuthenticationInterceptionDescription', { defaultMessage: 'Two-Factor Authentication Interception (T1111)' } ), id: 'T1111', @@ -4531,7 +4609,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.uncommonlyUsedPortDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.uncommonlyUsedPortDescription', { defaultMessage: 'Uncommonly Used Port (T1065)' } ), id: 'T1065', @@ -4542,7 +4620,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.unusedUnsupportedCloudRegionsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.unusedUnsupportedCloudRegionsDescription', { defaultMessage: 'Unused/Unsupported Cloud Regions (T1535)' } ), id: 'T1535', @@ -4553,7 +4631,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.userExecutionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.userExecutionDescription', { defaultMessage: 'User Execution (T1204)' } ), id: 'T1204', @@ -4564,7 +4642,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.validAccountsDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.validAccountsDescription', { defaultMessage: 'Valid Accounts (T1078)' } ), id: 'T1078', @@ -4575,7 +4653,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.videoCaptureDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.videoCaptureDescription', { defaultMessage: 'Video Capture (T1125)' } ), id: 'T1125', @@ -4586,7 +4664,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.virtualizationSandboxEvasionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.virtualizationSandboxEvasionDescription', { defaultMessage: 'Virtualization/Sandbox Evasion (T1497)' } ), id: 'T1497', @@ -4597,7 +4675,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.webServiceDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.webServiceDescription', { defaultMessage: 'Web Service (T1102)' } ), id: 'T1102', @@ -4608,7 +4686,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.webSessionCookieDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.webSessionCookieDescription', { defaultMessage: 'Web Session Cookie (T1506)' } ), id: 'T1506', @@ -4618,9 +4696,12 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ value: 'webSessionCookie', }, { - label: i18n.translate('xpack.siem.detectionEngine.mitreAttackTechniques.webShellDescription', { - defaultMessage: 'Web Shell (T1100)', - }), + label: i18n.translate( + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.webShellDescription', + { + defaultMessage: 'Web Shell (T1100)', + } + ), id: 'T1100', name: 'Web Shell', reference: 'https://attack.mitre.org/techniques/T1100', @@ -4629,7 +4710,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.windowsAdminSharesDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.windowsAdminSharesDescription', { defaultMessage: 'Windows Admin Shares (T1077)' } ), id: 'T1077', @@ -4640,7 +4721,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.windowsManagementInstrumentationDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.windowsManagementInstrumentationDescription', { defaultMessage: 'Windows Management Instrumentation (T1047)' } ), id: 'T1047', @@ -4651,7 +4732,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.windowsManagementInstrumentationEventSubscriptionDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.windowsManagementInstrumentationEventSubscriptionDescription', { defaultMessage: 'Windows Management Instrumentation Event Subscription (T1084)' } ), id: 'T1084', @@ -4662,7 +4743,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.windowsRemoteManagementDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.windowsRemoteManagementDescription', { defaultMessage: 'Windows Remote Management (T1028)' } ), id: 'T1028', @@ -4673,7 +4754,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.winlogonHelperDllDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.winlogonHelperDllDescription', { defaultMessage: 'Winlogon Helper DLL (T1004)' } ), id: 'T1004', @@ -4684,7 +4765,7 @@ export const techniquesOptions: MitreTechniquesOptions[] = [ }, { label: i18n.translate( - 'xpack.siem.detectionEngine.mitreAttackTechniques.xslScriptProcessingDescription', + 'xpack.securitySolution.detectionEngine.mitreAttackTechniques.xslScriptProcessingDescription', { defaultMessage: 'XSL Script Processing (T1220)' } ), id: 'T1220', diff --git a/x-pack/plugins/siem/public/alerts/mitre/types.ts b/x-pack/plugins/security_solution/public/alerts/mitre/types.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/mitre/types.ts rename to x-pack/plugins/security_solution/public/alerts/mitre/types.ts diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/detection_engine.test.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/detection_engine.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/detection_engine.test.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/detection_engine.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/detection_engine.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/detection_engine.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/detection_engine.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/detection_engine.tsx diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/detection_engine_empty_page.test.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/detection_engine_empty_page.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/detection_engine_empty_page.test.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/detection_engine_empty_page.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/detection_engine_empty_page.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/detection_engine_empty_page.tsx similarity index 92% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/detection_engine_empty_page.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/detection_engine_empty_page.tsx index 9632ddfeadc0d..0c58f5620964b 100644 --- a/x-pack/plugins/siem/public/alerts/pages/detection_engine/detection_engine_empty_page.tsx +++ b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/detection_engine_empty_page.tsx @@ -9,12 +9,13 @@ import React from 'react'; import { useKibana } from '../../../common/lib/kibana'; import { EmptyPage } from '../../../common/components/empty_page'; import * as i18n from '../../../common/translations'; +import { ADD_DATA_PATH } from '../../../../common/constants'; export const DetectionEngineEmptyPage = React.memo(() => ( void; + rulesCustomInstalled: number | null; + rulesInstalled: number | null; + rulesNotInstalled: number | null; + rulesNotUpdated: number | null; + setRefreshRulesData: (refreshRule: (refreshPrePackagedRule?: boolean) => void) => void; +} + +export enum AllRulesTabs { + rules = 'rules', + monitoring = 'monitoring', +} + +const allRulesTabs = [ + { + id: AllRulesTabs.rules, + name: i18n.RULES_TAB, + disabled: false, + }, + { + id: AllRulesTabs.monitoring, + name: i18n.MONITORING_TAB, + disabled: false, + }, +]; + +/** + * Table Component for displaying all Rules for a given cluster. Provides the ability to filter + * by name, sort by enabled, and perform the following actions: + * * Enable/Disable + * * Duplicate + * * Delete + * * Import/Export + */ +export const AllRules = React.memo( + ({ + createPrePackagedRules, + hasNoPermissions, + loading, + loadingCreatePrePackagedRules, + refetchPrePackagedRulesStatus, + rulesCustomInstalled, + rulesInstalled, + rulesNotInstalled, + rulesNotUpdated, + setRefreshRulesData, + }) => { + const [initLoading, setInitLoading] = useState(true); + const tableRef = useRef(); + const [ + { + exportRuleIds, + filterOptions, + loadingRuleIds, + loadingRulesAction, + pagination, + rules, + selectedRuleIds, + }, + dispatch, + ] = useReducer(allRulesReducer(tableRef), initialState); + const { loading: isLoadingRulesStatuses, rulesStatuses } = useRulesStatuses(rules); + const history = useHistory(); + const [, dispatchToaster] = useStateToaster(); + const mlCapabilities = useMlCapabilities(); + const [allRulesTab, setAllRulesTab] = useState(AllRulesTabs.rules); + + // TODO: Refactor license check + hasMlAdminPermissions to common check + const hasMlPermissions = + mlCapabilities.isPlatinumOrTrialLicense && hasMlAdminPermissions(mlCapabilities); + + const setRules = useCallback((newRules: Rule[], newPagination: Partial) => { + dispatch({ + type: 'setRules', + rules: newRules, + pagination: newPagination, + }); + }, []); + + const [isLoadingRules, , reFetchRulesData] = useRules({ + pagination, + filterOptions, + refetchPrePackagedRulesStatus, + dispatchRulesInReducer: setRules, + }); + + const sorting = useMemo( + (): SortingType => ({ sort: { field: 'enabled', direction: filterOptions.sortOrder } }), + [filterOptions.sortOrder] + ); + + const prePackagedRuleStatus = getPrePackagedRuleStatus( + rulesInstalled, + rulesNotInstalled, + rulesNotUpdated + ); + + const getBatchItemsPopoverContent = useCallback( + (closePopover: () => void) => ( + + ), + [ + dispatch, + dispatchToaster, + hasMlPermissions, + loadingRuleIds, + reFetchRulesData, + rules, + selectedRuleIds, + ] + ); + + const paginationMemo = useMemo( + () => ({ + pageIndex: pagination.page - 1, + pageSize: pagination.perPage, + totalItemCount: pagination.total, + pageSizeOptions: [5, 10, 20, 50, 100, 200, 300], + }), + [pagination] + ); + + const tableOnChangeCallback = useCallback( + ({ page, sort }: EuiBasicTableOnChange) => { + dispatch({ + type: 'updateFilterOptions', + filterOptions: { + sortField: SORT_FIELD, // Only enabled is supported for sorting currently + sortOrder: sort?.direction ?? 'desc', + }, + pagination: { page: page.index + 1, perPage: page.size }, + }); + }, + [dispatch] + ); + + const rulesColumns = useMemo(() => { + return getColumns({ + dispatch, + dispatchToaster, + history, + hasMlPermissions, + hasNoPermissions, + loadingRuleIds: + loadingRulesAction != null && + (loadingRulesAction === 'enable' || loadingRulesAction === 'disable') + ? loadingRuleIds + : [], + reFetchRules: reFetchRulesData, + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ + dispatch, + dispatchToaster, + hasMlPermissions, + history, + loadingRuleIds, + loadingRulesAction, + reFetchRulesData, + ]); + + const monitoringColumns = useMemo(() => getMonitoringColumns(), []); + + useEffect(() => { + if (reFetchRulesData != null) { + setRefreshRulesData(reFetchRulesData); + } + }, [reFetchRulesData, setRefreshRulesData]); + + useEffect(() => { + if (initLoading && !loading && !isLoadingRules && !isLoadingRulesStatuses) { + setInitLoading(false); + } + }, [initLoading, loading, isLoadingRules, isLoadingRulesStatuses]); + + const handleCreatePrePackagedRules = useCallback(async () => { + if (createPrePackagedRules != null && reFetchRulesData != null) { + await createPrePackagedRules(); + reFetchRulesData(true); + } + }, [createPrePackagedRules, reFetchRulesData]); + + const euiBasicTableSelectionProps = useMemo( + () => ({ + selectable: (item: Rule) => !loadingRuleIds.includes(item.id), + onSelectionChange: (selected: Rule[]) => + dispatch({ type: 'selectedRuleIds', ids: selected.map((r) => r.id) }), + }), + [loadingRuleIds] + ); + + const onFilterChangedCallback = useCallback((newFilterOptions: Partial) => { + dispatch({ + type: 'updateFilterOptions', + filterOptions: { + ...newFilterOptions, + }, + pagination: { page: 1 }, + }); + }, []); + + const isLoadingAnActionOnRule = useMemo(() => { + if ( + loadingRuleIds.length > 0 && + (loadingRulesAction === 'disable' || loadingRulesAction === 'enable') + ) { + return false; + } else if (loadingRuleIds.length > 0) { + return true; + } + return false; + }, [loadingRuleIds, loadingRulesAction]); + + const tabs = useMemo( + () => ( + + {allRulesTabs.map((tab) => ( + setAllRulesTab(tab.id)} + isSelected={tab.id === allRulesTab} + disabled={tab.disabled} + key={tab.id} + > + {tab.name} + + ))} + + ), + // eslint-disable-next-line react-hooks/exhaustive-deps + [allRulesTabs, allRulesTab, setAllRulesTab] + ); + + return ( + <> + { + dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); + dispatchToaster({ + type: 'addToaster', + toast: { + id: uuid.v4(), + title: i18n.SUCCESSFULLY_EXPORTED_RULES(exportCount), + color: 'success', + iconType: 'check', + }, + }); + }} + exportSelectedData={exportRules} + /> + + {tabs} + + + + <> + + + + + {(loading || isLoadingRules || isLoadingAnActionOnRule || isLoadingRulesStatuses) && + !initLoading && ( + + )} + {rulesCustomInstalled != null && + rulesCustomInstalled === 0 && + prePackagedRuleStatus === 'ruleNotInstalled' && + !initLoading && ( + + )} + {initLoading && ( + + )} + {showRulesTable({ rulesCustomInstalled, rulesInstalled }) && !initLoading && ( + <> + + + + + {i18n.SHOWING_RULES(pagination.total ?? 0)} + + + + + {i18n.SELECTED_RULES(selectedRuleIds.length)} + {!hasNoPermissions && ( + + {i18n.BATCH_ACTIONS} + + )} + reFetchRulesData(true)} + > + {i18n.REFRESH} + + + + + + + )} + + + + ); + } +); + +AllRules.displayName = 'AllRules'; diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/all/reducer.ts b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/all/reducer.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/all/reducer.ts rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/all/reducer.ts diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.test.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.test.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.tsx similarity index 98% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.tsx index 2bc19ae45a078..c65271c3cc014 100644 --- a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.tsx +++ b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.tsx @@ -45,6 +45,7 @@ const RulesTableFiltersComponent = ({ useEffect(() => { reFetchTags(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [rulesCustomInstalled, rulesInstalled]); // Propagate filter changes to parent diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.test.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.test.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.tsx diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/create/helpers.test.ts b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/create/helpers.test.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/create/helpers.test.ts rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/create/helpers.test.ts diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/create/helpers.ts b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/create/helpers.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/create/helpers.ts rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/create/helpers.ts diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/create/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/create/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/create/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/create/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/create/index.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/create/index.tsx new file mode 100644 index 0000000000000..de7c99acee6e5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/create/index.tsx @@ -0,0 +1,431 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiButtonEmpty, EuiAccordion, EuiHorizontalRule, EuiPanel, EuiSpacer } from '@elastic/eui'; +import React, { useCallback, useRef, useState, useMemo } from 'react'; +import { Redirect } from 'react-router-dom'; +import styled, { StyledComponent } from 'styled-components'; + +import { usePersistRule } from '../../../../../alerts/containers/detection_engine/rules'; + +import { DETECTION_ENGINE_PAGE_NAME } from '../../../../../common/components/link_to/redirect_to_detection_engine'; +import { WrapperPage } from '../../../../../common/components/wrapper_page'; +import { displaySuccessToast, useStateToaster } from '../../../../../common/components/toasters'; +import { SpyRoute } from '../../../../../common/utils/route/spy_routes'; +import { useUserInfo } from '../../../../components/user_info'; +import { AccordionTitle } from '../../../../components/rules/accordion_title'; +import { FormData, FormHook } from '../../../../../shared_imports'; +import { StepAboutRule } from '../../../../components/rules/step_about_rule'; +import { StepDefineRule } from '../../../../components/rules/step_define_rule'; +import { StepScheduleRule } from '../../../../components/rules/step_schedule_rule'; +import { StepRuleActions } from '../../../../components/rules/step_rule_actions'; +import { DetectionEngineHeaderPage } from '../../../../components/detection_engine_header_page'; +import * as RuleI18n from '../translations'; +import { redirectToDetections, getActionMessageParams, userHasNoPermissions } from '../helpers'; +import { + AboutStepRule, + DefineStepRule, + RuleStep, + RuleStepData, + ScheduleStepRule, + ActionsStepRule, +} from '../types'; +import { formatRule } from './helpers'; +import * as i18n from './translations'; + +const stepsRuleOrder = [ + RuleStep.defineRule, + RuleStep.aboutRule, + RuleStep.scheduleRule, + RuleStep.ruleActions, +]; + +const MyEuiPanel = styled(EuiPanel)<{ + zindex?: number; +}>` + position: relative; + z-index: ${(props) => props.zindex}; /* ugly fix to allow searchBar to overflow the EuiPanel */ + + > .euiAccordion > .euiAccordion__triggerWrapper { + .euiAccordion__button { + cursor: default !important; + &:hover { + text-decoration: none !important; + } + } + + .euiAccordion__iconWrapper { + display: none; + } + } +`; + +MyEuiPanel.displayName = 'MyEuiPanel'; + +const StepDefineRuleAccordion: StyledComponent< + typeof EuiAccordion, + any, // eslint-disable-line + { ref: React.MutableRefObject }, + never +> = styled(EuiAccordion)` + .euiAccordion__childWrapper { + overflow: visible; + } +`; + +StepDefineRuleAccordion.displayName = 'StepDefineRuleAccordion'; + +const CreateRulePageComponent: React.FC = () => { + const { + loading, + isSignalIndexExists, + isAuthenticated, + hasEncryptionKey, + canUserCRUD, + } = useUserInfo(); + const [, dispatchToaster] = useStateToaster(); + const [openAccordionId, setOpenAccordionId] = useState(RuleStep.defineRule); + const defineRuleRef = useRef(null); + const aboutRuleRef = useRef(null); + const scheduleRuleRef = useRef(null); + const ruleActionsRef = useRef(null); + const stepsForm = useRef | null>>({ + [RuleStep.defineRule]: null, + [RuleStep.aboutRule]: null, + [RuleStep.scheduleRule]: null, + [RuleStep.ruleActions]: null, + }); + const stepsData = useRef>({ + [RuleStep.defineRule]: { isValid: false, data: {} }, + [RuleStep.aboutRule]: { isValid: false, data: {} }, + [RuleStep.scheduleRule]: { isValid: false, data: {} }, + [RuleStep.ruleActions]: { isValid: false, data: {} }, + }); + const [isStepRuleInReadOnlyView, setIsStepRuleInEditView] = useState>({ + [RuleStep.defineRule]: false, + [RuleStep.aboutRule]: false, + [RuleStep.scheduleRule]: false, + [RuleStep.ruleActions]: false, + }); + const [{ isLoading, isSaved }, setRule] = usePersistRule(); + const actionMessageParams = useMemo( + () => + getActionMessageParams((stepsData.current['define-rule'].data as DefineStepRule).ruleType), + // eslint-disable-next-line react-hooks/exhaustive-deps + [stepsData.current['define-rule'].data] + ); + + const setStepData = useCallback( + (step: RuleStep, data: unknown, isValid: boolean) => { + stepsData.current[step] = { ...stepsData.current[step], data, isValid }; + if (isValid) { + const stepRuleIdx = stepsRuleOrder.findIndex((item) => step === item); + if ([0, 1, 2].includes(stepRuleIdx)) { + if (isStepRuleInReadOnlyView[stepsRuleOrder[stepRuleIdx + 1]]) { + setOpenAccordionId(stepsRuleOrder[stepRuleIdx + 1]); + setIsStepRuleInEditView({ + ...isStepRuleInReadOnlyView, + [step]: true, + [stepsRuleOrder[stepRuleIdx + 1]]: false, + }); + } else if (openAccordionId !== stepsRuleOrder[stepRuleIdx + 1]) { + setIsStepRuleInEditView({ + ...isStepRuleInReadOnlyView, + [step]: true, + }); + openCloseAccordion(stepsRuleOrder[stepRuleIdx + 1]); + setOpenAccordionId(stepsRuleOrder[stepRuleIdx + 1]); + } + } else if ( + stepRuleIdx === 3 && + stepsData.current[RuleStep.defineRule].isValid && + stepsData.current[RuleStep.aboutRule].isValid && + stepsData.current[RuleStep.scheduleRule].isValid + ) { + setRule( + formatRule( + stepsData.current[RuleStep.defineRule].data as DefineStepRule, + stepsData.current[RuleStep.aboutRule].data as AboutStepRule, + stepsData.current[RuleStep.scheduleRule].data as ScheduleStepRule, + stepsData.current[RuleStep.ruleActions].data as ActionsStepRule + ) + ); + } + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [isStepRuleInReadOnlyView, openAccordionId, stepsData.current, setRule] + ); + + const setStepsForm = useCallback((step: RuleStep, form: FormHook) => { + stepsForm.current[step] = form; + }, []); + + const getAccordionType = useCallback( + (accordionId: RuleStep) => { + if (accordionId === openAccordionId) { + return 'active'; + } else if (stepsData.current[accordionId].isValid) { + return 'valid'; + } + return 'passive'; + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [openAccordionId, stepsData.current] + ); + + const defineRuleButton = ( + + ); + + const aboutRuleButton = ( + + ); + + const scheduleRuleButton = ( + + ); + + const ruleActionsButton = ( + + ); + + const openCloseAccordion = (accordionId: RuleStep | null) => { + if (accordionId != null) { + if (accordionId === RuleStep.defineRule && defineRuleRef.current != null) { + defineRuleRef.current.onToggle(); + } else if (accordionId === RuleStep.aboutRule && aboutRuleRef.current != null) { + aboutRuleRef.current.onToggle(); + } else if (accordionId === RuleStep.scheduleRule && scheduleRuleRef.current != null) { + scheduleRuleRef.current.onToggle(); + } else if (accordionId === RuleStep.ruleActions && ruleActionsRef.current != null) { + ruleActionsRef.current.onToggle(); + } + } + }; + + // eslint-disable-next-line react-hooks/rules-of-hooks + const manageAccordions = useCallback( + (id: RuleStep, isOpen: boolean) => { + const activeRuleIdx = stepsRuleOrder.findIndex((step) => step === openAccordionId); + const stepRuleIdx = stepsRuleOrder.findIndex((step) => step === id); + + if ((id === openAccordionId || stepRuleIdx < activeRuleIdx) && !isOpen) { + openCloseAccordion(id); + } else if (stepRuleIdx >= activeRuleIdx) { + if ( + openAccordionId !== id && + !stepsData.current[openAccordionId].isValid && + !isStepRuleInReadOnlyView[id] && + isOpen + ) { + openCloseAccordion(id); + } + } + }, + [isStepRuleInReadOnlyView, openAccordionId, stepsData] + ); + + // eslint-disable-next-line react-hooks/rules-of-hooks + const manageIsEditable = useCallback( + async (id: RuleStep) => { + const activeForm = await stepsForm.current[openAccordionId]?.submit(); + if (activeForm != null && activeForm?.isValid) { + stepsData.current[openAccordionId] = { + ...stepsData.current[openAccordionId], + data: activeForm.data, + isValid: activeForm.isValid, + }; + setOpenAccordionId(id); + setIsStepRuleInEditView({ + ...isStepRuleInReadOnlyView, + [openAccordionId]: true, + [id]: false, + }); + } + }, + [isStepRuleInReadOnlyView, openAccordionId] + ); + + if (isSaved) { + const ruleName = (stepsData.current[RuleStep.aboutRule].data as AboutStepRule).name; + displaySuccessToast(i18n.SUCCESSFULLY_CREATED_RULES(ruleName), dispatchToaster); + return ; + } + + if (redirectToDetections(isSignalIndexExists, isAuthenticated, hasEncryptionKey)) { + return ; + } else if (userHasNoPermissions(canUserCRUD)) { + return ; + } + + return ( + <> + + + + + {i18n.EDIT_RULE} + + ) + } + > + + + + + + + + {i18n.EDIT_RULE} + + ) + } + > + + + + + + + + {i18n.EDIT_RULE} + + ) + } + > + + + + + + + + {i18n.EDIT_RULE} + + ) + } + > + + + + + + + + + ); +}; + +export const CreateRulePage = React.memo(CreateRulePageComponent); diff --git a/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/create/translations.ts b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/create/translations.ts new file mode 100644 index 0000000000000..dbcd05470b5cd --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/create/translations.ts @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const PAGE_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.pageTitle', + { + defaultMessage: 'Create new rule', + } +); + +export const BACK_TO_RULES = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.backToRulesDescription', + { + defaultMessage: 'Back to detection rules', + } +); + +export const EDIT_RULE = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.editRuleButton', + { + defaultMessage: 'Edit', + } +); + +export const SUCCESSFULLY_CREATED_RULES = (ruleName: string) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.create.successfullyCreatedRuleTitle', + { + values: { ruleName }, + defaultMessage: '{ruleName} was created', + } + ); diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/details/failure_history.test.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/failure_history.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/details/failure_history.test.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/failure_history.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/details/failure_history.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/failure_history.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/details/failure_history.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/failure_history.tsx diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/details/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/details/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/index.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/index.tsx new file mode 100644 index 0000000000000..43792e8bd19f4 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/index.tsx @@ -0,0 +1,431 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/* eslint-disable react-hooks/rules-of-hooks */ + +import { + EuiButton, + EuiLoadingSpinner, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiTab, + EuiTabs, + EuiToolTip, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import React, { FC, memo, useCallback, useMemo, useState } from 'react'; +import { Redirect, useParams } from 'react-router-dom'; +import { StickyContainer } from 'react-sticky'; +import { connect, ConnectedProps } from 'react-redux'; + +import { UpdateDateRange } from '../../../../../common/components/charts/common'; +import { FiltersGlobal } from '../../../../../common/components/filters_global'; +import { FormattedDate } from '../../../../../common/components/formatted_date'; +import { + getEditRuleUrl, + getRulesUrl, + DETECTION_ENGINE_PAGE_NAME, +} from '../../../../../common/components/link_to/redirect_to_detection_engine'; +import { SiemSearchBar } from '../../../../../common/components/search_bar'; +import { WrapperPage } from '../../../../../common/components/wrapper_page'; +import { useRule } from '../../../../../alerts/containers/detection_engine/rules'; + +import { + indicesExistOrDataTemporarilyUnavailable, + WithSource, +} from '../../../../../common/containers/source'; +import { SpyRoute } from '../../../../../common/utils/route/spy_routes'; + +import { StepAboutRuleToggleDetails } from '../../../../components/rules/step_about_rule_details'; +import { DetectionEngineHeaderPage } from '../../../../components/detection_engine_header_page'; +import { AlertsHistogramPanel } from '../../../../components/alerts_histogram_panel'; +import { AlertsTable } from '../../../../components/alerts_table'; +import { useUserInfo } from '../../../../components/user_info'; +import { DetectionEngineEmptyPage } from '../../detection_engine_empty_page'; +import { useAlertInfo } from '../../../../components/alerts_info'; +import { StepDefineRule } from '../../../../components/rules/step_define_rule'; +import { StepScheduleRule } from '../../../../components/rules/step_schedule_rule'; +import { buildAlertsRuleIdFilter } from '../../../../components/alerts_table/default_config'; +import { NoWriteAlertsCallOut } from '../../../../components/no_write_alerts_callout'; +import * as detectionI18n from '../../translations'; +import { ReadOnlyCallOut } from '../../../../components/rules/read_only_callout'; +import { RuleSwitch } from '../../../../components/rules/rule_switch'; +import { StepPanel } from '../../../../components/rules/step_panel'; +import { getStepsData, redirectToDetections, userHasNoPermissions } from '../helpers'; +import * as ruleI18n from '../translations'; +import * as i18n from './translations'; +import { GlobalTime } from '../../../../../common/containers/global_time'; +import { alertsHistogramOptions } from '../../../../components/alerts_histogram_panel/config'; +import { inputsSelectors } from '../../../../../common/store/inputs'; +import { State } from '../../../../../common/store'; +import { InputsRange } from '../../../../../common/store/inputs/model'; +import { setAbsoluteRangeDatePicker as dispatchSetAbsoluteRangeDatePicker } from '../../../../../common/store/inputs/actions'; +import { RuleActionsOverflow } from '../../../../components/rules/rule_actions_overflow'; +import { RuleStatusFailedCallOut } from './status_failed_callout'; +import { FailureHistory } from './failure_history'; +import { RuleStatus } from '../../../../components/rules//rule_status'; +import { useMlCapabilities } from '../../../../../common/components/ml_popover/hooks/use_ml_capabilities'; +import { hasMlAdminPermissions } from '../../../../../../common/machine_learning/has_ml_admin_permissions'; + +enum RuleDetailTabs { + alerts = 'alerts', + failures = 'failures', +} + +const ruleDetailTabs = [ + { + id: RuleDetailTabs.alerts, + name: detectionI18n.ALERT, + disabled: false, + }, + { + id: RuleDetailTabs.failures, + name: i18n.FAILURE_HISTORY_TAB, + disabled: false, + }, +]; + +export const RuleDetailsPageComponent: FC = ({ + filters, + query, + setAbsoluteRangeDatePicker, +}) => { + const { + loading, + isSignalIndexExists, + isAuthenticated, + hasEncryptionKey, + canUserCRUD, + hasIndexWrite, + signalIndexName, + } = useUserInfo(); + const { detailName: ruleId } = useParams(); + const [isLoading, rule] = useRule(ruleId); + // This is used to re-trigger api rule status when user de/activate rule + const [ruleEnabled, setRuleEnabled] = useState(null); + const [ruleDetailTab, setRuleDetailTab] = useState(RuleDetailTabs.alerts); + const { aboutRuleData, modifiedAboutRuleDetailsData, defineRuleData, scheduleRuleData } = + rule != null + ? getStepsData({ rule, detailsView: true }) + : { + aboutRuleData: null, + modifiedAboutRuleDetailsData: null, + defineRuleData: null, + scheduleRuleData: null, + }; + const [lastAlerts] = useAlertInfo({ ruleId }); + const mlCapabilities = useMlCapabilities(); + + // TODO: Refactor license check + hasMlAdminPermissions to common check + const hasMlPermissions = + mlCapabilities.isPlatinumOrTrialLicense && hasMlAdminPermissions(mlCapabilities); + + const title = isLoading === true || rule === null ? : rule.name; + const subTitle = useMemo( + () => + isLoading === true || rule === null ? ( + + ) : ( + [ + + ), + }} + />, + rule?.updated_by != null ? ( + + ), + }} + /> + ) : ( + '' + ), + ] + ), + [isLoading, rule] + ); + + const alertDefaultFilters = useMemo( + () => (ruleId != null ? buildAlertsRuleIdFilter(ruleId) : []), + [ruleId] + ); + + const alertMergedFilters = useMemo(() => [...alertDefaultFilters, ...filters], [ + alertDefaultFilters, + filters, + ]); + + const tabs = useMemo( + () => ( + + {ruleDetailTabs.map((tab) => ( + setRuleDetailTab(tab.id)} + isSelected={tab.id === ruleDetailTab} + disabled={tab.disabled} + key={tab.id} + > + {tab.name} + + ))} + + ), + // eslint-disable-next-line react-hooks/exhaustive-deps + [ruleDetailTabs, ruleDetailTab, setRuleDetailTab] + ); + const ruleError = useMemo( + () => + rule?.status === 'failed' && + ruleDetailTab === RuleDetailTabs.alerts && + rule?.last_failure_at != null ? ( + + ) : null, + // eslint-disable-next-line react-hooks/exhaustive-deps + [rule, ruleDetailTab] + ); + + const indexToAdd = useMemo(() => (signalIndexName == null ? [] : [signalIndexName]), [ + signalIndexName, + ]); + + const updateDateRangeCallback = useCallback( + ({ x }) => { + if (!x) { + return; + } + const [min, max] = x; + setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + }, + [setAbsoluteRangeDatePicker] + ); + + const handleOnChangeEnabledRule = useCallback( + (enabled: boolean) => { + if (ruleEnabled == null || enabled !== ruleEnabled) { + setRuleEnabled(enabled); + } + }, + [ruleEnabled, setRuleEnabled] + ); + + if (redirectToDetections(isSignalIndexExists, isAuthenticated, hasEncryptionKey)) { + return ; + } + + return ( + <> + {hasIndexWrite != null && !hasIndexWrite && } + {userHasNoPermissions(canUserCRUD) && } + + {({ indicesExist, indexPattern }) => { + return indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( + + {({ to, from, deleteQuery, setQuery }) => ( + + + + + + + + {detectionI18n.LAST_ALERT} + {': '} + {lastAlerts} + , + ] + : []), + , + ]} + title={title} + > + + + + + + + + + + + + {ruleI18n.EDIT_RULE_SETTINGS} + + + + + + + + + + {ruleError} + + + + + + + + + + + {defineRuleData != null && ( + + )} + + + + + + {scheduleRuleData != null && ( + + )} + + + + + + + {tabs} + + {ruleDetailTab === RuleDetailTabs.alerts && ( + <> + + + {ruleId != null && ( + + )} + + )} + {ruleDetailTab === RuleDetailTabs.failures && } + + + )} + + ) : ( + + + + + + ); + }} + + + + + ); +}; + +const makeMapStateToProps = () => { + const getGlobalInputs = inputsSelectors.globalSelector(); + return (state: State) => { + const globalInputs: InputsRange = getGlobalInputs(state); + const { query, filters } = globalInputs; + + return { + query, + filters, + }; + }; +}; + +const mapDispatchToProps = { + setAbsoluteRangeDatePicker: dispatchSetAbsoluteRangeDatePicker, +}; + +const connector = connect(makeMapStateToProps, mapDispatchToProps); + +type PropsFromRedux = ConnectedProps; + +export const RuleDetailsPage = connector(memo(RuleDetailsPageComponent)); diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/details/status_failed_callout.test.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/status_failed_callout.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/details/status_failed_callout.test.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/status_failed_callout.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/details/status_failed_callout.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/status_failed_callout.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/details/status_failed_callout.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/status_failed_callout.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/translations.ts b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/translations.ts new file mode 100644 index 0000000000000..9cf510f4a9b5d --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/details/translations.ts @@ -0,0 +1,91 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const PAGE_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleDetails.pageTitle', + { + defaultMessage: 'Rule details', + } +); + +export const BACK_TO_RULES = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleDetails.backToRulesDescription', + { + defaultMessage: 'Back to detection rules', + } +); + +export const EXPERIMENTAL = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleDetails.experimentalDescription', + { + defaultMessage: 'Experimental', + } +); + +export const ACTIVATE_RULE = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleDetails.activateRuleLabel', + { + defaultMessage: 'Activate', + } +); + +export const UNKNOWN = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleDetails.unknownDescription', + { + defaultMessage: 'Unknown', + } +); + +export const ERROR_CALLOUT_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleDetails.errorCalloutTitle', + { + defaultMessage: 'Rule failure at', + } +); + +export const FAILURE_HISTORY_TAB = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleDetails.failureHistoryTab', + { + defaultMessage: 'Failure History', + } +); + +export const LAST_FIVE_ERRORS = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleDetails.lastFiveErrorsTitle', + { + defaultMessage: 'Last five errors', + } +); + +export const COLUMN_STATUS_TYPE = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleDetails.statusTypeColumn', + { + defaultMessage: 'Type', + } +); + +export const COLUMN_FAILED_AT = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleDetails.statusFailedAtColumn', + { + defaultMessage: 'Failed at', + } +); + +export const COLUMN_FAILED_MSG = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleDetails.statusFailedMsgColumn', + { + defaultMessage: 'Failed message', + } +); + +export const TYPE_FAILED = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleDetails.statusFailedDescription', + { + defaultMessage: 'Failed', + } +); diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/edit/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/edit/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/edit/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/edit/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/edit/index.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/edit/index.tsx new file mode 100644 index 0000000000000..73e76165183c5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/edit/index.tsx @@ -0,0 +1,437 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/* eslint-disable react-hooks/rules-of-hooks */ + +import { + EuiButton, + EuiCallOut, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiTabbedContent, + EuiTabbedContentTab, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import React, { FC, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { Redirect, useParams } from 'react-router-dom'; + +import { useRule, usePersistRule } from '../../../../../alerts/containers/detection_engine/rules'; +import { WrapperPage } from '../../../../../common/components/wrapper_page'; +import { DETECTION_ENGINE_PAGE_NAME } from '../../../../../common/components/link_to/redirect_to_detection_engine'; +import { displaySuccessToast, useStateToaster } from '../../../../../common/components/toasters'; +import { SpyRoute } from '../../../../../common/utils/route/spy_routes'; +import { useUserInfo } from '../../../../components/user_info'; +import { DetectionEngineHeaderPage } from '../../../../components/detection_engine_header_page'; +import { FormHook, FormData } from '../../../../../shared_imports'; +import { StepPanel } from '../../../../components/rules/step_panel'; +import { StepAboutRule } from '../../../../components/rules/step_about_rule'; +import { StepDefineRule } from '../../../../components/rules/step_define_rule'; +import { StepScheduleRule } from '../../../../components/rules/step_schedule_rule'; +import { StepRuleActions } from '../../../../components/rules/step_rule_actions'; +import { formatRule } from '../create/helpers'; +import { + getStepsData, + redirectToDetections, + getActionMessageParams, + userHasNoPermissions, +} from '../helpers'; +import * as ruleI18n from '../translations'; +import { + RuleStep, + DefineStepRule, + AboutStepRule, + ScheduleStepRule, + ActionsStepRule, +} from '../types'; +import * as i18n from './translations'; + +interface StepRuleForm { + isValid: boolean; +} +interface AboutStepRuleForm extends StepRuleForm { + data: AboutStepRule | null; +} +interface DefineStepRuleForm extends StepRuleForm { + data: DefineStepRule | null; +} +interface ScheduleStepRuleForm extends StepRuleForm { + data: ScheduleStepRule | null; +} + +interface ActionsStepRuleForm extends StepRuleForm { + data: ActionsStepRule | null; +} + +const EditRulePageComponent: FC = () => { + const [, dispatchToaster] = useStateToaster(); + const { + loading: initLoading, + isSignalIndexExists, + isAuthenticated, + hasEncryptionKey, + canUserCRUD, + } = useUserInfo(); + const { detailName: ruleId } = useParams(); + const [loading, rule] = useRule(ruleId); + + const [initForm, setInitForm] = useState(false); + const [myAboutRuleForm, setMyAboutRuleForm] = useState({ + data: null, + isValid: false, + }); + const [myDefineRuleForm, setMyDefineRuleForm] = useState({ + data: null, + isValid: false, + }); + const [myScheduleRuleForm, setMyScheduleRuleForm] = useState({ + data: null, + isValid: false, + }); + const [myActionsRuleForm, setMyActionsRuleForm] = useState({ + data: null, + isValid: false, + }); + const [selectedTab, setSelectedTab] = useState(); + const stepsForm = useRef | null>>({ + [RuleStep.defineRule]: null, + [RuleStep.aboutRule]: null, + [RuleStep.scheduleRule]: null, + [RuleStep.ruleActions]: null, + }); + const [{ isLoading, isSaved }, setRule] = usePersistRule(); + const [tabHasError, setTabHasError] = useState([]); + // eslint-disable-next-line react-hooks/exhaustive-deps + const actionMessageParams = useMemo(() => getActionMessageParams(rule?.type), [rule]); + const setStepsForm = useCallback( + (step: RuleStep, form: FormHook) => { + stepsForm.current[step] = form; + if (initForm && step === (selectedTab?.id as RuleStep) && form.isSubmitted === false) { + setInitForm(false); + form.submit(); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [initForm, selectedTab] + ); + const tabs = useMemo( + () => [ + { + id: RuleStep.defineRule, + name: ruleI18n.DEFINITION, + disabled: rule?.immutable, + content: ( + <> + + + {myDefineRuleForm.data != null && ( + + )} + + + + ), + }, + { + id: RuleStep.aboutRule, + name: ruleI18n.ABOUT, + disabled: rule?.immutable, + content: ( + <> + + + {myAboutRuleForm.data != null && ( + + )} + + + + ), + }, + { + id: RuleStep.scheduleRule, + name: ruleI18n.SCHEDULE, + disabled: rule?.immutable, + content: ( + <> + + + {myScheduleRuleForm.data != null && ( + + )} + + + + ), + }, + { + id: RuleStep.ruleActions, + name: ruleI18n.ACTIONS, + content: ( + <> + + + {myActionsRuleForm.data != null && ( + + )} + + + + ), + }, + ], + // eslint-disable-next-line react-hooks/exhaustive-deps + [ + rule, + loading, + initLoading, + isLoading, + myAboutRuleForm, + myDefineRuleForm, + myScheduleRuleForm, + myActionsRuleForm, + setStepsForm, + stepsForm, + actionMessageParams, + ] + ); + + const onSubmit = useCallback(async () => { + const activeFormId = selectedTab?.id as RuleStep; + const activeForm = await stepsForm.current[activeFormId]?.submit(); + + const invalidForms = [ + RuleStep.aboutRule, + RuleStep.defineRule, + RuleStep.scheduleRule, + RuleStep.ruleActions, + ].reduce((acc, step) => { + if ( + (step === activeFormId && activeForm != null && !activeForm?.isValid) || + (step === RuleStep.aboutRule && !myAboutRuleForm.isValid) || + (step === RuleStep.defineRule && !myDefineRuleForm.isValid) || + (step === RuleStep.scheduleRule && !myScheduleRuleForm.isValid) || + (step === RuleStep.ruleActions && !myActionsRuleForm.isValid) + ) { + return [...acc, step]; + } + return acc; + }, []); + + if (invalidForms.length === 0 && activeForm != null) { + setTabHasError([]); + setRule({ + ...formatRule( + (activeFormId === RuleStep.defineRule + ? activeForm.data + : myDefineRuleForm.data) as DefineStepRule, + (activeFormId === RuleStep.aboutRule + ? activeForm.data + : myAboutRuleForm.data) as AboutStepRule, + (activeFormId === RuleStep.scheduleRule + ? activeForm.data + : myScheduleRuleForm.data) as ScheduleStepRule, + (activeFormId === RuleStep.ruleActions + ? activeForm.data + : myActionsRuleForm.data) as ActionsStepRule + ), + ...(ruleId ? { id: ruleId } : {}), + }); + } else { + setTabHasError(invalidForms); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ + stepsForm, + myAboutRuleForm, + myDefineRuleForm, + myScheduleRuleForm, + myActionsRuleForm, + selectedTab, + ruleId, + ]); + + useEffect(() => { + if (rule != null) { + const { aboutRuleData, defineRuleData, scheduleRuleData, ruleActionsData } = getStepsData({ + rule, + }); + setMyAboutRuleForm({ data: aboutRuleData, isValid: true }); + setMyDefineRuleForm({ data: defineRuleData, isValid: true }); + setMyScheduleRuleForm({ data: scheduleRuleData, isValid: true }); + setMyActionsRuleForm({ data: ruleActionsData, isValid: true }); + } + }, [rule]); + + const onTabClick = useCallback( + async (tab: EuiTabbedContentTab) => { + if (selectedTab != null) { + const ruleStep = selectedTab.id as RuleStep; + const respForm = await stepsForm.current[ruleStep]?.submit(); + + if (respForm != null) { + if (ruleStep === RuleStep.aboutRule) { + setMyAboutRuleForm({ + data: respForm.data as AboutStepRule, + isValid: respForm.isValid, + }); + } else if (ruleStep === RuleStep.defineRule) { + setMyDefineRuleForm({ + data: respForm.data as DefineStepRule, + isValid: respForm.isValid, + }); + } else if (ruleStep === RuleStep.scheduleRule) { + setMyScheduleRuleForm({ + data: respForm.data as ScheduleStepRule, + isValid: respForm.isValid, + }); + } else if (ruleStep === RuleStep.ruleActions) { + setMyActionsRuleForm({ + data: respForm.data as ActionsStepRule, + isValid: respForm.isValid, + }); + } + } + } + setInitForm(true); + setSelectedTab(tab); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [selectedTab, stepsForm.current] + ); + + useEffect(() => { + if (rule != null) { + const { aboutRuleData, defineRuleData, scheduleRuleData, ruleActionsData } = getStepsData({ + rule, + }); + setMyAboutRuleForm({ data: aboutRuleData, isValid: true }); + setMyDefineRuleForm({ data: defineRuleData, isValid: true }); + setMyScheduleRuleForm({ data: scheduleRuleData, isValid: true }); + setMyActionsRuleForm({ data: ruleActionsData, isValid: true }); + } + }, [rule]); + + useEffect(() => { + const tabIndex = rule?.immutable ? 3 : 0; + setSelectedTab(tabs[tabIndex]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [rule]); + + if (isSaved) { + displaySuccessToast(i18n.SUCCESSFULLY_SAVED_RULE(rule?.name ?? ''), dispatchToaster); + return ; + } + + if (redirectToDetections(isSignalIndexExists, isAuthenticated, hasEncryptionKey)) { + return ; + } else if (userHasNoPermissions(canUserCRUD)) { + return ; + } + + return ( + <> + + + {tabHasError.length > 0 && ( + + { + if (t === RuleStep.aboutRule) { + return ruleI18n.ABOUT; + } else if (t === RuleStep.defineRule) { + return ruleI18n.DEFINITION; + } else if (t === RuleStep.scheduleRule) { + return ruleI18n.SCHEDULE; + } else if (t === RuleStep.ruleActions) { + return ruleI18n.RULE_ACTIONS; + } + return t; + }) + .join(', '), + }} + /> + + )} + + t.id === selectedTab?.id)} + onTabClick={onTabClick} + tabs={tabs} + /> + + + + + + + {i18n.CANCEL} + + + + + + {i18n.SAVE_CHANGES} + + + + + + + + ); +}; + +export const EditRulePage = memo(EditRulePageComponent); diff --git a/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/edit/translations.ts b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/edit/translations.ts new file mode 100644 index 0000000000000..dcd55caf6549e --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/edit/translations.ts @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const PAGE_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.editRule.pageTitle', + { + defaultMessage: 'Edit rule settings', + } +); + +export const CANCEL = i18n.translate( + 'xpack.securitySolution.detectionEngine.editRule.cancelTitle', + { + defaultMessage: 'Cancel', + } +); + +export const SAVE_CHANGES = i18n.translate( + 'xpack.securitySolution.detectionEngine.editRule.saveChangeTitle', + { + defaultMessage: 'Save changes', + } +); + +export const SORRY_ERRORS = i18n.translate( + 'xpack.securitySolution.detectionEngine.editRule.errorMsgDescription', + { + defaultMessage: 'Sorry', + } +); + +export const BACK_TO = i18n.translate( + 'xpack.securitySolution.detectionEngine.editRule.backToDescription', + { + defaultMessage: 'Back to', + } +); + +export const SUCCESSFULLY_SAVED_RULE = (ruleName: string) => + i18n.translate('xpack.securitySolution.detectionEngine.rules.update.successfullySavedRuleTitle', { + values: { ruleName }, + defaultMessage: '{ruleName} was saved', + }); diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/helpers.test.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/helpers.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/helpers.test.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/helpers.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/helpers.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/helpers.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/helpers.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/helpers.tsx diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/index.test.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/index.test.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/index.test.tsx diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/index.tsx b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/index.tsx rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/index.tsx diff --git a/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/translations.ts b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/translations.ts new file mode 100644 index 0000000000000..32f59093e6a04 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/translations.ts @@ -0,0 +1,530 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const BACK_TO_ALERTS = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.backOptionsHeader', + { + defaultMessage: 'Back to alerts', + } +); + +export const IMPORT_RULE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.importRuleTitle', + { + defaultMessage: 'Import rule…', + } +); + +export const ADD_NEW_RULE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.addNewRuleTitle', + { + defaultMessage: 'Create new rule', + } +); + +export const PAGE_TITLE = i18n.translate('xpack.securitySolution.detectionEngine.rules.pageTitle', { + defaultMessage: 'Detection rules', +}); + +export const ADD_PAGE_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.addPageTitle', + { + defaultMessage: 'Create', + } +); + +export const EDIT_PAGE_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.editPageTitle', + { + defaultMessage: 'Edit', + } +); + +export const REFRESH = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.refreshTitle', + { + defaultMessage: 'Refresh', + } +); + +export const BATCH_ACTIONS = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.batchActionsTitle', + { + defaultMessage: 'Bulk actions', + } +); + +export const ACTIVE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.activeRuleDescription', + { + defaultMessage: 'active', + } +); + +export const INACTIVE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.inactiveRuleDescription', + { + defaultMessage: 'inactive', + } +); + +export const BATCH_ACTION_ACTIVATE_SELECTED = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.batchActions.activateSelectedTitle', + { + defaultMessage: 'Activate selected', + } +); + +export const BATCH_ACTION_ACTIVATE_SELECTED_ERROR = (totalRules: number) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.batchActions.activateSelectedErrorTitle', + { + values: { totalRules }, + defaultMessage: 'Error activating {totalRules, plural, =1 {rule} other {rules}}…', + } + ); + +export const BATCH_ACTION_DEACTIVATE_SELECTED = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.batchActions.deactivateSelectedTitle', + { + defaultMessage: 'Deactivate selected', + } +); + +export const BATCH_ACTION_DEACTIVATE_SELECTED_ERROR = (totalRules: number) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.batchActions.deactivateSelectedErrorTitle', + { + values: { totalRules }, + defaultMessage: 'Error deactivating {totalRules, plural, =1 {rule} other {rules}}…', + } + ); + +export const BATCH_ACTION_EXPORT_SELECTED = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.batchActions.exportSelectedTitle', + { + defaultMessage: 'Export selected', + } +); + +export const BATCH_ACTION_DUPLICATE_SELECTED = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.batchActions.duplicateSelectedTitle', + { + defaultMessage: 'Duplicate selected…', + } +); + +export const BATCH_ACTION_DELETE_SELECTED = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.batchActions.deleteSelectedTitle', + { + defaultMessage: 'Delete selected…', + } +); + +export const BATCH_ACTION_DELETE_SELECTED_IMMUTABLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.batchActions.deleteSelectedImmutableTitle', + { + defaultMessage: 'Selection contains immutable rules which cannot be deleted', + } +); + +export const BATCH_ACTION_DELETE_SELECTED_ERROR = (totalRules: number) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.batchActions.deleteSelectedErrorTitle', + { + values: { totalRules }, + defaultMessage: 'Error deleting {totalRules, plural, =1 {rule} other {rules}}…', + } + ); + +export const EXPORT_FILENAME = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.exportFilenameTitle', + { + defaultMessage: 'rules_export', + } +); + +export const SUCCESSFULLY_EXPORTED_RULES = (totalRules: number) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.successfullyExportedRulesTitle', + { + values: { totalRules }, + defaultMessage: + 'Successfully exported {totalRules, plural, =0 {all rules} =1 {{totalRules} rule} other {{totalRules} rules}}', + } + ); + +export const ALL_RULES = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.tableTitle', + { + defaultMessage: 'All rules', + } +); + +export const SEARCH_RULES = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.searchAriaLabel', + { + defaultMessage: 'Search rules', + } +); + +export const SEARCH_PLACEHOLDER = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.searchPlaceholder', + { + defaultMessage: 'e.g. rule name', + } +); + +export const SHOWING_RULES = (totalRules: number) => + i18n.translate('xpack.securitySolution.detectionEngine.rules.allRules.showingRulesTitle', { + values: { totalRules }, + defaultMessage: 'Showing {totalRules} {totalRules, plural, =1 {rule} other {rules}}', + }); + +export const SELECTED_RULES = (selectedRules: number) => + i18n.translate('xpack.securitySolution.detectionEngine.rules.allRules.selectedRulesTitle', { + values: { selectedRules }, + defaultMessage: 'Selected {selectedRules} {selectedRules, plural, =1 {rule} other {rules}}', + }); + +export const EDIT_RULE_SETTINGS = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.actions.editRuleSettingsDescription', + { + defaultMessage: 'Edit rule settings', + } +); + +export const DUPLICATE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.actions.duplicateTitle', + { + defaultMessage: 'Duplicate', + } +); + +export const DUPLICATE_RULE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.actions.duplicateRuleDescription', + { + defaultMessage: 'Duplicate rule…', + } +); + +export const SUCCESSFULLY_DUPLICATED_RULES = (totalRules: number) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.successfullyDuplicatedRulesTitle', + { + values: { totalRules }, + defaultMessage: + 'Successfully duplicated {totalRules, plural, =1 {{totalRules} rule} other {{totalRules} rules}}', + } + ); + +export const DUPLICATE_RULE_ERROR = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.actions.duplicateRuleErrorDescription', + { + defaultMessage: 'Error duplicating rule…', + } +); + +export const EXPORT_RULE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.actions.exportRuleDescription', + { + defaultMessage: 'Export rule', + } +); + +export const DELETE_RULE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.actions.deleteeRuleDescription', + { + defaultMessage: 'Delete rule…', + } +); + +export const COLUMN_RULE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.columns.ruleTitle', + { + defaultMessage: 'Rule', + } +); + +export const COLUMN_RISK_SCORE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.columns.riskScoreTitle', + { + defaultMessage: 'Risk score', + } +); + +export const COLUMN_SEVERITY = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.columns.severityTitle', + { + defaultMessage: 'Severity', + } +); + +export const COLUMN_LAST_COMPLETE_RUN = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.columns.lastRunTitle', + { + defaultMessage: 'Last run', + } +); + +export const COLUMN_LAST_RESPONSE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.columns.lastResponseTitle', + { + defaultMessage: 'Last response', + } +); + +export const COLUMN_TAGS = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.columns.tagsTitle', + { + defaultMessage: 'Tags', + } +); + +export const COLUMN_ACTIVATE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.columns.activateTitle', + { + defaultMessage: 'Activated', + } +); + +export const COLUMN_INDEXING_TIMES = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.columns.indexingTimes', + { + defaultMessage: 'Indexing Time (ms)', + } +); + +export const COLUMN_QUERY_TIMES = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.columns.queryTimes', + { + defaultMessage: 'Query Time (ms)', + } +); + +export const COLUMN_GAP = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.columns.gap', + { + defaultMessage: 'Gap (if any)', + } +); + +export const COLUMN_LAST_LOOKBACK_DATE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.columns.lastLookBackDate', + { + defaultMessage: 'Last Look-Back Date', + } +); + +export const RULES_TAB = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.tabs.rules', + { + defaultMessage: 'Rules', + } +); + +export const MONITORING_TAB = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.tabs.monitoring', + { + defaultMessage: 'Monitoring', + } +); + +export const CUSTOM_RULES = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.filters.customRulesTitle', + { + defaultMessage: 'Custom rules', + } +); + +export const ELASTIC_RULES = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.filters.elasticRulesTitle', + { + defaultMessage: 'Elastic rules', + } +); + +export const TAGS = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.filters.tagsLabel', + { + defaultMessage: 'Tags', + } +); + +export const NO_TAGS_AVAILABLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.filters.noTagsAvailableDescription', + { + defaultMessage: 'No tags available', + } +); + +export const NO_RULES = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.filters.noRulesTitle', + { + defaultMessage: 'No rules found', + } +); + +export const NO_RULES_BODY = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.allRules.filters.noRulesBodyTitle', + { + defaultMessage: "We weren't able to find any rules with the above filters.", + } +); + +export const DEFINE_RULE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.defineRuleTitle', + { + defaultMessage: 'Define rule', + } +); + +export const ABOUT_RULE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.aboutRuleTitle', + { + defaultMessage: 'About rule', + } +); + +export const SCHEDULE_RULE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.scheduleRuleTitle', + { + defaultMessage: 'Schedule rule', + } +); + +export const RULE_ACTIONS = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.ruleActionsTitle', + { + defaultMessage: 'Rule actions', + } +); + +export const DEFINITION = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.stepDefinitionTitle', + { + defaultMessage: 'Definition', + } +); + +export const ABOUT = i18n.translate('xpack.securitySolution.detectionEngine.rules.stepAboutTitle', { + defaultMessage: 'About', +}); + +export const SCHEDULE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.stepScheduleTitle', + { + defaultMessage: 'Schedule', + } +); + +export const ACTIONS = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.stepActionsTitle', + { + defaultMessage: 'Actions', + } +); + +export const OPTIONAL_FIELD = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.optionalFieldDescription', + { + defaultMessage: 'Optional', + } +); + +export const CONTINUE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.continueButtonTitle', + { + defaultMessage: 'Continue', + } +); + +export const UPDATE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.updateButtonTitle', + { + defaultMessage: 'Update', + } +); + +export const DELETE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.deleteDescription', + { + defaultMessage: 'Delete', + } +); + +export const LOAD_PREPACKAGED_RULES = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.loadPrePackagedRulesButton', + { + defaultMessage: 'Load Elastic prebuilt rules', + } +); + +export const RELOAD_MISSING_PREPACKAGED_RULES = (missingRules: number) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedRulesButton', + { + values: { missingRules }, + defaultMessage: + 'Install {missingRules} Elastic prebuilt {missingRules, plural, =1 {rule} other {rules}} ', + } + ); + +export const IMPORT_RULE_BTN_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.components.importRuleModal.importRuleTitle', + { + defaultMessage: 'Import rule', + } +); + +export const SELECT_RULE = i18n.translate( + 'xpack.securitySolution.detectionEngine.components.importRuleModal.selectRuleDescription', + { + defaultMessage: 'Select a SIEM rule (as exported from the Detection Engine view) to import', + } +); + +export const INITIAL_PROMPT_TEXT = i18n.translate( + 'xpack.securitySolution.detectionEngine.components.importRuleModal.initialPromptTextDescription', + { + defaultMessage: 'Select or drag and drop a valid rules_export.ndjson file', + } +); + +export const OVERWRITE_WITH_SAME_NAME = i18n.translate( + 'xpack.securitySolution.detectionEngine.components.importRuleModal.overwriteDescription', + { + defaultMessage: 'Automatically overwrite saved objects with the same rule ID', + } +); + +export const SUCCESSFULLY_IMPORTED_RULES = (totalRules: number) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.components.importRuleModal.successfullyImportedRulesTitle', + { + values: { totalRules }, + defaultMessage: + 'Successfully imported {totalRules} {totalRules, plural, =1 {rule} other {rules}}', + } + ); + +export const IMPORT_FAILED = i18n.translate( + 'xpack.securitySolution.detectionEngine.components.importRuleModal.importFailedTitle', + { + defaultMessage: 'Failed to import rules', + } +); + +export const IMPORT_FAILED_DETAILED = (ruleId: string, statusCode: number, message: string) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.components.importRuleModal.importFailedDetailedTitle', + { + values: { ruleId, statusCode, message }, + defaultMessage: 'Rule ID: {ruleId}\n Status Code: {statusCode}\n Message: {message}', + } + ); diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/types.ts b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/types.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/types.ts rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/types.ts diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/utils.test.ts b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/utils.test.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/utils.test.ts rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/utils.test.ts diff --git a/x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/utils.ts b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/utils.ts similarity index 100% rename from x-pack/plugins/siem/public/alerts/pages/detection_engine/rules/utils.ts rename to x-pack/plugins/security_solution/public/alerts/pages/detection_engine/rules/utils.ts diff --git a/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/translations.ts b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/translations.ts new file mode 100644 index 0000000000000..a19422d0de2c1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/translations.ts @@ -0,0 +1,117 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const PAGE_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.detectionsPageTitle', + { + defaultMessage: 'Alerts', + } +); + +export const LAST_ALERT = i18n.translate('xpack.securitySolution.detectionEngine.lastSignalTitle', { + defaultMessage: 'Last alert', +}); + +export const TOTAL_SIGNAL = i18n.translate( + 'xpack.securitySolution.detectionEngine.totalSignalTitle', + { + defaultMessage: 'Total', + } +); + +export const SIGNAL = i18n.translate('xpack.securitySolution.detectionEngine.signalTitle', { + defaultMessage: 'Detected alerts', +}); + +export const ALERT = i18n.translate('xpack.securitySolution.detectionEngine.alertTitle', { + defaultMessage: 'External alerts', +}); + +export const BUTTON_MANAGE_RULES = i18n.translate( + 'xpack.securitySolution.detectionEngine.buttonManageRules', + { + defaultMessage: 'Manage detection rules', + } +); + +export const PANEL_SUBTITLE_SHOWING = i18n.translate( + 'xpack.securitySolution.detectionEngine.panelSubtitleShowing', + { + defaultMessage: 'Showing', + } +); + +export const EMPTY_TITLE = i18n.translate('xpack.securitySolution.detectionEngine.emptyTitle', { + defaultMessage: + 'It looks like you don’t have any indices relevant to the detection engine in the SIEM application', +}); + +export const EMPTY_ACTION_PRIMARY = i18n.translate( + 'xpack.securitySolution.detectionEngine.emptyActionPrimary', + { + defaultMessage: 'View setup instructions', + } +); + +export const EMPTY_ACTION_SECONDARY = i18n.translate( + 'xpack.securitySolution.detectionEngine.emptyActionSecondary', + { + defaultMessage: 'Go to documentation', + } +); + +export const NO_INDEX_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.noIndexTitle', + { + defaultMessage: 'Let’s set up your detection engine', + } +); + +export const NO_INDEX_MSG_BODY = i18n.translate( + 'xpack.securitySolution.detectionEngine.noIndexMsgBody', + { + defaultMessage: + 'To use the detection engine, a user with the required cluster and index privileges must first access this page. For more help, contact your administrator.', + } +); + +export const GO_TO_DOCUMENTATION = i18n.translate( + 'xpack.securitySolution.detectionEngine.goToDocumentationButton', + { + defaultMessage: 'View documentation', + } +); + +export const USER_UNAUTHENTICATED_TITLE = i18n.translate( + 'xpack.securitySolution.detectionEngine.userUnauthenticatedTitle', + { + defaultMessage: 'Detection engine permissions required', + } +); + +export const USER_UNAUTHENTICATED_MSG_BODY = i18n.translate( + 'xpack.securitySolution.detectionEngine.userUnauthenticatedMsgBody', + { + defaultMessage: + 'You do not have the required permissions for viewing the detection engine. For more help, contact your administrator.', + } +); + +export const ML_RULES_DISABLED_MESSAGE = i18n.translate( + 'xpack.securitySolution.detectionEngine.mlRulesDisabledMessageTitle', + { + defaultMessage: 'ML rules require Platinum License and ML Admin Permissions', + } +); + +export const ML_RULES_UNAVAILABLE = (totalRules: number) => + i18n.translate('xpack.securitySolution.detectionEngine.mlUnavailableTitle', { + values: { totalRules }, + defaultMessage: + '{totalRules} {totalRules, plural, =1 {rule requires} other {rules require}} Machine Learning to enable.', + }); diff --git a/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/types.ts b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/types.ts new file mode 100644 index 0000000000000..d529d99ad3ad4 --- /dev/null +++ b/x-pack/plugins/security_solution/public/alerts/pages/detection_engine/types.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export enum DetectionEngineTab { + signals = 'signals', + alerts = 'alerts', +} diff --git a/x-pack/plugins/siem/public/alerts/routes.tsx b/x-pack/plugins/security_solution/public/alerts/routes.tsx similarity index 100% rename from x-pack/plugins/siem/public/alerts/routes.tsx rename to x-pack/plugins/security_solution/public/alerts/routes.tsx diff --git a/x-pack/plugins/siem/public/app/404.tsx b/x-pack/plugins/security_solution/public/app/404.tsx similarity index 88% rename from x-pack/plugins/siem/public/app/404.tsx rename to x-pack/plugins/security_solution/public/app/404.tsx index 6a1b5c56dc853..b24cad5ad5b4b 100644 --- a/x-pack/plugins/siem/public/app/404.tsx +++ b/x-pack/plugins/security_solution/public/app/404.tsx @@ -12,7 +12,7 @@ import { WrapperPage } from '../common/components/wrapper_page'; export const NotFoundPage = React.memo(() => ( diff --git a/x-pack/plugins/siem/public/app/app.tsx b/x-pack/plugins/security_solution/public/app/app.tsx similarity index 100% rename from x-pack/plugins/siem/public/app/app.tsx rename to x-pack/plugins/security_solution/public/app/app.tsx diff --git a/x-pack/plugins/siem/public/app/home/home_navigations.tsx b/x-pack/plugins/security_solution/public/app/home/home_navigations.tsx similarity index 100% rename from x-pack/plugins/siem/public/app/home/home_navigations.tsx rename to x-pack/plugins/security_solution/public/app/home/home_navigations.tsx diff --git a/x-pack/plugins/siem/public/app/home/index.tsx b/x-pack/plugins/security_solution/public/app/home/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/app/home/index.tsx rename to x-pack/plugins/security_solution/public/app/home/index.tsx diff --git a/x-pack/plugins/siem/public/app/home/setup.tsx b/x-pack/plugins/security_solution/public/app/home/setup.tsx similarity index 90% rename from x-pack/plugins/siem/public/app/home/setup.tsx rename to x-pack/plugins/security_solution/public/app/home/setup.tsx index a88b6a36100db..5b977a83302a9 100644 --- a/x-pack/plugins/siem/public/app/home/setup.tsx +++ b/x-pack/plugins/security_solution/public/app/home/setup.tsx @@ -13,11 +13,11 @@ export const Setup: React.FunctionComponent<{ notifications: NotificationsStart; }> = ({ ingestManager, notifications }) => { React.useEffect(() => { - const defaultText = i18n.translate('xpack.siem.endpoint.ingestToastMessage', { + const defaultText = i18n.translate('xpack.securitySolution.endpoint.ingestToastMessage', { defaultMessage: 'Ingest Manager failed during its setup.', }); - const title = i18n.translate('xpack.siem.endpoint.ingestToastTitle', { + const title = i18n.translate('xpack.securitySolution.endpoint.ingestToastTitle', { defaultMessage: 'App failed to initialize', }); diff --git a/x-pack/plugins/security_solution/public/app/home/translations.ts b/x-pack/plugins/security_solution/public/app/home/translations.ts new file mode 100644 index 0000000000000..ccf927eba20c9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/app/home/translations.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const OVERVIEW = i18n.translate('xpack.securitySolution.navigation.overview', { + defaultMessage: 'Overview', +}); + +export const HOSTS = i18n.translate('xpack.securitySolution.navigation.hosts', { + defaultMessage: 'Hosts', +}); + +export const NETWORK = i18n.translate('xpack.securitySolution.navigation.network', { + defaultMessage: 'Network', +}); + +export const DETECTION_ENGINE = i18n.translate( + 'xpack.securitySolution.navigation.detectionEngine', + { + defaultMessage: 'Detections', + } +); + +export const TIMELINES = i18n.translate('xpack.securitySolution.navigation.timelines', { + defaultMessage: 'Timelines', +}); + +export const CASE = i18n.translate('xpack.securitySolution.navigation.case', { + defaultMessage: 'Cases', +}); + +export const MANAGEMENT = i18n.translate('xpack.securitySolution.navigation.management', { + defaultMessage: 'Management', +}); diff --git a/x-pack/plugins/siem/public/app/index.tsx b/x-pack/plugins/security_solution/public/app/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/app/index.tsx rename to x-pack/plugins/security_solution/public/app/index.tsx diff --git a/x-pack/plugins/siem/public/app/routes.tsx b/x-pack/plugins/security_solution/public/app/routes.tsx similarity index 100% rename from x-pack/plugins/siem/public/app/routes.tsx rename to x-pack/plugins/security_solution/public/app/routes.tsx diff --git a/x-pack/plugins/siem/public/app/types.ts b/x-pack/plugins/security_solution/public/app/types.ts similarity index 100% rename from x-pack/plugins/siem/public/app/types.ts rename to x-pack/plugins/security_solution/public/app/types.ts diff --git a/x-pack/plugins/siem/public/cases/components/__mock__/form.ts b/x-pack/plugins/security_solution/public/cases/components/__mock__/form.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/components/__mock__/form.ts rename to x-pack/plugins/security_solution/public/cases/components/__mock__/form.ts diff --git a/x-pack/plugins/siem/public/cases/components/__mock__/router.ts b/x-pack/plugins/security_solution/public/cases/components/__mock__/router.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/components/__mock__/router.ts rename to x-pack/plugins/security_solution/public/cases/components/__mock__/router.ts diff --git a/x-pack/plugins/siem/public/cases/components/add_comment/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/add_comment/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/add_comment/index.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/add_comment/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/add_comment/index.tsx b/x-pack/plugins/security_solution/public/cases/components/add_comment/index.tsx new file mode 100644 index 0000000000000..a57fae8081bea --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/add_comment/index.tsx @@ -0,0 +1,116 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiButton, EuiLoadingSpinner } from '@elastic/eui'; +import React, { useCallback, useEffect } from 'react'; +import styled from 'styled-components'; + +import { CommentRequest } from '../../../../../case/common/api'; +import { usePostComment } from '../../containers/use_post_comment'; +import { Case } from '../../containers/types'; +import { MarkdownEditorForm } from '../../../common/components/markdown_editor/form'; +import { InsertTimelinePopover } from '../../../timelines/components/timeline/insert_timeline_popover'; +import { useInsertTimeline } from '../../../timelines/components/timeline/insert_timeline_popover/use_insert_timeline'; +import { Form, useForm, UseField } from '../../../shared_imports'; + +import * as i18n from './translations'; +import { schema } from './schema'; + +const MySpinner = styled(EuiLoadingSpinner)` + position: absolute; + top: 50%; + left: 50%; +`; + +const initialCommentValue: CommentRequest = { + comment: '', +}; + +interface AddCommentProps { + caseId: string; + disabled?: boolean; + insertQuote: string | null; + onCommentSaving?: () => void; + onCommentPosted: (newCase: Case) => void; + showLoading?: boolean; +} + +export const AddComment = React.memo( + ({ caseId, disabled, insertQuote, showLoading = true, onCommentPosted, onCommentSaving }) => { + const { isLoading, postComment } = usePostComment(caseId); + const { form } = useForm({ + defaultValue: initialCommentValue, + options: { stripEmptyFields: false }, + schema, + }); + const { handleCursorChange, handleOnTimelineChange } = useInsertTimeline( + form, + 'comment' + ); + + useEffect(() => { + if (insertQuote !== null) { + const { comment } = form.getFormData(); + form.setFieldValue( + 'comment', + `${comment}${comment.length > 0 ? '\n\n' : ''}${insertQuote}` + ); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [insertQuote]); + + const onSubmit = useCallback(async () => { + const { isValid, data } = await form.submit(); + if (isValid) { + if (onCommentSaving != null) { + onCommentSaving(); + } + postComment(data, onCommentPosted); + form.reset(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [form, onCommentPosted, onCommentSaving]); + return ( + + {isLoading && showLoading && } +
+ + {i18n.ADD_COMMENT} + + ), + topRightContent: ( + + ), + }} + /> + +
+ ); + } +); + +AddComment.displayName = 'AddComment'; diff --git a/x-pack/plugins/siem/public/cases/components/add_comment/schema.tsx b/x-pack/plugins/security_solution/public/cases/components/add_comment/schema.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/add_comment/schema.tsx rename to x-pack/plugins/security_solution/public/cases/components/add_comment/schema.tsx diff --git a/x-pack/plugins/siem/public/cases/components/add_comment/translations.ts b/x-pack/plugins/security_solution/public/cases/components/add_comment/translations.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/components/add_comment/translations.ts rename to x-pack/plugins/security_solution/public/cases/components/add_comment/translations.ts diff --git a/x-pack/plugins/siem/public/cases/components/all_cases/actions.tsx b/x-pack/plugins/security_solution/public/cases/components/all_cases/actions.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/all_cases/actions.tsx rename to x-pack/plugins/security_solution/public/cases/components/all_cases/actions.tsx diff --git a/x-pack/plugins/siem/public/cases/components/all_cases/columns.test.tsx b/x-pack/plugins/security_solution/public/cases/components/all_cases/columns.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/all_cases/columns.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/all_cases/columns.test.tsx diff --git a/x-pack/plugins/siem/public/cases/components/all_cases/columns.tsx b/x-pack/plugins/security_solution/public/cases/components/all_cases/columns.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/all_cases/columns.tsx rename to x-pack/plugins/security_solution/public/cases/components/all_cases/columns.tsx diff --git a/x-pack/plugins/siem/public/cases/components/all_cases/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/all_cases/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/all_cases/index.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/all_cases/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/all_cases/index.tsx b/x-pack/plugins/security_solution/public/cases/components/all_cases/index.tsx new file mode 100644 index 0000000000000..32a7c4078071e --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/all_cases/index.tsx @@ -0,0 +1,450 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { + EuiBasicTable, + EuiButton, + EuiContextMenuPanel, + EuiEmptyPrompt, + EuiFlexGroup, + EuiFlexItem, + EuiLoadingContent, + EuiProgress, + EuiTableSortingType, +} from '@elastic/eui'; +import { EuiTableSelectionType } from '@elastic/eui/src/components/basic_table/table_types'; +import { isEmpty } from 'lodash/fp'; +import styled, { css } from 'styled-components'; +import * as i18n from './translations'; + +import { getCasesColumns } from './columns'; +import { Case, DeleteCase, FilterOptions, SortFieldCase } from '../../containers/types'; +import { useGetCases, UpdateCase } from '../../containers/use_get_cases'; +import { useGetCasesStatus } from '../../containers/use_get_cases_status'; +import { useDeleteCases } from '../../containers/use_delete_cases'; +import { EuiBasicTableOnChange } from '../../../alerts/pages/detection_engine/rules/types'; +import { useGetUrlSearch } from '../../../common/components/navigation/use_get_url_search'; +import { Panel } from '../../../common/components/panel'; +import { + UtilityBar, + UtilityBarAction, + UtilityBarGroup, + UtilityBarSection, + UtilityBarText, +} from '../../../common/components/utility_bar'; +import { getCreateCaseUrl } from '../../../common/components/link_to'; +import { getBulkItems } from '../bulk_actions'; +import { CaseHeaderPage } from '../case_header_page'; +import { ConfirmDeleteCaseModal } from '../confirm_delete_case'; +import { OpenClosedStats } from '../open_closed_stats'; +import { navTabs } from '../../../app/home/home_navigations'; + +import { getActions } from './actions'; +import { CasesTableFilters } from './table_filters'; +import { useUpdateCases } from '../../containers/use_bulk_update_case'; +import { useGetActionLicense } from '../../containers/use_get_action_license'; +import { getActionLicenseError } from '../use_push_to_service/helpers'; +import { CaseCallOut } from '../callout'; +import { ConfigureCaseButton } from '../configure_cases/button'; +import { ERROR_PUSH_SERVICE_CALLOUT_TITLE } from '../use_push_to_service/translations'; + +const Div = styled.div` + margin-top: ${({ theme }) => theme.eui.paddingSizes.m}; +`; +const FlexItemDivider = styled(EuiFlexItem)` + ${({ theme }) => css` + .euiFlexGroup--gutterMedium > &.euiFlexItem { + border-right: ${theme.eui.euiBorderThin}; + padding-right: ${theme.eui.euiSize}; + margin-right: ${theme.eui.euiSize}; + } + `} +`; + +const ProgressLoader = styled(EuiProgress)` + ${({ theme }) => css` + top: 2px; + border-radius: ${theme.eui.euiBorderRadius}; + z-index: ${theme.eui.euiZHeader}; + `} +`; + +const getSortField = (field: string): SortFieldCase => { + if (field === SortFieldCase.createdAt) { + return SortFieldCase.createdAt; + } else if (field === SortFieldCase.closedAt) { + return SortFieldCase.closedAt; + } + return SortFieldCase.createdAt; +}; + +interface AllCasesProps { + userCanCrud: boolean; +} +export const AllCases = React.memo(({ userCanCrud }) => { + const urlSearch = useGetUrlSearch(navTabs.case); + const { actionLicense } = useGetActionLicense(); + const { + countClosedCases, + countOpenCases, + isLoading: isCasesStatusLoading, + fetchCasesStatus, + } = useGetCasesStatus(); + const { + data, + dispatchUpdateCaseProperty, + filterOptions, + loading, + queryParams, + selectedCases, + refetchCases, + setFilters, + setQueryParams, + setSelectedCases, + } = useGetCases(); + + // Delete case + const { + dispatchResetIsDeleted, + handleOnDeleteConfirm, + handleToggleModal, + isLoading: isDeleting, + isDeleted, + isDisplayConfirmDeleteModal, + } = useDeleteCases(); + + // Update case + const { + dispatchResetIsUpdated, + isLoading: isUpdating, + isUpdated, + updateBulkStatus, + } = useUpdateCases(); + const [deleteThisCase, setDeleteThisCase] = useState({ + title: '', + id: '', + }); + const [deleteBulk, setDeleteBulk] = useState([]); + const filterRefetch = useRef<() => void>(); + const setFilterRefetch = useCallback( + (refetchFilter: () => void) => { + filterRefetch.current = refetchFilter; + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [filterRefetch.current] + ); + const refreshCases = useCallback( + (dataRefresh = true) => { + if (dataRefresh) refetchCases(); + fetchCasesStatus(); + setSelectedCases([]); + setDeleteBulk([]); + if (filterRefetch.current != null) { + filterRefetch.current(); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [filterOptions, queryParams, filterRefetch.current] + ); + + useEffect(() => { + if (isDeleted) { + refreshCases(); + dispatchResetIsDeleted(); + } + if (isUpdated) { + refreshCases(); + dispatchResetIsUpdated(); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isDeleted, isUpdated]); + const confirmDeleteModal = useMemo( + () => ( + 0} + onCancel={handleToggleModal} + onConfirm={handleOnDeleteConfirm.bind( + null, + deleteBulk.length > 0 ? deleteBulk : [deleteThisCase] + )} + /> + ), + // eslint-disable-next-line react-hooks/exhaustive-deps + [deleteBulk, deleteThisCase, isDisplayConfirmDeleteModal] + ); + + const toggleDeleteModal = useCallback((deleteCase: Case) => { + handleToggleModal(); + setDeleteThisCase(deleteCase); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const toggleBulkDeleteModal = useCallback( + (caseIds: string[]) => { + handleToggleModal(); + if (caseIds.length === 1) { + const singleCase = selectedCases.find((theCase) => theCase.id === caseIds[0]); + if (singleCase) { + return setDeleteThisCase({ id: singleCase.id, title: singleCase.title }); + } + } + const convertToDeleteCases: DeleteCase[] = caseIds.map((id) => ({ id })); + setDeleteBulk(convertToDeleteCases); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [selectedCases] + ); + + const handleUpdateCaseStatus = useCallback( + (status: string) => { + updateBulkStatus(selectedCases, status); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [selectedCases] + ); + + const selectedCaseIds = useMemo( + (): string[] => selectedCases.map((caseObj: Case) => caseObj.id), + [selectedCases] + ); + + const getBulkItemsPopoverContent = useCallback( + (closePopover: () => void) => ( + + ), + // eslint-disable-next-line react-hooks/exhaustive-deps + [selectedCaseIds, filterOptions.status, toggleBulkDeleteModal] + ); + const handleDispatchUpdate = useCallback( + (args: Omit) => { + dispatchUpdateCaseProperty({ ...args, refetchCasesStatus: fetchCasesStatus }); + }, + [dispatchUpdateCaseProperty, fetchCasesStatus] + ); + + const actions = useMemo( + () => + getActions({ + caseStatus: filterOptions.status, + deleteCaseOnClick: toggleDeleteModal, + dispatchUpdate: handleDispatchUpdate, + }), + [filterOptions.status, toggleDeleteModal, handleDispatchUpdate] + ); + + const actionsErrors = useMemo(() => getActionLicenseError(actionLicense), [actionLicense]); + + const tableOnChangeCallback = useCallback( + ({ page, sort }: EuiBasicTableOnChange) => { + let newQueryParams = queryParams; + if (sort) { + newQueryParams = { + ...newQueryParams, + sortField: getSortField(sort.field), + sortOrder: sort.direction, + }; + } + if (page) { + newQueryParams = { + ...newQueryParams, + page: page.index + 1, + perPage: page.size, + }; + } + setQueryParams(newQueryParams); + refreshCases(false); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [queryParams] + ); + + const onFilterChangedCallback = useCallback( + (newFilterOptions: Partial) => { + if (newFilterOptions.status && newFilterOptions.status === 'closed') { + setQueryParams({ sortField: SortFieldCase.closedAt }); + } else if (newFilterOptions.status && newFilterOptions.status === 'open') { + setQueryParams({ sortField: SortFieldCase.createdAt }); + } + setFilters(newFilterOptions); + refreshCases(false); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [filterOptions, queryParams] + ); + + const memoizedGetCasesColumns = useMemo( + () => getCasesColumns(userCanCrud ? actions : [], filterOptions.status), + [actions, filterOptions.status, userCanCrud] + ); + const memoizedPagination = useMemo( + () => ({ + pageIndex: queryParams.page - 1, + pageSize: queryParams.perPage, + totalItemCount: data.total, + pageSizeOptions: [5, 10, 15, 20, 25], + }), + [data, queryParams] + ); + + const sorting: EuiTableSortingType = { + sort: { field: queryParams.sortField, direction: queryParams.sortOrder }, + }; + const euiBasicTableSelectionProps = useMemo>( + () => ({ onSelectionChange: setSelectedCases }), + // eslint-disable-next-line react-hooks/exhaustive-deps + [selectedCases] + ); + const isCasesLoading = useMemo( + () => loading.indexOf('cases') > -1 || loading.indexOf('caseUpdate') > -1, + [loading] + ); + const isDataEmpty = useMemo(() => data.total === 0, [data]); + + return ( + <> + {!isEmpty(actionsErrors) && ( + + )} + + + + + + + + + + } + titleTooltip={!isEmpty(actionsErrors) ? actionsErrors[0].title : ''} + urlSearch={urlSearch} + /> + + + + {i18n.CREATE_TITLE} + + + + + {(isCasesLoading || isDeleting || isUpdating) && !isDataEmpty && ( + + )} + + + {isCasesLoading && isDataEmpty ? ( +
+ +
+ ) : ( +
+ + + + + {i18n.SHOWING_CASES(data.total ?? 0)} + + + + + {i18n.SHOWING_SELECTED_CASES(selectedCases.length)} + + {userCanCrud && ( + + {i18n.BULK_ACTIONS} + + )} + + {i18n.REFRESH} + + + + + {i18n.NO_CASES}} + titleSize="xs" + body={i18n.NO_CASES_BODY} + actions={ + + {i18n.ADD_NEW_CASE} + + } + /> + } + onChange={tableOnChangeCallback} + pagination={memoizedPagination} + selection={userCanCrud ? euiBasicTableSelectionProps : {}} + sorting={sorting} + /> +
+ )} +
+ {confirmDeleteModal} + + ); +}); + +AllCases.displayName = 'AllCases'; diff --git a/x-pack/plugins/siem/public/cases/components/all_cases/table_filters.test.tsx b/x-pack/plugins/security_solution/public/cases/components/all_cases/table_filters.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/all_cases/table_filters.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/all_cases/table_filters.test.tsx diff --git a/x-pack/plugins/siem/public/cases/components/all_cases/table_filters.tsx b/x-pack/plugins/security_solution/public/cases/components/all_cases/table_filters.tsx similarity index 93% rename from x-pack/plugins/siem/public/cases/components/all_cases/table_filters.tsx rename to x-pack/plugins/security_solution/public/cases/components/all_cases/table_filters.tsx index 42340b455c3af..63172bd6ad6bb 100644 --- a/x-pack/plugins/siem/public/cases/components/all_cases/table_filters.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/all_cases/table_filters.tsx @@ -66,12 +66,14 @@ const CasesTableFiltersComponent = ({ const newReporters = selectedReporters.filter((r) => reporters.includes(r)); handleSelectedReporters(newReporters); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [reporters]); useEffect(() => { if (selectedTags.length) { const newTags = selectedTags.filter((t) => tags.includes(t)); handleSelectedTags(newTags); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [tags]); const handleSelectedReporters = useCallback( @@ -84,6 +86,7 @@ const CasesTableFiltersComponent = ({ onFilterChanged({ reporters: reportersObj }); } }, + // eslint-disable-next-line react-hooks/exhaustive-deps [selectedReporters, respReporters] ); @@ -94,6 +97,7 @@ const CasesTableFiltersComponent = ({ onFilterChanged({ tags: newTags }); } }, + // eslint-disable-next-line react-hooks/exhaustive-deps [selectedTags] ); const handleOnSearch = useCallback( @@ -104,6 +108,7 @@ const CasesTableFiltersComponent = ({ onFilterChanged({ search: trimSearch }); } }, + // eslint-disable-next-line react-hooks/exhaustive-deps [search] ); const handleToggleFilter = useCallback( @@ -113,6 +118,7 @@ const CasesTableFiltersComponent = ({ onFilterChanged({ status: showOpen ? 'open' : 'closed' }); } }, + // eslint-disable-next-line react-hooks/exhaustive-deps [showOpenCases] ); return ( diff --git a/x-pack/plugins/security_solution/public/cases/components/all_cases/translations.ts b/x-pack/plugins/security_solution/public/cases/components/all_cases/translations.ts new file mode 100644 index 0000000000000..9198aaceb96f9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/all_cases/translations.ts @@ -0,0 +1,110 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export * from '../../translations'; + +export const NO_CASES = i18n.translate('xpack.securitySolution.case.caseTable.noCases.title', { + defaultMessage: 'No Cases', +}); +export const NO_CASES_BODY = i18n.translate('xpack.securitySolution.case.caseTable.noCases.body', { + defaultMessage: + 'There are no cases to display. Please create a new case or change your filter settings above.', +}); + +export const ADD_NEW_CASE = i18n.translate('xpack.securitySolution.case.caseTable.addNewCase', { + defaultMessage: 'Add New Case', +}); + +export const SHOWING_SELECTED_CASES = (totalRules: number) => + i18n.translate('xpack.securitySolution.case.caseTable.selectedCasesTitle', { + values: { totalRules }, + defaultMessage: 'Selected {totalRules} {totalRules, plural, =1 {case} other {cases}}', + }); + +export const SHOWING_CASES = (totalRules: number) => + i18n.translate('xpack.securitySolution.case.caseTable.showingCasesTitle', { + values: { totalRules }, + defaultMessage: 'Showing {totalRules} {totalRules, plural, =1 {case} other {cases}}', + }); + +export const UNIT = (totalCount: number) => + i18n.translate('xpack.securitySolution.case.caseTable.unit', { + values: { totalCount }, + defaultMessage: `{totalCount, plural, =1 {case} other {cases}}`, + }); + +export const SEARCH_CASES = i18n.translate( + 'xpack.securitySolution.case.caseTable.searchAriaLabel', + { + defaultMessage: 'Search cases', + } +); + +export const BULK_ACTIONS = i18n.translate('xpack.securitySolution.case.caseTable.bulkActions', { + defaultMessage: 'Bulk actions', +}); + +export const EXTERNAL_INCIDENT = i18n.translate( + 'xpack.securitySolution.case.caseTable.snIncident', + { + defaultMessage: 'External Incident', + } +); + +export const INCIDENT_MANAGEMENT_SYSTEM = i18n.translate( + 'xpack.securitySolution.case.caseTable.incidentSystem', + { + defaultMessage: 'Incident Management System', + } +); + +export const SEARCH_PLACEHOLDER = i18n.translate( + 'xpack.securitySolution.case.caseTable.searchPlaceholder', + { + defaultMessage: 'e.g. case name', + } +); +export const OPEN_CASES = i18n.translate('xpack.securitySolution.case.caseTable.openCases', { + defaultMessage: 'Open cases', +}); +export const CLOSED_CASES = i18n.translate('xpack.securitySolution.case.caseTable.closedCases', { + defaultMessage: 'Closed cases', +}); + +export const CLOSED = i18n.translate('xpack.securitySolution.case.caseTable.closed', { + defaultMessage: 'Closed', +}); + +export const DELETE = i18n.translate('xpack.securitySolution.case.caseTable.delete', { + defaultMessage: 'Delete', +}); + +export const REQUIRES_UPDATE = i18n.translate( + 'xpack.securitySolution.case.caseTable.requiresUpdate', + { + defaultMessage: ' requires update', + } +); + +export const UP_TO_DATE = i18n.translate('xpack.securitySolution.case.caseTable.upToDate', { + defaultMessage: ' is up to date', +}); +export const NOT_PUSHED = i18n.translate('xpack.securitySolution.case.caseTable.notPushed', { + defaultMessage: 'Not pushed', +}); + +export const REFRESH = i18n.translate('xpack.securitySolution.case.caseTable.refreshTitle', { + defaultMessage: 'Refresh', +}); + +export const SERVICENOW_LINK_ARIA = i18n.translate( + 'xpack.securitySolution.case.caseTable.serviceNowLinkAria', + { + defaultMessage: 'click to view the incident on servicenow', + } +); diff --git a/x-pack/plugins/siem/public/cases/components/bulk_actions/index.tsx b/x-pack/plugins/security_solution/public/cases/components/bulk_actions/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/bulk_actions/index.tsx rename to x-pack/plugins/security_solution/public/cases/components/bulk_actions/index.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/bulk_actions/translations.ts b/x-pack/plugins/security_solution/public/cases/components/bulk_actions/translations.ts new file mode 100644 index 0000000000000..25e22aebb6a0b --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/bulk_actions/translations.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const BULK_ACTION_CLOSE_SELECTED = i18n.translate( + 'xpack.securitySolution.case.caseTable.bulkActions.closeSelectedTitle', + { + defaultMessage: 'Close selected', + } +); + +export const BULK_ACTION_OPEN_SELECTED = i18n.translate( + 'xpack.securitySolution.case.caseTable.bulkActions.openSelectedTitle', + { + defaultMessage: 'Reopen selected', + } +); + +export const BULK_ACTION_DELETE_SELECTED = i18n.translate( + 'xpack.securitySolution.case.caseTable.bulkActions.deleteSelectedTitle', + { + defaultMessage: 'Delete selected', + } +); diff --git a/x-pack/plugins/siem/public/cases/components/callout/helpers.tsx b/x-pack/plugins/security_solution/public/cases/components/callout/helpers.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/callout/helpers.tsx rename to x-pack/plugins/security_solution/public/cases/components/callout/helpers.tsx diff --git a/x-pack/plugins/siem/public/cases/components/callout/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/callout/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/callout/index.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/callout/index.test.tsx diff --git a/x-pack/plugins/siem/public/cases/components/callout/index.tsx b/x-pack/plugins/security_solution/public/cases/components/callout/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/callout/index.tsx rename to x-pack/plugins/security_solution/public/cases/components/callout/index.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/callout/translations.ts b/x-pack/plugins/security_solution/public/cases/components/callout/translations.ts new file mode 100644 index 0000000000000..01956ca942997 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/callout/translations.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const READ_ONLY_SAVED_OBJECT_TITLE = i18n.translate( + 'xpack.securitySolution.case.readOnlySavedObjectTitle', + { + defaultMessage: 'You have read-only feature privileges', + } +); + +export const READ_ONLY_SAVED_OBJECT_MSG = i18n.translate( + 'xpack.securitySolution.case.readOnlySavedObjectDescription', + { + defaultMessage: + 'You are only allowed to view cases. If you need to open and update cases, contact your Kibana administrator', + } +); + +export const DISMISS_CALLOUT = i18n.translate( + 'xpack.securitySolution.case.dismissErrorsPushServiceCallOutTitle', + { + defaultMessage: 'Dismiss', + } +); diff --git a/x-pack/plugins/siem/public/cases/components/case_header_page/index.tsx b/x-pack/plugins/security_solution/public/cases/components/case_header_page/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/case_header_page/index.tsx rename to x-pack/plugins/security_solution/public/cases/components/case_header_page/index.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/case_header_page/translations.ts b/x-pack/plugins/security_solution/public/cases/components/case_header_page/translations.ts new file mode 100644 index 0000000000000..8cdc287b1584c --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/case_header_page/translations.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const PAGE_BADGE_LABEL = i18n.translate( + 'xpack.securitySolution.case.caseView.pageBadgeLabel', + { + defaultMessage: 'Beta', + } +); + +export const PAGE_BADGE_TOOLTIP = i18n.translate( + 'xpack.securitySolution.case.caseView.pageBadgeTooltip', + { + defaultMessage: + 'Case Workflow is still in beta. Please help us improve by reporting issues or bugs in the Kibana repo.', + } +); diff --git a/x-pack/plugins/siem/public/cases/components/case_status/index.tsx b/x-pack/plugins/security_solution/public/cases/components/case_status/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/case_status/index.tsx rename to x-pack/plugins/security_solution/public/cases/components/case_status/index.tsx diff --git a/x-pack/plugins/siem/public/cases/components/case_view/actions.test.tsx b/x-pack/plugins/security_solution/public/cases/components/case_view/actions.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/case_view/actions.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/case_view/actions.test.tsx diff --git a/x-pack/plugins/siem/public/cases/components/case_view/actions.tsx b/x-pack/plugins/security_solution/public/cases/components/case_view/actions.tsx similarity index 97% rename from x-pack/plugins/siem/public/cases/components/case_view/actions.tsx rename to x-pack/plugins/security_solution/public/cases/components/case_view/actions.tsx index cd9318a355e3c..df1082ec48f91 100644 --- a/x-pack/plugins/siem/public/cases/components/case_view/actions.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/case_view/actions.tsx @@ -44,6 +44,7 @@ const CaseViewActionsComponent: React.FC = ({ onConfirm={handleOnDeleteConfirm.bind(null, [{ id: caseData.id, title: caseData.title }])} /> ), + // eslint-disable-next-line react-hooks/exhaustive-deps [isDisplayConfirmDeleteModal, caseData] ); const propertyActions = useMemo( diff --git a/x-pack/plugins/siem/public/cases/components/case_view/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/case_view/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/case_view/index.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/case_view/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx b/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx new file mode 100644 index 0000000000000..bb63cf633747b --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx @@ -0,0 +1,392 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiButtonToggle, + EuiFlexGroup, + EuiFlexItem, + EuiLoadingContent, + EuiLoadingSpinner, + EuiHorizontalRule, +} from '@elastic/eui'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import styled from 'styled-components'; + +import * as i18n from './translations'; +import { Case } from '../../containers/types'; +import { getCaseUrl } from '../../../common/components/link_to'; +import { gutterTimeline } from '../../../common/lib/helpers'; +import { HeaderPage } from '../../../common/components/header_page'; +import { EditableTitle } from '../../../common/components/header_page/editable_title'; +import { TagList } from '../tag_list'; +import { useGetCase } from '../../containers/use_get_case'; +import { UserActionTree } from '../user_action_tree'; +import { UserList } from '../user_list'; +import { useUpdateCase } from '../../containers/use_update_case'; +import { useGetUrlSearch } from '../../../common/components/navigation/use_get_url_search'; +import { getTypedPayload } from '../../containers/utils'; +import { WhitePageWrapper, HeaderWrapper } from '../wrappers'; +import { useBasePath } from '../../../common/lib/kibana'; +import { CaseStatus } from '../case_status'; +import { navTabs } from '../../../app/home/home_navigations'; +import { SpyRoute } from '../../../common/utils/route/spy_routes'; +import { useGetCaseUserActions } from '../../containers/use_get_case_user_actions'; +import { usePushToService } from '../use_push_to_service'; +import { EditConnector } from '../edit_connector'; +import { useConnectors } from '../../containers/configure/use_connectors'; + +interface Props { + caseId: string; + userCanCrud: boolean; +} + +const MyWrapper = styled.div` + padding: ${({ + theme, + }) => `${theme.eui.paddingSizes.l} ${gutterTimeline} ${theme.eui.paddingSizes.l} + ${theme.eui.paddingSizes.l}`}; +`; + +const MyEuiFlexGroup = styled(EuiFlexGroup)` + height: 100%; +`; + +const MyEuiHorizontalRule = styled(EuiHorizontalRule)` + margin-left: 48px; + &.euiHorizontalRule--full { + width: calc(100% - 48px); + } +`; + +export interface CaseProps extends Props { + fetchCase: () => void; + caseData: Case; + updateCase: (newCase: Case) => void; +} + +export const CaseComponent = React.memo( + ({ caseId, caseData, fetchCase, updateCase, userCanCrud }) => { + const basePath = window.location.origin + useBasePath(); + const caseLink = `${basePath}/app/security#/case/${caseId}`; + const search = useGetUrlSearch(navTabs.case); + const [initLoadingData, setInitLoadingData] = useState(true); + const { + caseUserActions, + fetchCaseUserActions, + caseServices, + hasDataToPush, + isLoading: isLoadingUserActions, + participants, + } = useGetCaseUserActions(caseId, caseData.connectorId); + const { isLoading, updateKey, updateCaseProperty } = useUpdateCase({ + caseId, + }); + + // Update Fields + const onUpdateField = useCallback( + (newUpdateKey: keyof Case, updateValue: Case[keyof Case]) => { + const handleUpdateNewCase = (newCase: Case) => + updateCase({ ...newCase, comments: caseData.comments }); + switch (newUpdateKey) { + case 'title': + const titleUpdate = getTypedPayload(updateValue); + if (titleUpdate.length > 0) { + updateCaseProperty({ + fetchCaseUserActions, + updateKey: 'title', + updateValue: titleUpdate, + updateCase: handleUpdateNewCase, + version: caseData.version, + }); + } + break; + case 'connectorId': + const connectorId = getTypedPayload(updateValue); + if (connectorId.length > 0) { + updateCaseProperty({ + fetchCaseUserActions, + updateKey: 'connector_id', + updateValue: connectorId, + updateCase: handleUpdateNewCase, + version: caseData.version, + }); + } + break; + case 'description': + const descriptionUpdate = getTypedPayload(updateValue); + if (descriptionUpdate.length > 0) { + updateCaseProperty({ + fetchCaseUserActions, + updateKey: 'description', + updateValue: descriptionUpdate, + updateCase: handleUpdateNewCase, + version: caseData.version, + }); + } + break; + case 'tags': + const tagsUpdate = getTypedPayload(updateValue); + updateCaseProperty({ + fetchCaseUserActions, + updateKey: 'tags', + updateValue: tagsUpdate, + updateCase: handleUpdateNewCase, + version: caseData.version, + }); + break; + case 'status': + const statusUpdate = getTypedPayload(updateValue); + if (caseData.status !== updateValue) { + updateCaseProperty({ + fetchCaseUserActions, + updateKey: 'status', + updateValue: statusUpdate, + updateCase: handleUpdateNewCase, + version: caseData.version, + }); + } + default: + return null; + } + }, + [fetchCaseUserActions, updateCaseProperty, updateCase, caseData] + ); + const handleUpdateCase = useCallback( + (newCase: Case) => { + updateCase(newCase); + fetchCaseUserActions(newCase.id); + }, + [updateCase, fetchCaseUserActions] + ); + + const { loading: isLoadingConnectors, connectors } = useConnectors(); + + const [caseConnectorName, isValidConnector] = useMemo(() => { + const connector = connectors.find((c) => c.id === caseData.connectorId); + return [connector?.name ?? 'none', !!connector]; + }, [connectors, caseData.connectorId]); + + const currentExternalIncident = useMemo( + () => + caseServices != null && caseServices[caseData.connectorId] != null + ? caseServices[caseData.connectorId] + : null, + [caseServices, caseData.connectorId] + ); + + const { pushButton, pushCallouts } = usePushToService({ + caseConnectorId: caseData.connectorId, + caseConnectorName, + caseServices, + caseId: caseData.id, + caseStatus: caseData.status, + connectors, + updateCase: handleUpdateCase, + userCanCrud, + isValidConnector, + }); + + const onSubmitConnector = useCallback( + (connectorId) => onUpdateField('connectorId', connectorId), + [onUpdateField] + ); + const onSubmitTags = useCallback((newTags) => onUpdateField('tags', newTags), [onUpdateField]); + const onSubmitTitle = useCallback((newTitle) => onUpdateField('title', newTitle), [ + onUpdateField, + ]); + const toggleStatusCase = useCallback( + (e) => onUpdateField('status', e.target.checked ? 'closed' : 'open'), + [onUpdateField] + ); + const handleRefresh = useCallback(() => { + fetchCaseUserActions(caseData.id); + fetchCase(); + }, [caseData.id, fetchCase, fetchCaseUserActions]); + + const spyState = useMemo(() => ({ caseTitle: caseData.title }), [caseData.title]); + + const caseStatusData = useMemo( + () => + caseData.status === 'open' + ? { + 'data-test-subj': 'case-view-createdAt', + value: caseData.createdAt, + title: i18n.CASE_OPENED, + buttonLabel: i18n.CLOSE_CASE, + status: caseData.status, + icon: 'folderCheck', + badgeColor: 'secondary', + isSelected: false, + } + : { + 'data-test-subj': 'case-view-closedAt', + value: caseData.closedAt ?? '', + title: i18n.CASE_CLOSED, + buttonLabel: i18n.REOPEN_CASE, + status: caseData.status, + icon: 'folderExclamation', + badgeColor: 'danger', + isSelected: true, + }, + [caseData.closedAt, caseData.createdAt, caseData.status] + ); + const emailContent = useMemo( + () => ({ + subject: i18n.EMAIL_SUBJECT(caseData.title), + body: i18n.EMAIL_BODY(caseLink), + }), + [caseLink, caseData.title] + ); + + useEffect(() => { + if (initLoadingData && !isLoadingUserActions) { + setInitLoadingData(false); + } + }, [initLoadingData, isLoadingUserActions]); + + const backOptions = useMemo( + () => ({ + href: getCaseUrl(search), + text: i18n.BACK_TO_ALL, + dataTestSubj: 'backToCases', + }), + [search] + ); + + return ( + <> + + + } + title={caseData.title} + > + + + + + + {!initLoadingData && pushCallouts != null && pushCallouts} + + + {initLoadingData && } + {!initLoadingData && ( + <> + + + + + + + {hasDataToPush && ( + + {pushButton} + + )} + + + )} + + + + + + + + + + + + + ); + } +); + +export const CaseView = React.memo(({ caseId, userCanCrud }: Props) => { + const { data, isLoading, isError, fetchCase, updateCase } = useGetCase(caseId); + if (isError) { + return null; + } + if (isLoading) { + return ( + + + + + + ); + } + + return ( + + ); +}); + +CaseComponent.displayName = 'CaseComponent'; +CaseView.displayName = 'CaseView'; diff --git a/x-pack/plugins/security_solution/public/cases/components/case_view/translations.ts b/x-pack/plugins/security_solution/public/cases/components/case_view/translations.ts new file mode 100644 index 0000000000000..b8219ad52f5b0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/case_view/translations.ts @@ -0,0 +1,156 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export * from '../../translations'; + +export const SHOWING_CASES = (actionDate: string, actionName: string, userName: string) => + i18n.translate('xpack.securitySolution.case.caseView.actionHeadline', { + values: { + actionDate, + actionName, + userName, + }, + defaultMessage: '{userName} {actionName} on {actionDate}', + }); + +export const ADDED_FIELD = i18n.translate( + 'xpack.securitySolution.case.caseView.actionLabel.addedField', + { + defaultMessage: 'added', + } +); + +export const CHANGED_FIELD = i18n.translate( + 'xpack.securitySolution.case.caseView.actionLabel.changededField', + { + defaultMessage: 'changed', + } +); + +export const SELECTED_THIRD_PARTY = (thirdParty: string) => + i18n.translate('xpack.securitySolution.case.caseView.actionLabel.selectedThirdParty', { + values: { + thirdParty, + }, + defaultMessage: 'selected { thirdParty } as incident management system', + }); + +export const REMOVED_THIRD_PARTY = i18n.translate( + 'xpack.securitySolution.case.caseView.actionLabel.removedThirdParty', + { + defaultMessage: 'removed external incident management system', + } +); + +export const EDITED_FIELD = i18n.translate( + 'xpack.securitySolution.case.caseView.actionLabel.editedField', + { + defaultMessage: 'edited', + } +); + +export const REMOVED_FIELD = i18n.translate( + 'xpack.securitySolution.case.caseView.actionLabel.removedField', + { + defaultMessage: 'removed', + } +); + +export const VIEW_INCIDENT = (incidentNumber: string) => + i18n.translate('xpack.securitySolution.case.caseView.actionLabel.viewIncident', { + defaultMessage: 'View {incidentNumber}', + values: { + incidentNumber, + }, + }); + +export const PUSHED_NEW_INCIDENT = i18n.translate( + 'xpack.securitySolution.case.caseView.actionLabel.pushedNewIncident', + { + defaultMessage: 'pushed as new incident', + } +); + +export const UPDATE_INCIDENT = i18n.translate( + 'xpack.securitySolution.case.caseView.actionLabel.updateIncident', + { + defaultMessage: 'updated incident', + } +); + +export const ADDED_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.case.caseView.actionLabel.addDescription', + { + defaultMessage: 'added description', + } +); + +export const EDIT_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.case.caseView.edit.description', + { + defaultMessage: 'Edit description', + } +); + +export const QUOTE = i18n.translate('xpack.securitySolution.case.caseView.edit.quote', { + defaultMessage: 'Quote', +}); + +export const EDIT_COMMENT = i18n.translate('xpack.securitySolution.case.caseView.edit.comment', { + defaultMessage: 'Edit comment', +}); + +export const ON = i18n.translate('xpack.securitySolution.case.caseView.actionLabel.on', { + defaultMessage: 'on', +}); + +export const ADDED_COMMENT = i18n.translate( + 'xpack.securitySolution.case.caseView.actionLabel.addComment', + { + defaultMessage: 'added comment', + } +); + +export const STATUS = i18n.translate('xpack.securitySolution.case.caseView.statusLabel', { + defaultMessage: 'Status', +}); + +export const CASE = i18n.translate('xpack.securitySolution.case.caseView.case', { + defaultMessage: 'case', +}); + +export const COMMENT = i18n.translate('xpack.securitySolution.case.caseView.comment', { + defaultMessage: 'comment', +}); + +export const CASE_OPENED = i18n.translate('xpack.securitySolution.case.caseView.caseOpened', { + defaultMessage: 'Case opened', +}); + +export const CASE_CLOSED = i18n.translate('xpack.securitySolution.case.caseView.caseClosed', { + defaultMessage: 'Case closed', +}); + +export const CASE_REFRESH = i18n.translate('xpack.securitySolution.case.caseView.caseRefresh', { + defaultMessage: 'Refresh case', +}); + +export const EMAIL_SUBJECT = (caseTitle: string) => + i18n.translate('xpack.securitySolution.case.caseView.emailSubject', { + values: { caseTitle }, + defaultMessage: 'Security Case - {caseTitle}', + }); + +export const EMAIL_BODY = (caseUrl: string) => + i18n.translate('xpack.securitySolution.case.caseView.emailBody', { + values: { caseUrl }, + defaultMessage: 'Case reference: {caseUrl}', + }); +export const UNKNOWN = i18n.translate('xpack.securitySolution.case.caseView.unknown', { + defaultMessage: 'Unknown', +}); diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/__mock__/index.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/__mock__/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/configure_cases/__mock__/index.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/__mock__/index.tsx diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/button.test.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/button.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/configure_cases/button.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/button.test.tsx diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/button.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/button.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/configure_cases/button.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/button.tsx diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/closure_options.test.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/closure_options.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/configure_cases/closure_options.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/closure_options.test.tsx diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/closure_options.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/closure_options.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/configure_cases/closure_options.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/closure_options.tsx diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/closure_options_radio.test.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/closure_options_radio.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/configure_cases/closure_options_radio.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/closure_options_radio.test.tsx diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/closure_options_radio.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/closure_options_radio.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/configure_cases/closure_options_radio.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/closure_options_radio.tsx diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/connectors.test.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/connectors.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/configure_cases/connectors.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/connectors.test.tsx diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/connectors.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/connectors.tsx similarity index 97% rename from x-pack/plugins/siem/public/cases/components/configure_cases/connectors.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/connectors.tsx index 947d68fd04f7b..b8151cb6fe18c 100644 --- a/x-pack/plugins/siem/public/cases/components/configure_cases/connectors.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/configure_cases/connectors.tsx @@ -68,6 +68,7 @@ const ConnectorsComponent: React.FC = ({
), + // eslint-disable-next-line react-hooks/exhaustive-deps [connectorsName, updateConnectorDisabled] ); diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/connectors_dropdown.test.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/connectors_dropdown.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/configure_cases/connectors_dropdown.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/connectors_dropdown.test.tsx diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/connectors_dropdown.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/connectors_dropdown.tsx similarity index 98% rename from x-pack/plugins/siem/public/cases/components/configure_cases/connectors_dropdown.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/connectors_dropdown.tsx index c5481f592e750..018d3a0fdb4e0 100644 --- a/x-pack/plugins/siem/public/cases/components/configure_cases/connectors_dropdown.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/configure_cases/connectors_dropdown.tsx @@ -91,6 +91,7 @@ const ConnectorsDropdownComponent: React.FC = ({ } return connectorsFormatted; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [connectors]); return ( diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/field_mapping.test.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/field_mapping.test.tsx similarity index 94% rename from x-pack/plugins/siem/public/cases/components/configure_cases/field_mapping.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/field_mapping.test.tsx index 43d5351a5dce3..67963c7487826 100644 --- a/x-pack/plugins/siem/public/cases/components/configure_cases/field_mapping.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/configure_cases/field_mapping.test.tsx @@ -52,7 +52,7 @@ describe('FieldMappingRow', () => { test('it pass the corrects props to mapping row', () => { const rows = wrapper.find(FieldMappingRow); rows.forEach((row, index) => { - expect(row.prop('siemField')).toEqual(mapping[index].source); + expect(row.prop('securitySolutionField')).toEqual(mapping[index].source); expect(row.prop('selectedActionType')).toEqual(mapping[index].actionType); expect(row.prop('selectedThirdParty')).toEqual(mapping[index].target); }); @@ -68,7 +68,7 @@ describe('FieldMappingRow', () => { const rows = newWrapper.find(FieldMappingRow); rows.forEach((row, index) => { - expect(row.prop('siemField')).toEqual(defaultMapping[index].source); + expect(row.prop('securitySolutionField')).toEqual(defaultMapping[index].source); expect(row.prop('selectedActionType')).toEqual(defaultMapping[index].actionType); expect(row.prop('selectedThirdParty')).toEqual(defaultMapping[index].target); }); diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/field_mapping.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/field_mapping.tsx similarity index 96% rename from x-pack/plugins/siem/public/cases/components/configure_cases/field_mapping.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/field_mapping.tsx index 3d515941fc2f3..fe5c0c19820a1 100644 --- a/x-pack/plugins/siem/public/cases/components/configure_cases/field_mapping.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/configure_cases/field_mapping.tsx @@ -95,6 +95,7 @@ const FieldMappingComponent: React.FC = ({ const myMapping = mapping ?? defaultMapping; onChangeMapping(setActionTypeToMapping(caseField, newActionType, myMapping)); }, + // eslint-disable-next-line react-hooks/exhaustive-deps [mapping] ); @@ -103,6 +104,7 @@ const FieldMappingComponent: React.FC = ({ const myMapping = mapping ?? defaultMapping; onChangeMapping(setThirdPartyToMapping(caseField, newThirdPartyField, myMapping)); }, + // eslint-disable-next-line react-hooks/exhaustive-deps [mapping] ); @@ -132,7 +134,7 @@ const FieldMappingComponent: React.FC = ({ key={`${item.source}`} id={`${item.source}`} disabled={disabled} - siemField={item.source} + securitySolutionField={item.source} thirdPartyOptions={getThirdPartyOptions(item.source, selectedConnector.fields)} actionTypeOptions={actionTypeOptions} onChangeActionType={onChangeActionType} diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/field_mapping_row.test.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/field_mapping_row.test.tsx similarity index 98% rename from x-pack/plugins/siem/public/cases/components/configure_cases/field_mapping_row.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/field_mapping_row.test.tsx index 3787a43ff2d28..a2acd0e20b6ad 100644 --- a/x-pack/plugins/siem/public/cases/components/configure_cases/field_mapping_row.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/configure_cases/field_mapping_row.test.tsx @@ -51,7 +51,7 @@ describe('FieldMappingRow', () => { const props: RowProps = { id: 'title', disabled: false, - siemField: 'title', + securitySolutionField: 'title', thirdPartyOptions, actionTypeOptions, onChangeActionType, diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/field_mapping_row.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/field_mapping_row.tsx similarity index 85% rename from x-pack/plugins/siem/public/cases/components/configure_cases/field_mapping_row.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/field_mapping_row.tsx index 922ea7222efce..6e688b213f82c 100644 --- a/x-pack/plugins/siem/public/cases/components/configure_cases/field_mapping_row.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/configure_cases/field_mapping_row.tsx @@ -20,7 +20,7 @@ import { AllThirdPartyFields } from '../../../common/lib/connectors/types'; export interface RowProps { id: string; disabled: boolean; - siemField: CaseField; + securitySolutionField: CaseField; thirdPartyOptions: Array>; actionTypeOptions: Array>; onChangeActionType: (caseField: CaseField, newActionType: ActionType) => void; @@ -32,7 +32,7 @@ export interface RowProps { const FieldMappingRowComponent: React.FC = ({ id, disabled, - siemField, + securitySolutionField, thirdPartyOptions, actionTypeOptions, onChangeActionType, @@ -40,13 +40,15 @@ const FieldMappingRowComponent: React.FC = ({ selectedActionType, selectedThirdParty, }) => { - const siemFieldCapitalized = useMemo(() => capitalize(siemField), [siemField]); + const securitySolutionFieldCapitalized = useMemo(() => capitalize(securitySolutionField), [ + securitySolutionField, + ]); return ( - {siemFieldCapitalized} + {securitySolutionFieldCapitalized} @@ -58,7 +60,7 @@ const FieldMappingRowComponent: React.FC = ({ disabled={disabled} options={thirdPartyOptions} valueOfSelected={selectedThirdParty} - onChange={onChangeThirdParty.bind(null, siemField)} + onChange={onChangeThirdParty.bind(null, securitySolutionField)} data-test-subj={`case-configure-third-party-select-${id}`} /> @@ -67,7 +69,7 @@ const FieldMappingRowComponent: React.FC = ({ disabled={disabled} options={actionTypeOptions} valueOfSelected={selectedActionType} - onChange={onChangeActionType.bind(null, siemField)} + onChange={onChangeActionType.bind(null, securitySolutionField)} data-test-subj={`case-configure-action-type-select-${id}`} /> diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/configure_cases/index.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.tsx new file mode 100644 index 0000000000000..256c8893be941 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.tsx @@ -0,0 +1,223 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback, useEffect, useState, Dispatch, SetStateAction } from 'react'; +import styled, { css } from 'styled-components'; + +import { EuiCallOut } from '@elastic/eui'; + +import { useKibana } from '../../../common/lib/kibana'; +import { useConnectors } from '../../containers/configure/use_connectors'; +import { useCaseConfigure } from '../../containers/configure/use_configure'; +import { + ActionsConnectorsContextProvider, + ActionType, + ConnectorAddFlyout, + ConnectorEditFlyout, +} from '../../../../../triggers_actions_ui/public'; + +import { ClosureType } from '../../containers/configure/types'; + +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { ActionConnectorTableItem } from '../../../../../triggers_actions_ui/public/types'; +import { connectorsConfiguration } from '../../../common/lib/connectors/config'; + +import { Connectors } from './connectors'; +import { ClosureOptions } from './closure_options'; +import { SectionWrapper } from '../wrappers'; +import * as i18n from './translations'; + +const FormWrapper = styled.div` + ${({ theme }) => css` + & > * { + margin-top 40px; + } + + & > :first-child { + margin-top: 0; + } + + padding-top: ${theme.eui.paddingSizes.xl}; + padding-bottom: ${theme.eui.paddingSizes.xl}; + `} +`; + +const actionTypes: ActionType[] = Object.values(connectorsConfiguration); + +interface ConfigureCasesComponentProps { + userCanCrud: boolean; +} + +const ConfigureCasesComponent: React.FC = ({ userCanCrud }) => { + const { http, triggers_actions_ui, notifications, application, docLinks } = useKibana().services; + + const [connectorIsValid, setConnectorIsValid] = useState(true); + const [addFlyoutVisible, setAddFlyoutVisibility] = useState(false); + const [editFlyoutVisible, setEditFlyoutVisibility] = useState(false); + const [editedConnectorItem, setEditedConnectorItem] = useState( + null + ); + + const { + connectorId, + closureType, + currentConfiguration, + loading: loadingCaseConfigure, + persistLoading, + version, + persistCaseConfigure, + setConnector, + setClosureType, + } = useCaseConfigure(); + + const { loading: isLoadingConnectors, connectors, refetchConnectors } = useConnectors(); + + // ActionsConnectorsContextProvider reloadConnectors prop expects a Promise. + // TODO: Fix it if reloadConnectors type change. + // eslint-disable-next-line react-hooks/exhaustive-deps + const reloadConnectors = useCallback(async () => refetchConnectors(), []); + const isLoadingAny = isLoadingConnectors || persistLoading || loadingCaseConfigure; + const updateConnectorDisabled = isLoadingAny || !connectorIsValid || connectorId === 'none'; + + const onClickUpdateConnector = useCallback(() => { + setEditFlyoutVisibility(true); + }, []); + + const handleSetAddFlyoutVisibility = useCallback( + (isVisible: boolean) => { + setAddFlyoutVisibility(isVisible); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [currentConfiguration, connectorId, closureType] + ); + + const handleSetEditFlyoutVisibility = useCallback( + (isVisible: boolean) => { + setEditFlyoutVisibility(isVisible); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [currentConfiguration, connectorId, closureType] + ); + + const onChangeConnector = useCallback( + (id: string) => { + if (id === 'add-connector') { + setAddFlyoutVisibility(true); + return; + } + + setConnector(id); + persistCaseConfigure({ + connectorId: id, + connectorName: connectors.find((c) => c.id === id)?.name ?? '', + closureType, + }); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [connectorId, closureType, version] + ); + + const onChangeClosureType = useCallback( + (type: ClosureType) => { + setClosureType(type); + persistCaseConfigure({ + connectorId, + connectorName: connectors.find((c) => c.id === connectorId)?.name ?? '', + closureType: type, + }); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [connectorId, closureType, version] + ); + + useEffect(() => { + if ( + !isLoadingConnectors && + connectorId !== 'none' && + !connectors.some((c) => c.id === connectorId) + ) { + setConnectorIsValid(false); + } else if ( + !isLoadingConnectors && + (connectorId === 'none' || connectors.some((c) => c.id === connectorId)) + ) { + setConnectorIsValid(true); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [connectors, connectorId]); + + useEffect(() => { + if (!isLoadingConnectors && connectorId !== 'none') { + setEditedConnectorItem( + connectors.find((c) => c.id === connectorId) as ActionConnectorTableItem + ); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [connectors, connectorId]); + + return ( + + {!connectorIsValid && ( + + + {i18n.WARNING_NO_CONNECTOR_MESSAGE} + + + )} + + + + + + + + >} + actionTypes={actionTypes} + /> + {editedConnectorItem && ( + > + } + /> + )} + + + ); +}; + +export const ConfigureCases = React.memo(ConfigureCasesComponent); diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/mapping.test.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/mapping.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/configure_cases/mapping.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/mapping.test.tsx diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/mapping.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/mapping.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/configure_cases/mapping.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/mapping.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/configure_cases/translations.ts b/x-pack/plugins/security_solution/public/cases/components/configure_cases/translations.ts new file mode 100644 index 0000000000000..9ef6ce2f3d4a9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/configure_cases/translations.ts @@ -0,0 +1,184 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const INCIDENT_MANAGEMENT_SYSTEM_TITLE = i18n.translate( + 'xpack.securitySolution.case.configureCases.incidentManagementSystemTitle', + { + defaultMessage: 'Connect to external incident management system', + } +); + +export const INCIDENT_MANAGEMENT_SYSTEM_DESC = i18n.translate( + 'xpack.securitySolution.case.configureCases.incidentManagementSystemDesc', + { + defaultMessage: + 'You may optionally connect Security cases to an external incident management system of your choosing. This will allow you to push case data as an incident in your chosen third-party system.', + } +); + +export const INCIDENT_MANAGEMENT_SYSTEM_LABEL = i18n.translate( + 'xpack.securitySolution.case.configureCases.incidentManagementSystemLabel', + { + defaultMessage: 'Incident management system', + } +); + +export const NO_CONNECTOR = i18n.translate( + 'xpack.securitySolution.case.configureCases.noConnector', + { + defaultMessage: 'No connector selected', + } +); + +export const ADD_NEW_CONNECTOR = i18n.translate( + 'xpack.securitySolution.case.configureCases.addNewConnector', + { + defaultMessage: 'Add new connector', + } +); + +export const CASE_CLOSURE_OPTIONS_TITLE = i18n.translate( + 'xpack.securitySolution.case.configureCases.caseClosureOptionsTitle', + { + defaultMessage: 'Case Closures', + } +); + +export const CASE_CLOSURE_OPTIONS_DESC = i18n.translate( + 'xpack.securitySolution.case.configureCases.caseClosureOptionsDesc', + { + defaultMessage: + 'Define how you wish Security cases to be closed. Automated case closures require an established connection to an external incident management system.', + } +); + +export const CASE_CLOSURE_OPTIONS_LABEL = i18n.translate( + 'xpack.securitySolution.case.configureCases.caseClosureOptionsLabel', + { + defaultMessage: 'Case closure options', + } +); + +export const CASE_CLOSURE_OPTIONS_MANUAL = i18n.translate( + 'xpack.securitySolution.case.configureCases.caseClosureOptionsManual', + { + defaultMessage: 'Manually close Security cases', + } +); + +export const CASE_CLOSURE_OPTIONS_NEW_INCIDENT = i18n.translate( + 'xpack.securitySolution.case.configureCases.caseClosureOptionsNewIncident', + { + defaultMessage: + 'Automatically close Security cases when pushing new incident to external system', + } +); + +export const CASE_CLOSURE_OPTIONS_CLOSED_INCIDENT = i18n.translate( + 'xpack.securitySolution.case.configureCases.caseClosureOptionsClosedIncident', + { + defaultMessage: 'Automatically close Security cases when incident is closed in external system', + } +); + +export const FIELD_MAPPING_TITLE = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingTitle', + { + defaultMessage: 'Field mappings', + } +); + +export const FIELD_MAPPING_DESC = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingDesc', + { + defaultMessage: + 'Map Security case fields when pushing data to a third-party. Field mappings require an established connection to an external incident management system.', + } +); + +export const FIELD_MAPPING_FIRST_COL = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingFirstCol', + { + defaultMessage: 'Security case field', + } +); + +export const FIELD_MAPPING_SECOND_COL = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingSecondCol', + { + defaultMessage: 'External incident field', + } +); + +export const FIELD_MAPPING_THIRD_COL = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingThirdCol', + { + defaultMessage: 'On edit and update', + } +); + +export const FIELD_MAPPING_EDIT_NOTHING = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingEditNothing', + { + defaultMessage: 'Nothing', + } +); + +export const FIELD_MAPPING_EDIT_OVERWRITE = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingEditOverwrite', + { + defaultMessage: 'Overwrite', + } +); + +export const FIELD_MAPPING_EDIT_APPEND = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingEditAppend', + { + defaultMessage: 'Append', + } +); + +export const CANCEL = i18n.translate('xpack.securitySolution.case.configureCases.cancelButton', { + defaultMessage: 'Cancel', +}); + +export const WARNING_NO_CONNECTOR_TITLE = i18n.translate( + 'xpack.securitySolution.case.configureCases.warningTitle', + { + defaultMessage: 'Warning', + } +); + +export const WARNING_NO_CONNECTOR_MESSAGE = i18n.translate( + 'xpack.securitySolution.case.configureCases.warningMessage', + { + defaultMessage: + 'The selected connector has been deleted. Either select a different connector or create a new one.', + } +); + +export const MAPPING_FIELD_NOT_MAPPED = i18n.translate( + 'xpack.securitySolution.case.configureCases.mappingFieldNotMapped', + { + defaultMessage: 'Not mapped', + } +); + +export const UPDATE_CONNECTOR = i18n.translate( + 'xpack.securitySolution.case.configureCases.updateConnector', + { + defaultMessage: 'Update connector', + } +); + +export const UPDATE_SELECTED_CONNECTOR = (connectorName: string): string => { + return i18n.translate('xpack.securitySolution.case.configureCases.updateSelectedConnector', { + values: { connectorName }, + defaultMessage: 'Update { connectorName }', + }); +}; diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/utils.test.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/utils.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/configure_cases/utils.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/utils.test.tsx diff --git a/x-pack/plugins/siem/public/cases/components/configure_cases/utils.ts b/x-pack/plugins/security_solution/public/cases/components/configure_cases/utils.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/components/configure_cases/utils.ts rename to x-pack/plugins/security_solution/public/cases/components/configure_cases/utils.ts diff --git a/x-pack/plugins/siem/public/cases/components/confirm_delete_case/index.tsx b/x-pack/plugins/security_solution/public/cases/components/confirm_delete_case/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/confirm_delete_case/index.tsx rename to x-pack/plugins/security_solution/public/cases/components/confirm_delete_case/index.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/confirm_delete_case/translations.ts b/x-pack/plugins/security_solution/public/cases/components/confirm_delete_case/translations.ts new file mode 100644 index 0000000000000..ad51d13206809 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/confirm_delete_case/translations.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; +export * from '../../translations'; + +export const DELETE_TITLE = (caseTitle: string) => + i18n.translate('xpack.securitySolution.case.confirmDeleteCase.deleteTitle', { + values: { caseTitle }, + defaultMessage: 'Delete "{caseTitle}"', + }); + +export const CONFIRM_QUESTION = i18n.translate( + 'xpack.securitySolution.case.confirmDeleteCase.confirmQuestion', + { + defaultMessage: + 'By deleting this case, all related case data will be permanently removed and you will no longer be able to push data to an external incident management system. Are you sure you wish to proceed?', + } +); +export const DELETE_SELECTED_CASES = i18n.translate( + 'xpack.securitySolution.case.confirmDeleteCase.selectedCases', + { + defaultMessage: 'Delete selected cases', + } +); + +export const CONFIRM_QUESTION_PLURAL = i18n.translate( + 'xpack.securitySolution.case.confirmDeleteCase.confirmQuestionPlural', + { + defaultMessage: + 'By deleting these cases, all related case data will be permanently removed and you will no longer be able to push data to an external incident management system. Are you sure you wish to proceed?', + } +); diff --git a/x-pack/plugins/siem/public/cases/components/connector_selector/form.tsx b/x-pack/plugins/security_solution/public/cases/components/connector_selector/form.tsx similarity index 96% rename from x-pack/plugins/siem/public/cases/components/connector_selector/form.tsx rename to x-pack/plugins/security_solution/public/cases/components/connector_selector/form.tsx index 9e058ee5cf09e..1706fa38bb8a0 100644 --- a/x-pack/plugins/siem/public/cases/components/connector_selector/form.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/connector_selector/form.tsx @@ -33,6 +33,7 @@ export const ConnectorSelector = ({ useEffect(() => { field.setValue(defaultValue); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [defaultValue]); const handleContentChange = useCallback( diff --git a/x-pack/plugins/siem/public/cases/components/create/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/create/index.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/create/index.tsx b/x-pack/plugins/security_solution/public/cases/components/create/index.tsx new file mode 100644 index 0000000000000..1b65b2582c760 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/create/index.tsx @@ -0,0 +1,217 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React, { useCallback, useEffect, useState } from 'react'; +import { + EuiButton, + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiLoadingSpinner, + EuiPanel, +} from '@elastic/eui'; +import styled, { css } from 'styled-components'; +import { Redirect } from 'react-router-dom'; + +import { isEqual } from 'lodash/fp'; +import { CasePostRequest } from '../../../../../case/common/api'; +import { + Field, + Form, + getUseField, + useForm, + UseField, + FormDataProvider, +} from '../../../shared_imports'; +import { usePostCase } from '../../containers/use_post_case'; +import { schema } from './schema'; +import { InsertTimelinePopover } from '../../../timelines/components/timeline/insert_timeline_popover'; +import { useInsertTimeline } from '../../../timelines/components/timeline/insert_timeline_popover/use_insert_timeline'; +import * as i18n from '../../translations'; +import { SiemPageName } from '../../../app/types'; +import { MarkdownEditorForm } from '../../../common/components//markdown_editor/form'; +import { useGetTags } from '../../containers/use_get_tags'; + +export const CommonUseField = getUseField({ component: Field }); + +const ContainerBig = styled.div` + ${({ theme }) => css` + margin-top: ${theme.eui.euiSizeXL}; + `} +`; + +const Container = styled.div` + ${({ theme }) => css` + margin-top: ${theme.eui.euiSize}; + `} +`; +const MySpinner = styled(EuiLoadingSpinner)` + position: absolute; + top: 50%; + left: 50%; + z-index: 99; +`; + +const initialCaseValue: CasePostRequest = { + description: '', + tags: [], + title: '', +}; + +export const Create = React.memo(() => { + const { caseData, isLoading, postCase } = usePostCase(); + const [isCancel, setIsCancel] = useState(false); + const { form } = useForm({ + defaultValue: initialCaseValue, + options: { stripEmptyFields: false }, + schema, + }); + const { tags: tagOptions } = useGetTags(); + const [options, setOptions] = useState( + tagOptions.map((label) => ({ + label, + })) + ); + useEffect( + () => + setOptions( + tagOptions.map((label) => ({ + label, + })) + ), + [tagOptions] + ); + const { handleCursorChange, handleOnTimelineChange } = useInsertTimeline( + form, + 'description' + ); + + const onSubmit = useCallback(async () => { + const { isValid, data } = await form.submit(); + if (isValid) { + // `postCase`'s type is incorrect, it actually returns a promise + await postCase(data); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [form]); + + const handleSetIsCancel = useCallback(() => { + setIsCancel(true); + }, []); + + if (caseData != null && caseData.id) { + return ; + } + + if (isCancel) { + return ; + } + + return ( + + {isLoading && } +
+ + + + + + + ), + }} + /> + + + {({ tags: anotherTags }) => { + const current: string[] = options.map((opt) => opt.label); + const newOptions = anotherTags.reduce((acc: string[], item: string) => { + if (!acc.includes(item)) { + return [...acc, item]; + } + return acc; + }, current); + if (!isEqual(current, newOptions)) { + setOptions( + newOptions.map((label: string) => ({ + label, + })) + ); + } + return null; + }} + + + + + + + {i18n.CANCEL} + + + + + {i18n.CREATE_CASE} + + + + +
+ ); +}); + +Create.displayName = 'Create'; diff --git a/x-pack/plugins/siem/public/cases/components/create/optional_field_label/index.tsx b/x-pack/plugins/security_solution/public/cases/components/create/optional_field_label/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/create/optional_field_label/index.tsx rename to x-pack/plugins/security_solution/public/cases/components/create/optional_field_label/index.tsx diff --git a/x-pack/plugins/siem/public/cases/components/create/schema.tsx b/x-pack/plugins/security_solution/public/cases/components/create/schema.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/create/schema.tsx rename to x-pack/plugins/security_solution/public/cases/components/create/schema.tsx diff --git a/x-pack/plugins/siem/public/cases/components/edit_connector/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/edit_connector/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/edit_connector/index.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/edit_connector/index.test.tsx diff --git a/x-pack/plugins/siem/public/cases/components/edit_connector/index.tsx b/x-pack/plugins/security_solution/public/cases/components/edit_connector/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/edit_connector/index.tsx rename to x-pack/plugins/security_solution/public/cases/components/edit_connector/index.tsx diff --git a/x-pack/plugins/siem/public/cases/components/edit_connector/schema.tsx b/x-pack/plugins/security_solution/public/cases/components/edit_connector/schema.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/edit_connector/schema.tsx rename to x-pack/plugins/security_solution/public/cases/components/edit_connector/schema.tsx diff --git a/x-pack/plugins/siem/public/cases/components/filter_popover/index.tsx b/x-pack/plugins/security_solution/public/cases/components/filter_popover/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/filter_popover/index.tsx rename to x-pack/plugins/security_solution/public/cases/components/filter_popover/index.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/open_closed_stats/index.tsx b/x-pack/plugins/security_solution/public/cases/components/open_closed_stats/index.tsx new file mode 100644 index 0000000000000..e7d5299842494 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/open_closed_stats/index.tsx @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useMemo } from 'react'; +import { EuiDescriptionList, EuiLoadingSpinner } from '@elastic/eui'; +import * as i18n from '../all_cases/translations'; + +export interface Props { + caseCount: number | null; + caseStatus: 'open' | 'closed'; + isLoading: boolean; + dataTestSubj?: string; +} + +export const OpenClosedStats = React.memo( + ({ caseCount, caseStatus, isLoading, dataTestSubj }) => { + const openClosedStats = useMemo( + () => [ + { + title: caseStatus === 'open' ? i18n.OPEN_CASES : i18n.CLOSED_CASES, + description: isLoading ? : caseCount ?? 'N/A', + }, + ], + // eslint-disable-next-line react-hooks/exhaustive-deps + [caseCount, caseStatus, isLoading, dataTestSubj] + ); + return ( + + ); + } +); + +OpenClosedStats.displayName = 'OpenClosedStats'; diff --git a/x-pack/plugins/siem/public/cases/components/property_actions/constants.ts b/x-pack/plugins/security_solution/public/cases/components/property_actions/constants.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/components/property_actions/constants.ts rename to x-pack/plugins/security_solution/public/cases/components/property_actions/constants.ts diff --git a/x-pack/plugins/siem/public/cases/components/property_actions/index.tsx b/x-pack/plugins/security_solution/public/cases/components/property_actions/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/property_actions/index.tsx rename to x-pack/plugins/security_solution/public/cases/components/property_actions/index.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/property_actions/translations.ts b/x-pack/plugins/security_solution/public/cases/components/property_actions/translations.ts new file mode 100644 index 0000000000000..a00abcc7845b0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/property_actions/translations.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const ACTIONS_ARIA = i18n.translate( + 'xpack.securitySolution.case.caseView.editActionsLinkAria', + { + defaultMessage: 'click to see all actions', + } +); diff --git a/x-pack/plugins/siem/public/cases/components/tag_list/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/tag_list/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/tag_list/index.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/tag_list/index.test.tsx diff --git a/x-pack/plugins/siem/public/cases/components/tag_list/index.tsx b/x-pack/plugins/security_solution/public/cases/components/tag_list/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/tag_list/index.tsx rename to x-pack/plugins/security_solution/public/cases/components/tag_list/index.tsx diff --git a/x-pack/plugins/siem/public/cases/components/tag_list/schema.tsx b/x-pack/plugins/security_solution/public/cases/components/tag_list/schema.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/tag_list/schema.tsx rename to x-pack/plugins/security_solution/public/cases/components/tag_list/schema.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/tag_list/translations.ts b/x-pack/plugins/security_solution/public/cases/components/tag_list/translations.ts new file mode 100644 index 0000000000000..3aeb6391267f6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/tag_list/translations.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export * from '../../translations'; + +export const EDIT_TAGS_ARIA = i18n.translate( + 'xpack.securitySolution.case.caseView.editTagsLinkAria', + { + defaultMessage: 'click to edit tags', + } +); diff --git a/x-pack/plugins/security_solution/public/cases/components/use_push_to_service/helpers.tsx b/x-pack/plugins/security_solution/public/cases/components/use_push_to_service/helpers.tsx new file mode 100644 index 0000000000000..919231d2f6034 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/use_push_to_service/helpers.tsx @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiLink } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import React from 'react'; + +import * as i18n from './translations'; +import { ActionLicense } from '../../containers/types'; + +export const getLicenseError = () => ({ + title: i18n.PUSH_DISABLE_BY_LICENSE_TITLE, + description: ( + + {i18n.LINK_CLOUD_DEPLOYMENT} + + ), + }} + /> + ), +}); + +export const getKibanaConfigError = () => ({ + title: i18n.PUSH_DISABLE_BY_KIBANA_CONFIG_TITLE, + description: ( + + {'coming soon...'} + + ), + }} + /> + ), +}); + +export const getActionLicenseError = ( + actionLicense: ActionLicense | null +): Array<{ title: string; description: JSX.Element }> => { + let errors: Array<{ title: string; description: JSX.Element }> = []; + if (actionLicense != null && !actionLicense.enabledInLicense) { + errors = [...errors, getLicenseError()]; + } + if (actionLicense != null && !actionLicense.enabledInConfig) { + errors = [...errors, getKibanaConfigError()]; + } + return errors; +}; diff --git a/x-pack/plugins/siem/public/cases/components/use_push_to_service/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/use_push_to_service/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/use_push_to_service/index.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/use_push_to_service/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/use_push_to_service/index.tsx b/x-pack/plugins/security_solution/public/cases/components/use_push_to_service/index.tsx new file mode 100644 index 0000000000000..f18870787ded1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/use_push_to_service/index.tsx @@ -0,0 +1,199 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiButton, EuiLink, EuiToolTip } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import React, { useCallback, useMemo } from 'react'; + +import { Case } from '../../containers/types'; +import { useGetActionLicense } from '../../containers/use_get_action_license'; +import { usePostPushToService } from '../../containers/use_post_push_to_service'; +import { getConfigureCasesUrl } from '../../../common/components/link_to'; +import { useGetUrlSearch } from '../../../common/components/navigation/use_get_url_search'; +import { navTabs } from '../../../app/home/home_navigations'; +import { CaseCallOut } from '../callout'; +import { getLicenseError, getKibanaConfigError } from './helpers'; +import * as i18n from './translations'; +import { Connector } from '../../../../../case/common/api/cases'; +import { CaseServices } from '../../containers/use_get_case_user_actions'; + +export interface UsePushToService { + caseId: string; + caseStatus: string; + caseConnectorId: string; + caseConnectorName: string; + caseServices: CaseServices; + connectors: Connector[]; + updateCase: (newCase: Case) => void; + userCanCrud: boolean; + isValidConnector: boolean; +} + +export interface ReturnUsePushToService { + pushButton: JSX.Element; + pushCallouts: JSX.Element | null; +} + +export const usePushToService = ({ + caseConnectorId, + caseConnectorName, + caseId, + caseServices, + caseStatus, + connectors, + updateCase, + userCanCrud, + isValidConnector, +}: UsePushToService): ReturnUsePushToService => { + const urlSearch = useGetUrlSearch(navTabs.case); + + const { isLoading, postPushToService } = usePostPushToService(); + + const { isLoading: loadingLicense, actionLicense } = useGetActionLicense(); + + const handlePushToService = useCallback(() => { + if (caseConnectorId != null && caseConnectorId !== 'none') { + postPushToService({ + caseId, + caseServices, + connectorId: caseConnectorId, + connectorName: caseConnectorName, + updateCase, + }); + } + }, [caseId, caseServices, caseConnectorId, caseConnectorName, postPushToService, updateCase]); + + const errorsMsg = useMemo(() => { + let errors: Array<{ + title: string; + description: JSX.Element; + errorType?: 'primary' | 'success' | 'warning' | 'danger'; + }> = []; + if (actionLicense != null && !actionLicense.enabledInLicense) { + errors = [...errors, getLicenseError()]; + } + if (connectors.length === 0 && caseConnectorId === 'none' && !loadingLicense) { + errors = [ + ...errors, + { + title: i18n.PUSH_DISABLE_BY_NO_CONFIG_TITLE, + description: ( + + {i18n.LINK_CONNECTOR_CONFIGURE} + + ), + }} + /> + ), + }, + ]; + } else if (caseConnectorId === 'none' && !loadingLicense) { + errors = [ + ...errors, + { + title: i18n.PUSH_DISABLE_BY_NO_CASE_CONFIG_TITLE, + description: ( + + ), + }, + ]; + } else if (!isValidConnector && !loadingLicense) { + errors = [ + ...errors, + { + title: i18n.PUSH_DISABLE_BY_NO_CASE_CONFIG_TITLE, + description: ( + + ), + errorType: 'danger', + }, + ]; + } + if (caseStatus === 'closed') { + errors = [ + ...errors, + { + title: i18n.PUSH_DISABLE_BECAUSE_CASE_CLOSED_TITLE, + description: ( + + ), + }, + ]; + } + if (actionLicense != null && !actionLicense.enabledInConfig) { + errors = [...errors, getKibanaConfigError()]; + } + return errors; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [actionLicense, caseStatus, connectors.length, caseConnectorId, loadingLicense, urlSearch]); + + const pushToServiceButton = useMemo(() => { + return ( + 0 || !userCanCrud || !isValidConnector + } + isLoading={isLoading} + > + {caseServices[caseConnectorId] + ? i18n.UPDATE_THIRD(caseConnectorName) + : i18n.PUSH_THIRD(caseConnectorName)} + + ); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ + caseConnectorId, + caseConnectorName, + connectors, + errorsMsg, + handlePushToService, + isLoading, + loadingLicense, + userCanCrud, + isValidConnector, + ]); + + const objToReturn = useMemo(() => { + return { + pushButton: + errorsMsg.length > 0 ? ( + {errorsMsg[0].description}

} + > + {pushToServiceButton} +
+ ) : ( + <>{pushToServiceButton} + ), + pushCallouts: + errorsMsg.length > 0 ? ( + + ) : null, + }; + }, [errorsMsg, pushToServiceButton]); + + return objToReturn; +}; diff --git a/x-pack/plugins/security_solution/public/cases/components/use_push_to_service/translations.ts b/x-pack/plugins/security_solution/public/cases/components/use_push_to_service/translations.ts new file mode 100644 index 0000000000000..f4539b8019d43 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/use_push_to_service/translations.ts @@ -0,0 +1,88 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const ERROR_PUSH_SERVICE_CALLOUT_TITLE = i18n.translate( + 'xpack.securitySolution.case.caseView.errorsPushServiceCallOutTitle', + { + defaultMessage: 'To send cases to external systems, you need to:', + } +); +export const PUSH_THIRD = (thirdParty: string) => { + if (thirdParty === 'none') { + return i18n.translate('xpack.securitySolution.case.caseView.pushThirdPartyIncident', { + defaultMessage: 'Push as external incident', + }); + } + + return i18n.translate('xpack.securitySolution.case.caseView.pushNamedIncident', { + values: { thirdParty }, + defaultMessage: 'Push as { thirdParty } incident', + }); +}; + +export const UPDATE_THIRD = (thirdParty: string) => { + if (thirdParty === 'none') { + return i18n.translate('xpack.securitySolution.case.caseView.updateThirdPartyIncident', { + defaultMessage: 'Update external incident', + }); + } + + return i18n.translate('xpack.securitySolution.case.caseView.updateNamedIncident', { + values: { thirdParty }, + defaultMessage: 'Update { thirdParty } incident', + }); +}; + +export const PUSH_DISABLE_BY_NO_CONFIG_TITLE = i18n.translate( + 'xpack.securitySolution.case.caseView.pushToServiceDisableByNoConfigTitle', + { + defaultMessage: 'Configure external connector', + } +); + +export const PUSH_DISABLE_BY_NO_CASE_CONFIG_TITLE = i18n.translate( + 'xpack.securitySolution.case.caseView.pushToServiceDisableByNoCaseConfigTitle', + { + defaultMessage: 'Select external connector', + } +); + +export const PUSH_DISABLE_BECAUSE_CASE_CLOSED_TITLE = i18n.translate( + 'xpack.securitySolution.case.caseView.pushToServiceDisableBecauseCaseClosedTitle', + { + defaultMessage: 'Reopen the case', + } +); + +export const PUSH_DISABLE_BY_KIBANA_CONFIG_TITLE = i18n.translate( + 'xpack.securitySolution.case.caseView.pushToServiceDisableByConfigTitle', + { + defaultMessage: 'Enable external service in Kibana configuration file', + } +); + +export const PUSH_DISABLE_BY_LICENSE_TITLE = i18n.translate( + 'xpack.securitySolution.case.caseView.pushToServiceDisableByLicenseTitle', + { + defaultMessage: 'Upgrade to Elastic Platinum', + } +); + +export const LINK_CLOUD_DEPLOYMENT = i18n.translate( + 'xpack.securitySolution.case.caseView.cloudDeploymentLink', + { + defaultMessage: 'cloud deployment', + } +); + +export const LINK_CONNECTOR_CONFIGURE = i18n.translate( + 'xpack.securitySolution.case.caseView.connectorConfigureLink', + { + defaultMessage: 'connector', + } +); diff --git a/x-pack/plugins/siem/public/cases/components/user_action_tree/helpers.test.tsx b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/helpers.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/user_action_tree/helpers.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/user_action_tree/helpers.test.tsx diff --git a/x-pack/plugins/siem/public/cases/components/user_action_tree/helpers.tsx b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/helpers.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/user_action_tree/helpers.tsx rename to x-pack/plugins/security_solution/public/cases/components/user_action_tree/helpers.tsx diff --git a/x-pack/plugins/siem/public/cases/components/user_action_tree/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/user_action_tree/index.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.tsx b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.tsx new file mode 100644 index 0000000000000..52c2779a93fc0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.tsx @@ -0,0 +1,307 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui'; +import React, { useCallback, useMemo, useRef, useState, useEffect } from 'react'; +import { useParams } from 'react-router-dom'; +import styled from 'styled-components'; + +import * as i18n from '../case_view/translations'; + +import { Case, CaseUserActions } from '../../containers/types'; +import { useUpdateComment } from '../../containers/use_update_comment'; +import { useCurrentUser } from '../../../common/lib/kibana'; +import { AddComment } from '../add_comment'; +import { getLabelTitle } from './helpers'; +import { UserActionItem } from './user_action_item'; +import { UserActionMarkdown } from './user_action_markdown'; +import { Connector } from '../../../../../case/common/api/cases'; +import { CaseServices } from '../../containers/use_get_case_user_actions'; +import { parseString } from '../../containers/utils'; + +export interface UserActionTreeProps { + caseServices: CaseServices; + caseUserActions: CaseUserActions[]; + connectors: Connector[]; + data: Case; + fetchUserActions: () => void; + isLoadingDescription: boolean; + isLoadingUserActions: boolean; + onUpdateField: (updateKey: keyof Case, updateValue: string | string[]) => void; + updateCase: (newCase: Case) => void; + userCanCrud: boolean; +} + +const MyEuiFlexGroup = styled(EuiFlexGroup)` + margin-bottom: 8px; +`; + +const DESCRIPTION_ID = 'description'; +const NEW_ID = 'newComment'; + +export const UserActionTree = React.memo( + ({ + data: caseData, + caseServices, + caseUserActions, + connectors, + fetchUserActions, + isLoadingDescription, + isLoadingUserActions, + onUpdateField, + updateCase, + userCanCrud, + }: UserActionTreeProps) => { + const { commentId } = useParams(); + const handlerTimeoutId = useRef(0); + const [initLoading, setInitLoading] = useState(true); + const [selectedOutlineCommentId, setSelectedOutlineCommentId] = useState(''); + const { isLoadingIds, patchComment } = useUpdateComment(); + const currentUser = useCurrentUser(); + const [manageMarkdownEditIds, setManangeMardownEditIds] = useState([]); + const [insertQuote, setInsertQuote] = useState(null); + const handleManageMarkdownEditId = useCallback( + (id: string) => { + if (!manageMarkdownEditIds.includes(id)) { + setManangeMardownEditIds([...manageMarkdownEditIds, id]); + } else { + setManangeMardownEditIds(manageMarkdownEditIds.filter((myId) => id !== myId)); + } + }, + [manageMarkdownEditIds] + ); + + const handleSaveComment = useCallback( + ({ id, version }: { id: string; version: string }, content: string) => { + patchComment({ + caseId: caseData.id, + commentId: id, + commentUpdate: content, + fetchUserActions, + version, + updateCase, + }); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [caseData, handleManageMarkdownEditId, patchComment, updateCase] + ); + + const handleOutlineComment = useCallback( + (id: string) => { + const moveToTarget = document.getElementById(`${id}-permLink`); + if (moveToTarget != null) { + const yOffset = -60; + const y = moveToTarget.getBoundingClientRect().top + window.pageYOffset + yOffset; + window.scrollTo({ + top: y, + behavior: 'smooth', + }); + if (id === 'add-comment') { + moveToTarget.getElementsByTagName('textarea')[0].focus(); + } + } + window.clearTimeout(handlerTimeoutId.current); + setSelectedOutlineCommentId(id); + handlerTimeoutId.current = window.setTimeout(() => { + setSelectedOutlineCommentId(''); + window.clearTimeout(handlerTimeoutId.current); + }, 2400); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [handlerTimeoutId.current] + ); + + const handleManageQuote = useCallback( + (quote: string) => { + const addCarrots = quote.replace(new RegExp('\r?\n', 'g'), ' \n> '); + setInsertQuote(`> ${addCarrots} \n`); + handleOutlineComment('add-comment'); + }, + [handleOutlineComment] + ); + + const handleUpdate = useCallback( + (newCase: Case) => { + updateCase(newCase); + fetchUserActions(); + }, + [fetchUserActions, updateCase] + ); + + const MarkdownDescription = useMemo( + () => ( + { + onUpdateField(DESCRIPTION_ID, content); + }} + onChangeEditable={handleManageMarkdownEditId} + /> + ), + [caseData.description, handleManageMarkdownEditId, manageMarkdownEditIds, onUpdateField] + ); + + const MarkdownNewComment = useMemo( + () => ( + + ), + // eslint-disable-next-line react-hooks/exhaustive-deps + [caseData.id, handleUpdate, insertQuote, userCanCrud] + ); + + useEffect(() => { + if (initLoading && !isLoadingUserActions && isLoadingIds.length === 0) { + setInitLoading(false); + if (commentId != null) { + handleOutlineComment(commentId); + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [commentId, initLoading, isLoadingUserActions, isLoadingIds]); + return ( + <> + {i18n.ADDED_DESCRIPTION}} + fullName={caseData.createdBy.fullName ?? caseData.createdBy.username ?? ''} + markdown={MarkdownDescription} + onEdit={handleManageMarkdownEditId.bind(null, DESCRIPTION_ID)} + onQuote={handleManageQuote.bind(null, caseData.description)} + username={caseData.createdBy.username ?? i18n.UNKNOWN} + /> + + {caseUserActions.map((action, index) => { + if (action.commentId != null && action.action === 'create') { + const comment = caseData.comments.find((c) => c.id === action.commentId); + if (comment != null) { + return ( + {i18n.ADDED_COMMENT}} + fullName={comment.createdBy.fullName ?? comment.createdBy.username ?? ''} + markdown={ + + } + onEdit={handleManageMarkdownEditId.bind(null, comment.id)} + onQuote={handleManageQuote.bind(null, comment.comment)} + outlineComment={handleOutlineComment} + username={comment.createdBy.username ?? ''} + updatedAt={comment.updatedAt} + /> + ); + } + } + if (action.actionField.length === 1) { + const myField = action.actionField[0]; + const parsedValue = parseString(`${action.newValue}`); + const { firstPush, parsedConnectorId, parsedConnectorName } = + parsedValue != null + ? { + firstPush: caseServices[parsedValue.connector_id].firstPushIndex === index, + parsedConnectorId: parsedValue.connector_id, + parsedConnectorName: parsedValue.connector_name, + } + : { + firstPush: false, + parsedConnectorId: 'none', + parsedConnectorName: 'none', + }; + const labelTitle: string | JSX.Element = getLabelTitle({ + action, + field: myField, + firstPush, + connectors, + }); + + return ( + {labelTitle}} + linkId={ + action.action === 'update' && action.commentId != null ? action.commentId : null + } + fullName={action.actionBy.fullName ?? action.actionBy.username ?? ''} + outlineComment={handleOutlineComment} + showTopFooter={ + action.action === 'push-to-service' && + index === caseServices[parsedConnectorId].lastPushIndex + } + showBottomFooter={ + action.action === 'push-to-service' && + index === caseServices[parsedConnectorId].lastPushIndex && + caseServices[parsedConnectorId].hasDataToPush + } + username={action.actionBy.username ?? ''} + /> + ); + } + return null; + })} + {(isLoadingUserActions || isLoadingIds.includes(NEW_ID)) && ( + + + + + + )} + + + ); + } +); + +UserActionTree.displayName = 'UserActionTree'; diff --git a/x-pack/plugins/siem/public/cases/components/user_action_tree/schema.ts b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/schema.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/components/user_action_tree/schema.ts rename to x-pack/plugins/security_solution/public/cases/components/user_action_tree/schema.ts diff --git a/x-pack/plugins/security_solution/public/cases/components/user_action_tree/translations.ts b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/translations.ts new file mode 100644 index 0000000000000..73c94477b4e73 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/translations.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export * from '../case_view/translations'; + +export const ALREADY_PUSHED_TO_SERVICE = (externalService: string) => + i18n.translate('xpack.securitySolution.case.caseView.alreadyPushedToExternalService', { + values: { externalService }, + defaultMessage: 'Already pushed to { externalService } incident', + }); + +export const REQUIRED_UPDATE_TO_SERVICE = (externalService: string) => + i18n.translate('xpack.securitySolution.case.caseView.requiredUpdateToExternalService', { + values: { externalService }, + defaultMessage: 'Requires update to { externalService } incident', + }); + +export const COPY_REFERENCE_LINK = i18n.translate( + 'xpack.securitySolution.case.caseView.copyCommentLinkAria', + { + defaultMessage: 'Copy reference link', + } +); + +export const MOVE_TO_ORIGINAL_COMMENT = i18n.translate( + 'xpack.securitySolution.case.caseView.moveToCommentAria', + { + defaultMessage: 'Highlight the referenced comment', + } +); diff --git a/x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_avatar.tsx b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/user_action_avatar.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_avatar.tsx rename to x-pack/plugins/security_solution/public/cases/components/user_action_tree/user_action_avatar.tsx diff --git a/x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_item.tsx b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/user_action_item.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_item.tsx rename to x-pack/plugins/security_solution/public/cases/components/user_action_tree/user_action_item.tsx diff --git a/x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_markdown.test.tsx b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/user_action_markdown.test.tsx similarity index 97% rename from x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_markdown.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/user_action_tree/user_action_markdown.test.tsx index 8e07706d9c6ba..ae9f1ec7469e4 100644 --- a/x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_markdown.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/user_action_markdown.test.tsx @@ -18,7 +18,7 @@ const onSaveContent = jest.fn(); const timelineId = '1e10f150-949b-11ea-b63c-2bc51864784c'; const defaultProps = { - content: `A link to a timeline [timeline](http://localhost:5601/app/siem#/timelines?timeline=(id:'${timelineId}',isOpen:!t))`, + content: `A link to a timeline [timeline](http://localhost:5601/app/security#/timelines?timeline=(id:'${timelineId}',isOpen:!t))`, id: 'markdown-id', isEditable: false, onChangeEditable, diff --git a/x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_markdown.tsx b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/user_action_markdown.tsx similarity index 97% rename from x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_markdown.tsx rename to x-pack/plugins/security_solution/public/cases/components/user_action_tree/user_action_markdown.tsx index 03dd599da88e5..b3a5f1e0158d8 100644 --- a/x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_markdown.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/user_action_markdown.tsx @@ -74,6 +74,7 @@ export const UserActionMarkdown = ({ updateTimeline: dispatchUpdateTimeline(dispatch), }); }, + // eslint-disable-next-line react-hooks/exhaustive-deps [apolloClient] ); @@ -114,6 +115,7 @@ export const UserActionMarkdown = ({
); }, + // eslint-disable-next-line react-hooks/exhaustive-deps [handleCancelAction, handleSaveAction] ); return isEditable ? ( diff --git a/x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_title.test.tsx b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/user_action_title.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_title.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/user_action_tree/user_action_title.test.tsx diff --git a/x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_title.tsx b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/user_action_title.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/user_action_tree/user_action_title.tsx rename to x-pack/plugins/security_solution/public/cases/components/user_action_tree/user_action_title.tsx diff --git a/x-pack/plugins/siem/public/cases/components/user_list/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/user_list/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/user_list/index.test.tsx rename to x-pack/plugins/security_solution/public/cases/components/user_list/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/cases/components/user_list/index.tsx b/x-pack/plugins/security_solution/public/cases/components/user_list/index.tsx new file mode 100644 index 0000000000000..86ff42561c409 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/user_list/index.tsx @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback } from 'react'; +import { isEmpty } from 'lodash/fp'; + +import { + EuiButtonIcon, + EuiText, + EuiHorizontalRule, + EuiAvatar, + EuiFlexGroup, + EuiFlexItem, + EuiLoadingSpinner, + EuiToolTip, +} from '@elastic/eui'; + +import styled, { css } from 'styled-components'; + +import { ElasticUser } from '../../containers/types'; +import * as i18n from './translations'; + +interface UserListProps { + email: { + subject: string; + body: string; + }; + headline: string; + loading?: boolean; + users: ElasticUser[]; +} + +const MyAvatar = styled(EuiAvatar)` + top: -4px; +`; + +const MyFlexGroup = styled(EuiFlexGroup)` + ${({ theme }) => css` + margin-top: ${theme.eui.euiSizeM}; + `} +`; + +const renderUsers = ( + users: ElasticUser[], + handleSendEmail: (emailAddress: string | undefined | null) => void +) => + users.map(({ fullName, username, email }, key) => ( + + + + + + + + {fullName ? fullName : username ?? ''}

}> +

+ + {username} + +

+
+
+
+
+ + + +
+ )); + +export const UserList = React.memo(({ email, headline, loading, users }: UserListProps) => { + const handleSendEmail = useCallback( + (emailAddress: string | undefined | null) => { + if (emailAddress && emailAddress != null) { + window.open(`mailto:${emailAddress}?subject=${email.subject}&body=${email.body}`, '_blank'); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [email.subject] + ); + return users.filter(({ username }) => username != null && username !== '').length > 0 ? ( + +

{headline}

+ + {loading && ( + + + + + + )} + {renderUsers( + users.filter(({ username }) => username != null && username !== ''), + handleSendEmail + )} +
+ ) : null; +}); + +UserList.displayName = 'UserList'; diff --git a/x-pack/plugins/security_solution/public/cases/components/user_list/translations.ts b/x-pack/plugins/security_solution/public/cases/components/user_list/translations.ts new file mode 100644 index 0000000000000..3439d58eb41f0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/components/user_list/translations.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const SEND_EMAIL_ARIA = (user: string) => + i18n.translate('xpack.securitySolution.case.caseView.sendEmalLinkAria', { + values: { user }, + defaultMessage: 'click to send an email to {user}', + }); diff --git a/x-pack/plugins/siem/public/cases/components/wrappers/index.tsx b/x-pack/plugins/security_solution/public/cases/components/wrappers/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/components/wrappers/index.tsx rename to x-pack/plugins/security_solution/public/cases/components/wrappers/index.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/__mocks__/api.ts b/x-pack/plugins/security_solution/public/cases/containers/__mocks__/api.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/__mocks__/api.ts rename to x-pack/plugins/security_solution/public/cases/containers/__mocks__/api.ts diff --git a/x-pack/plugins/siem/public/cases/containers/api.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/api.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/api.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/api.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/api.ts b/x-pack/plugins/security_solution/public/cases/containers/api.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/api.ts rename to x-pack/plugins/security_solution/public/cases/containers/api.ts diff --git a/x-pack/plugins/siem/public/cases/containers/configure/__mocks__/api.ts b/x-pack/plugins/security_solution/public/cases/containers/configure/__mocks__/api.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/configure/__mocks__/api.ts rename to x-pack/plugins/security_solution/public/cases/containers/configure/__mocks__/api.ts diff --git a/x-pack/plugins/siem/public/cases/containers/configure/api.test.ts b/x-pack/plugins/security_solution/public/cases/containers/configure/api.test.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/configure/api.test.ts rename to x-pack/plugins/security_solution/public/cases/containers/configure/api.test.ts diff --git a/x-pack/plugins/siem/public/cases/containers/configure/api.ts b/x-pack/plugins/security_solution/public/cases/containers/configure/api.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/configure/api.ts rename to x-pack/plugins/security_solution/public/cases/containers/configure/api.ts diff --git a/x-pack/plugins/siem/public/cases/containers/configure/mock.ts b/x-pack/plugins/security_solution/public/cases/containers/configure/mock.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/configure/mock.ts rename to x-pack/plugins/security_solution/public/cases/containers/configure/mock.ts diff --git a/x-pack/plugins/security_solution/public/cases/containers/configure/translations.ts b/x-pack/plugins/security_solution/public/cases/containers/configure/translations.ts new file mode 100644 index 0000000000000..ee21167021e19 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/containers/configure/translations.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export * from '../translations'; + +export const SUCCESS_CONFIGURE = i18n.translate( + 'xpack.securitySolution.case.configure.successSaveToast', + { + defaultMessage: 'Saved external connection settings', + } +); diff --git a/x-pack/plugins/siem/public/cases/containers/configure/types.ts b/x-pack/plugins/security_solution/public/cases/containers/configure/types.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/configure/types.ts rename to x-pack/plugins/security_solution/public/cases/containers/configure/types.ts diff --git a/x-pack/plugins/siem/public/cases/containers/configure/use_configure.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/configure/use_configure.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/configure/use_configure.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/configure/use_configure.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/configure/use_configure.tsx b/x-pack/plugins/security_solution/public/cases/containers/configure/use_configure.tsx similarity index 97% rename from x-pack/plugins/siem/public/cases/containers/configure/use_configure.tsx rename to x-pack/plugins/security_solution/public/cases/containers/configure/use_configure.tsx index 5a85a3a0633bc..e89212036ec20 100644 --- a/x-pack/plugins/siem/public/cases/containers/configure/use_configure.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/configure/use_configure.tsx @@ -253,6 +253,7 @@ export const useCaseConfigure = (): ReturnUseCaseConfigure => { didCancel = true; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [state.firstLoad]); const persistCaseConfigure = useCallback( @@ -311,11 +312,13 @@ export const useCaseConfigure = (): ReturnUseCaseConfigure => { abortCtrl.abort(); }; }, + // eslint-disable-next-line react-hooks/exhaustive-deps [state.version] ); useEffect(() => { refetchCaseConfigure(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return { diff --git a/x-pack/plugins/siem/public/cases/containers/configure/use_connectors.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/configure/use_connectors.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/configure/use_connectors.tsx b/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx similarity index 93% rename from x-pack/plugins/siem/public/cases/containers/configure/use_connectors.tsx rename to x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx index 9cd755864d37b..812e580ad653f 100644 --- a/x-pack/plugins/siem/public/cases/containers/configure/use_connectors.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx @@ -50,10 +50,12 @@ export const useConnectors = (): ReturnConnectors => { didCancel = true; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { refetchConnectors(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return { diff --git a/x-pack/plugins/siem/public/cases/containers/constants.ts b/x-pack/plugins/security_solution/public/cases/containers/constants.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/constants.ts rename to x-pack/plugins/security_solution/public/cases/containers/constants.ts diff --git a/x-pack/plugins/siem/public/cases/containers/mock.ts b/x-pack/plugins/security_solution/public/cases/containers/mock.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/mock.ts rename to x-pack/plugins/security_solution/public/cases/containers/mock.ts diff --git a/x-pack/plugins/security_solution/public/cases/containers/translations.ts b/x-pack/plugins/security_solution/public/cases/containers/translations.ts new file mode 100644 index 0000000000000..96d2ec2f874db --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/containers/translations.ts @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const ERROR_TITLE = i18n.translate('xpack.securitySolution.containers.case.errorTitle', { + defaultMessage: 'Error fetching data', +}); + +export const ERROR_DELETING = i18n.translate( + 'xpack.securitySolution.containers.case.errorDeletingTitle', + { + defaultMessage: 'Error deleting data', + } +); + +export const UPDATED_CASE = (caseTitle: string) => + i18n.translate('xpack.securitySolution.containers.case.updatedCase', { + values: { caseTitle }, + defaultMessage: 'Updated "{caseTitle}"', + }); + +export const DELETED_CASES = (totalCases: number, caseTitle?: string) => + i18n.translate('xpack.securitySolution.containers.case.deletedCases', { + values: { caseTitle, totalCases }, + defaultMessage: 'Deleted {totalCases, plural, =1 {"{caseTitle}"} other {{totalCases} cases}}', + }); + +export const CLOSED_CASES = ({ + totalCases, + caseTitle, +}: { + totalCases: number; + caseTitle?: string; +}) => + i18n.translate('xpack.securitySolution.containers.case.closedCases', { + values: { caseTitle, totalCases }, + defaultMessage: 'Closed {totalCases, plural, =1 {"{caseTitle}"} other {{totalCases} cases}}', + }); + +export const REOPENED_CASES = ({ + totalCases, + caseTitle, +}: { + totalCases: number; + caseTitle?: string; +}) => + i18n.translate('xpack.securitySolution.containers.case.reopenedCases', { + values: { caseTitle, totalCases }, + defaultMessage: 'Reopened {totalCases, plural, =1 {"{caseTitle}"} other {{totalCases} cases}}', + }); + +export const SUCCESS_SEND_TO_EXTERNAL_SERVICE = (serviceName: string) => + i18n.translate('xpack.securitySolution.containers.case.pushToExternalService', { + values: { serviceName }, + defaultMessage: 'Successfully sent to { serviceName }', + }); + +export const ERROR_PUSH_TO_SERVICE = i18n.translate( + 'xpack.securitySolution.case.configure.errorPushingToService', + { + defaultMessage: 'Error pushing to service', + } +); diff --git a/x-pack/plugins/siem/public/cases/containers/types.ts b/x-pack/plugins/security_solution/public/cases/containers/types.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/types.ts rename to x-pack/plugins/security_solution/public/cases/containers/types.ts diff --git a/x-pack/plugins/siem/public/cases/containers/use_bulk_update_case.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_bulk_update_case.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/use_bulk_update_case.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_bulk_update_case.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/use_bulk_update_case.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_bulk_update_case.tsx similarity index 96% rename from x-pack/plugins/siem/public/cases/containers/use_bulk_update_case.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_bulk_update_case.tsx index ef68f4f48b1a0..c333ff4207833 100644 --- a/x-pack/plugins/siem/public/cases/containers/use_bulk_update_case.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_bulk_update_case.tsx @@ -108,6 +108,7 @@ export const useUpdateCases = (): UseUpdateCases => { cancel = true; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const dispatchResetIsUpdated = useCallback(() => { @@ -121,6 +122,7 @@ export const useUpdateCases = (): UseUpdateCases => { version: theCase.version, })); dispatchUpdateCases(updateCasesStatus); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return { ...state, updateBulkStatus, dispatchResetIsUpdated }; }; diff --git a/x-pack/plugins/siem/public/cases/containers/use_delete_cases.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_delete_cases.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/use_delete_cases.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_delete_cases.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/use_delete_cases.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_delete_cases.tsx similarity index 94% rename from x-pack/plugins/siem/public/cases/containers/use_delete_cases.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_delete_cases.tsx index 2e8c7dfae2313..f47e9e51f865a 100644 --- a/x-pack/plugins/siem/public/cases/containers/use_delete_cases.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_delete_cases.tsx @@ -110,6 +110,7 @@ export const useDeleteCases = (): UseDeleteCase => { abortCtrl.abort(); cancel = true; }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const dispatchToggleDeleteModal = useCallback(() => { @@ -118,6 +119,7 @@ export const useDeleteCases = (): UseDeleteCase => { const dispatchResetIsDeleted = useCallback(() => { dispatch({ type: 'RESET_IS_DELETED' }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [state.isDisplayConfirmDeleteModal]); const handleOnDeleteConfirm = useCallback( @@ -125,10 +127,12 @@ export const useDeleteCases = (): UseDeleteCase => { dispatchDeleteCases(cases); dispatchToggleDeleteModal(); }, + // eslint-disable-next-line react-hooks/exhaustive-deps [state.isDisplayConfirmDeleteModal] ); const handleToggleModal = useCallback(() => { dispatchToggleDeleteModal(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [state.isDisplayConfirmDeleteModal]); return { ...state, dispatchResetIsDeleted, handleOnDeleteConfirm, handleToggleModal }; diff --git a/x-pack/plugins/siem/public/cases/containers/use_get_action_license.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_get_action_license.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/use_get_action_license.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_get_action_license.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/use_get_action_license.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_get_action_license.tsx similarity index 94% rename from x-pack/plugins/siem/public/cases/containers/use_get_action_license.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_get_action_license.tsx index 563e2a4a58c70..e289a1973cf6e 100644 --- a/x-pack/plugins/siem/public/cases/containers/use_get_action_license.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_get_action_license.tsx @@ -65,10 +65,12 @@ export const useGetActionLicense = (): ActionLicenseState => { didCancel = true; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [actionLicenseState]); useEffect(() => { fetchActionLicense(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return { ...actionLicenseState }; }; diff --git a/x-pack/plugins/siem/public/cases/containers/use_get_case.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_get_case.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/use_get_case.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_get_case.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/use_get_case.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_get_case.tsx similarity index 96% rename from x-pack/plugins/siem/public/cases/containers/use_get_case.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_get_case.tsx index 01ada00ba9b72..ea4da41151993 100644 --- a/x-pack/plugins/siem/public/cases/containers/use_get_case.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_get_case.tsx @@ -118,10 +118,12 @@ export const useGetCase = (caseId: string): UseGetCase => { didCancel = true; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [caseId]); useEffect(() => { callFetch(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [caseId]); return { ...state, fetchCase: callFetch, updateCase }; }; diff --git a/x-pack/plugins/siem/public/cases/containers/use_get_case_user_actions.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_get_case_user_actions.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/use_get_case_user_actions.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_get_case_user_actions.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/use_get_case_user_actions.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_get_case_user_actions.tsx similarity index 98% rename from x-pack/plugins/siem/public/cases/containers/use_get_case_user_actions.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_get_case_user_actions.tsx index 050b2815dc511..76d939de06a0a 100644 --- a/x-pack/plugins/siem/public/cases/containers/use_get_case_user_actions.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_get_case_user_actions.tsx @@ -210,6 +210,7 @@ export const useGetCaseUserActions = ( abortCtrl.abort(); }; }, + // eslint-disable-next-line react-hooks/exhaustive-deps [caseUserActionsState, caseConnectorId] ); @@ -217,6 +218,7 @@ export const useGetCaseUserActions = ( if (!isEmpty(caseId)) { fetchCaseUserActions(caseId); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [caseId, caseConnectorId]); return { ...caseUserActionsState, fetchCaseUserActions }; }; diff --git a/x-pack/plugins/siem/public/cases/containers/use_get_cases.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_get_cases.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/use_get_cases.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_get_cases.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/use_get_cases.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_get_cases.tsx similarity index 96% rename from x-pack/plugins/siem/public/cases/containers/use_get_cases.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_get_cases.tsx index 45b571a8fe7e2..fdf526a1e4d88 100644 --- a/x-pack/plugins/siem/public/cases/containers/use_get_cases.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_get_cases.tsx @@ -184,8 +184,10 @@ export const useGetCases = (initialQueryParams?: QueryParams): UseGetCases => { abortCtrl.abort(); didCancel = true; }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + // eslint-disable-next-line react-hooks/exhaustive-deps useEffect(() => fetchCases(state.filterOptions, state.queryParams), [ state.queryParams, state.filterOptions, @@ -224,11 +226,13 @@ export const useGetCases = (initialQueryParams?: QueryParams): UseGetCases => { didCancel = true; }; }, + // eslint-disable-next-line react-hooks/exhaustive-deps [state.filterOptions, state.queryParams] ); const refetchCases = useCallback(() => { fetchCases(state.filterOptions, state.queryParams); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [state.filterOptions, state.queryParams]); return { diff --git a/x-pack/plugins/siem/public/cases/containers/use_get_cases_status.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_get_cases_status.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/use_get_cases_status.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_get_cases_status.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/use_get_cases_status.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_get_cases_status.tsx similarity index 94% rename from x-pack/plugins/siem/public/cases/containers/use_get_cases_status.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_get_cases_status.tsx index 476462b7e4c28..5260b6d5cc283 100644 --- a/x-pack/plugins/siem/public/cases/containers/use_get_cases_status.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_get_cases_status.tsx @@ -69,10 +69,12 @@ export const useGetCasesStatus = (): UseGetCasesStatus => { didCancel = true; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [casesStatusState]); useEffect(() => { fetchCasesStatus(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return { diff --git a/x-pack/plugins/siem/public/cases/containers/use_get_reporters.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_get_reporters.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/use_get_reporters.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_get_reporters.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/use_get_reporters.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_get_reporters.tsx similarity index 95% rename from x-pack/plugins/siem/public/cases/containers/use_get_reporters.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_get_reporters.tsx index d723b8cc37c23..b4ca775660910 100644 --- a/x-pack/plugins/siem/public/cases/containers/use_get_reporters.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_get_reporters.tsx @@ -79,10 +79,12 @@ export const useGetReporters = (): UseGetReporters => { didCancel = true; abortCtrl.abort(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [reportersState]); useEffect(() => { fetchReporters(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return { ...reportersState, fetchReporters }; }; diff --git a/x-pack/plugins/siem/public/cases/containers/use_get_tags.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_get_tags.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/use_get_tags.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_get_tags.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/use_get_tags.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_get_tags.tsx similarity index 97% rename from x-pack/plugins/siem/public/cases/containers/use_get_tags.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_get_tags.tsx index 14f5e35bc4976..eded326719e52 100644 --- a/x-pack/plugins/siem/public/cases/containers/use_get_tags.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_get_tags.tsx @@ -89,6 +89,7 @@ export const useGetTags = (): UseGetTags => { }; useEffect(() => { callFetch(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return { ...state, fetchTags: callFetch }; }; diff --git a/x-pack/plugins/siem/public/cases/containers/use_post_case.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_post_case.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/use_post_case.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_post_case.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/use_post_case.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_post_case.tsx similarity index 97% rename from x-pack/plugins/siem/public/cases/containers/use_post_case.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_post_case.tsx index 13cfc2738620f..0752fe9b2071c 100644 --- a/x-pack/plugins/siem/public/cases/containers/use_post_case.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_post_case.tsx @@ -86,6 +86,7 @@ export const usePostCase = (): UsePostCase => { abortCtrl.abort(); cancel = true; }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return { ...state, postCase: postMyCase }; diff --git a/x-pack/plugins/siem/public/cases/containers/use_post_comment.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_post_comment.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/use_post_comment.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_post_comment.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/use_post_comment.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_post_comment.tsx similarity index 97% rename from x-pack/plugins/siem/public/cases/containers/use_post_comment.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_post_comment.tsx index 9a52eaaf0db6b..e6cb8a9c3d150 100644 --- a/x-pack/plugins/siem/public/cases/containers/use_post_comment.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_post_comment.tsx @@ -79,6 +79,7 @@ export const usePostComment = (caseId: string): UsePostComment => { cancel = true; }; }, + // eslint-disable-next-line react-hooks/exhaustive-deps [caseId] ); diff --git a/x-pack/plugins/siem/public/cases/containers/use_post_push_to_service.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_post_push_to_service.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/use_post_push_to_service.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_post_push_to_service.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/use_post_push_to_service.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_post_push_to_service.tsx similarity index 98% rename from x-pack/plugins/siem/public/cases/containers/use_post_push_to_service.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_post_push_to_service.tsx index 4d25ac7fbf0db..0d8a4c04ca7cd 100644 --- a/x-pack/plugins/siem/public/cases/containers/use_post_push_to_service.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_post_push_to_service.tsx @@ -146,6 +146,7 @@ export const usePostPushToService = (): UsePostPushToService => { abortCtrl.abort(); }; }, + // eslint-disable-next-line react-hooks/exhaustive-deps [] ); diff --git a/x-pack/plugins/siem/public/cases/containers/use_update_case.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_update_case.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/use_update_case.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_update_case.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/use_update_case.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_update_case.tsx similarity index 98% rename from x-pack/plugins/siem/public/cases/containers/use_update_case.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_update_case.tsx index 77cf53165d914..18dd9f5278503 100644 --- a/x-pack/plugins/siem/public/cases/containers/use_update_case.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_update_case.tsx @@ -118,6 +118,7 @@ export const useUpdateCase = ({ caseId }: { caseId: string }): UseUpdateCase => abortCtrl.abort(); }; }, + // eslint-disable-next-line react-hooks/exhaustive-deps [] ); diff --git a/x-pack/plugins/siem/public/cases/containers/use_update_comment.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_update_comment.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/use_update_comment.test.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_update_comment.test.tsx diff --git a/x-pack/plugins/siem/public/cases/containers/use_update_comment.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_update_comment.tsx similarity index 98% rename from x-pack/plugins/siem/public/cases/containers/use_update_comment.tsx rename to x-pack/plugins/security_solution/public/cases/containers/use_update_comment.tsx index 821fd5523a751..f896185dbccfb 100644 --- a/x-pack/plugins/siem/public/cases/containers/use_update_comment.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_update_comment.tsx @@ -111,6 +111,7 @@ export const useUpdateComment = (): UseUpdateComment => { abortCtrl.abort(); }; }, + // eslint-disable-next-line react-hooks/exhaustive-deps [] ); diff --git a/x-pack/plugins/siem/public/cases/containers/utils.ts b/x-pack/plugins/security_solution/public/cases/containers/utils.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/containers/utils.ts rename to x-pack/plugins/security_solution/public/cases/containers/utils.ts diff --git a/x-pack/plugins/siem/public/cases/index.ts b/x-pack/plugins/security_solution/public/cases/index.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/index.ts rename to x-pack/plugins/security_solution/public/cases/index.ts diff --git a/x-pack/plugins/siem/public/cases/pages/case.tsx b/x-pack/plugins/security_solution/public/cases/pages/case.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/pages/case.tsx rename to x-pack/plugins/security_solution/public/cases/pages/case.tsx diff --git a/x-pack/plugins/siem/public/cases/pages/case_details.tsx b/x-pack/plugins/security_solution/public/cases/pages/case_details.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/pages/case_details.tsx rename to x-pack/plugins/security_solution/public/cases/pages/case_details.tsx diff --git a/x-pack/plugins/siem/public/cases/pages/configure_cases.tsx b/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/pages/configure_cases.tsx rename to x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx diff --git a/x-pack/plugins/siem/public/cases/pages/create_case.tsx b/x-pack/plugins/security_solution/public/cases/pages/create_case.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/pages/create_case.tsx rename to x-pack/plugins/security_solution/public/cases/pages/create_case.tsx diff --git a/x-pack/plugins/siem/public/cases/pages/index.tsx b/x-pack/plugins/security_solution/public/cases/pages/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/pages/index.tsx rename to x-pack/plugins/security_solution/public/cases/pages/index.tsx diff --git a/x-pack/plugins/siem/public/cases/pages/saved_object_no_permissions.tsx b/x-pack/plugins/security_solution/public/cases/pages/saved_object_no_permissions.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/pages/saved_object_no_permissions.tsx rename to x-pack/plugins/security_solution/public/cases/pages/saved_object_no_permissions.tsx diff --git a/x-pack/plugins/security_solution/public/cases/pages/translations.ts b/x-pack/plugins/security_solution/public/cases/pages/translations.ts new file mode 100644 index 0000000000000..5b595c5892ef2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/pages/translations.ts @@ -0,0 +1,232 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const SAVED_OBJECT_NO_PERMISSIONS_TITLE = i18n.translate( + 'xpack.securitySolution.case.caseSavedObjectNoPermissionsTitle', + { + defaultMessage: 'Kibana feature privileges required', + } +); + +export const SAVED_OBJECT_NO_PERMISSIONS_MSG = i18n.translate( + 'xpack.securitySolution.case.caseSavedObjectNoPermissionsMessage', + { + defaultMessage: + 'To view cases, you must have privileges for the Saved Object Management feature in the Kibana space. For more information, contact your Kibana administrator.', + } +); + +export const BACK_TO_ALL = i18n.translate('xpack.securitySolution.case.caseView.backLabel', { + defaultMessage: 'Back to cases', +}); + +export const CANCEL = i18n.translate('xpack.securitySolution.case.caseView.cancel', { + defaultMessage: 'Cancel', +}); + +export const DELETE_CASE = i18n.translate( + 'xpack.securitySolution.case.confirmDeleteCase.deleteCase', + { + defaultMessage: 'Delete case', + } +); + +export const DELETE_CASES = i18n.translate( + 'xpack.securitySolution.case.confirmDeleteCase.deleteCases', + { + defaultMessage: 'Delete cases', + } +); + +export const NAME = i18n.translate('xpack.securitySolution.case.caseView.name', { + defaultMessage: 'Name', +}); + +export const OPENED_ON = i18n.translate('xpack.securitySolution.case.caseView.openedOn', { + defaultMessage: 'Opened on', +}); + +export const CLOSED_ON = i18n.translate('xpack.securitySolution.case.caseView.closedOn', { + defaultMessage: 'Closed on', +}); + +export const REPORTER = i18n.translate('xpack.securitySolution.case.caseView.reporterLabel', { + defaultMessage: 'Reporter', +}); + +export const PARTICIPANTS = i18n.translate( + 'xpack.securitySolution.case.caseView.particpantsLabel', + { + defaultMessage: 'Participants', + } +); + +export const CREATE_BC_TITLE = i18n.translate('xpack.securitySolution.case.caseView.breadcrumb', { + defaultMessage: 'Create', +}); + +export const CREATE_TITLE = i18n.translate('xpack.securitySolution.case.caseView.create', { + defaultMessage: 'Create new case', +}); + +export const DESCRIPTION = i18n.translate('xpack.securitySolution.case.caseView.description', { + defaultMessage: 'Description', +}); + +export const DESCRIPTION_REQUIRED = i18n.translate( + 'xpack.securitySolution.case.createCase.descriptionFieldRequiredError', + { + defaultMessage: 'A description is required.', + } +); + +export const COMMENT_REQUIRED = i18n.translate( + 'xpack.securitySolution.case.caseView.commentFieldRequiredError', + { + defaultMessage: 'A comment is required.', + } +); + +export const REQUIRED_FIELD = i18n.translate( + 'xpack.securitySolution.case.caseView.fieldRequiredError', + { + defaultMessage: 'Required field', + } +); + +export const EDIT = i18n.translate('xpack.securitySolution.case.caseView.edit', { + defaultMessage: 'Edit', +}); + +export const OPTIONAL = i18n.translate('xpack.securitySolution.case.caseView.optional', { + defaultMessage: 'Optional', +}); + +export const PAGE_TITLE = i18n.translate('xpack.securitySolution.case.pageTitle', { + defaultMessage: 'Cases', +}); + +export const CREATE_CASE = i18n.translate('xpack.securitySolution.case.caseView.createCase', { + defaultMessage: 'Create case', +}); + +export const CLOSED_CASE = i18n.translate('xpack.securitySolution.case.caseView.closedCase', { + defaultMessage: 'Closed case', +}); + +export const CLOSE_CASE = i18n.translate('xpack.securitySolution.case.caseView.closeCase', { + defaultMessage: 'Close case', +}); + +export const REOPEN_CASE = i18n.translate('xpack.securitySolution.case.caseView.reopenCase', { + defaultMessage: 'Reopen case', +}); + +export const REOPENED_CASE = i18n.translate('xpack.securitySolution.case.caseView.reopenedCase', { + defaultMessage: 'Reopened case', +}); + +export const CASE_NAME = i18n.translate('xpack.securitySolution.case.caseView.caseName', { + defaultMessage: 'Case name', +}); + +export const TO = i18n.translate('xpack.securitySolution.case.caseView.to', { + defaultMessage: 'to', +}); + +export const TAGS = i18n.translate('xpack.securitySolution.case.caseView.tags', { + defaultMessage: 'Tags', +}); + +export const ACTIONS = i18n.translate('xpack.securitySolution.case.allCases.actions', { + defaultMessage: 'Actions', +}); + +export const NO_TAGS_AVAILABLE = i18n.translate( + 'xpack.securitySolution.case.allCases.noTagsAvailable', + { + defaultMessage: 'No tags available', + } +); + +export const NO_REPORTERS_AVAILABLE = i18n.translate( + 'xpack.securitySolution.case.caseView.noReportersAvailable', + { + defaultMessage: 'No reporters available.', + } +); + +export const COMMENTS = i18n.translate('xpack.securitySolution.case.allCases.comments', { + defaultMessage: 'Comments', +}); + +export const TAGS_HELP = i18n.translate( + 'xpack.securitySolution.case.createCase.fieldTagsHelpText', + { + defaultMessage: + 'Type one or more custom identifying tags for this case. Press enter after each tag to begin a new one.', + } +); + +export const NO_TAGS = i18n.translate('xpack.securitySolution.case.caseView.noTags', { + defaultMessage: 'No tags are currently assigned to this case.', +}); + +export const TITLE_REQUIRED = i18n.translate( + 'xpack.securitySolution.case.createCase.titleFieldRequiredError', + { + defaultMessage: 'A title is required.', + } +); + +export const CONFIGURE_CASES_PAGE_TITLE = i18n.translate( + 'xpack.securitySolution.case.configureCases.headerTitle', + { + defaultMessage: 'Configure cases', + } +); + +export const CONFIGURE_CASES_BUTTON = i18n.translate( + 'xpack.securitySolution.case.configureCasesButton', + { + defaultMessage: 'Edit external connection', + } +); + +export const ADD_COMMENT = i18n.translate( + 'xpack.securitySolution.case.caseView.comment.addComment', + { + defaultMessage: 'Add comment', + } +); + +export const ADD_COMMENT_HELP_TEXT = i18n.translate( + 'xpack.securitySolution.case.caseView.comment.addCommentHelpText', + { + defaultMessage: 'Add a new comment...', + } +); + +export const SAVE = i18n.translate('xpack.securitySolution.case.caseView.description.save', { + defaultMessage: 'Save', +}); + +export const GO_TO_DOCUMENTATION = i18n.translate( + 'xpack.securitySolution.case.caseView.goToDocumentationButton', + { + defaultMessage: 'View documentation', + } +); + +export const CONNECTORS = i18n.translate('xpack.securitySolution.case.caseView.connectors', { + defaultMessage: 'External incident management system', +}); + +export const EDIT_CONNECTOR = i18n.translate('xpack.securitySolution.case.caseView.editConnector', { + defaultMessage: 'Change external incident management system', +}); diff --git a/x-pack/plugins/siem/public/cases/pages/utils.ts b/x-pack/plugins/security_solution/public/cases/pages/utils.ts similarity index 100% rename from x-pack/plugins/siem/public/cases/pages/utils.ts rename to x-pack/plugins/security_solution/public/cases/pages/utils.ts diff --git a/x-pack/plugins/siem/public/cases/routes.tsx b/x-pack/plugins/security_solution/public/cases/routes.tsx similarity index 100% rename from x-pack/plugins/siem/public/cases/routes.tsx rename to x-pack/plugins/security_solution/public/cases/routes.tsx diff --git a/x-pack/plugins/security_solution/public/cases/translations.ts b/x-pack/plugins/security_solution/public/cases/translations.ts new file mode 100644 index 0000000000000..5b595c5892ef2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/cases/translations.ts @@ -0,0 +1,232 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const SAVED_OBJECT_NO_PERMISSIONS_TITLE = i18n.translate( + 'xpack.securitySolution.case.caseSavedObjectNoPermissionsTitle', + { + defaultMessage: 'Kibana feature privileges required', + } +); + +export const SAVED_OBJECT_NO_PERMISSIONS_MSG = i18n.translate( + 'xpack.securitySolution.case.caseSavedObjectNoPermissionsMessage', + { + defaultMessage: + 'To view cases, you must have privileges for the Saved Object Management feature in the Kibana space. For more information, contact your Kibana administrator.', + } +); + +export const BACK_TO_ALL = i18n.translate('xpack.securitySolution.case.caseView.backLabel', { + defaultMessage: 'Back to cases', +}); + +export const CANCEL = i18n.translate('xpack.securitySolution.case.caseView.cancel', { + defaultMessage: 'Cancel', +}); + +export const DELETE_CASE = i18n.translate( + 'xpack.securitySolution.case.confirmDeleteCase.deleteCase', + { + defaultMessage: 'Delete case', + } +); + +export const DELETE_CASES = i18n.translate( + 'xpack.securitySolution.case.confirmDeleteCase.deleteCases', + { + defaultMessage: 'Delete cases', + } +); + +export const NAME = i18n.translate('xpack.securitySolution.case.caseView.name', { + defaultMessage: 'Name', +}); + +export const OPENED_ON = i18n.translate('xpack.securitySolution.case.caseView.openedOn', { + defaultMessage: 'Opened on', +}); + +export const CLOSED_ON = i18n.translate('xpack.securitySolution.case.caseView.closedOn', { + defaultMessage: 'Closed on', +}); + +export const REPORTER = i18n.translate('xpack.securitySolution.case.caseView.reporterLabel', { + defaultMessage: 'Reporter', +}); + +export const PARTICIPANTS = i18n.translate( + 'xpack.securitySolution.case.caseView.particpantsLabel', + { + defaultMessage: 'Participants', + } +); + +export const CREATE_BC_TITLE = i18n.translate('xpack.securitySolution.case.caseView.breadcrumb', { + defaultMessage: 'Create', +}); + +export const CREATE_TITLE = i18n.translate('xpack.securitySolution.case.caseView.create', { + defaultMessage: 'Create new case', +}); + +export const DESCRIPTION = i18n.translate('xpack.securitySolution.case.caseView.description', { + defaultMessage: 'Description', +}); + +export const DESCRIPTION_REQUIRED = i18n.translate( + 'xpack.securitySolution.case.createCase.descriptionFieldRequiredError', + { + defaultMessage: 'A description is required.', + } +); + +export const COMMENT_REQUIRED = i18n.translate( + 'xpack.securitySolution.case.caseView.commentFieldRequiredError', + { + defaultMessage: 'A comment is required.', + } +); + +export const REQUIRED_FIELD = i18n.translate( + 'xpack.securitySolution.case.caseView.fieldRequiredError', + { + defaultMessage: 'Required field', + } +); + +export const EDIT = i18n.translate('xpack.securitySolution.case.caseView.edit', { + defaultMessage: 'Edit', +}); + +export const OPTIONAL = i18n.translate('xpack.securitySolution.case.caseView.optional', { + defaultMessage: 'Optional', +}); + +export const PAGE_TITLE = i18n.translate('xpack.securitySolution.case.pageTitle', { + defaultMessage: 'Cases', +}); + +export const CREATE_CASE = i18n.translate('xpack.securitySolution.case.caseView.createCase', { + defaultMessage: 'Create case', +}); + +export const CLOSED_CASE = i18n.translate('xpack.securitySolution.case.caseView.closedCase', { + defaultMessage: 'Closed case', +}); + +export const CLOSE_CASE = i18n.translate('xpack.securitySolution.case.caseView.closeCase', { + defaultMessage: 'Close case', +}); + +export const REOPEN_CASE = i18n.translate('xpack.securitySolution.case.caseView.reopenCase', { + defaultMessage: 'Reopen case', +}); + +export const REOPENED_CASE = i18n.translate('xpack.securitySolution.case.caseView.reopenedCase', { + defaultMessage: 'Reopened case', +}); + +export const CASE_NAME = i18n.translate('xpack.securitySolution.case.caseView.caseName', { + defaultMessage: 'Case name', +}); + +export const TO = i18n.translate('xpack.securitySolution.case.caseView.to', { + defaultMessage: 'to', +}); + +export const TAGS = i18n.translate('xpack.securitySolution.case.caseView.tags', { + defaultMessage: 'Tags', +}); + +export const ACTIONS = i18n.translate('xpack.securitySolution.case.allCases.actions', { + defaultMessage: 'Actions', +}); + +export const NO_TAGS_AVAILABLE = i18n.translate( + 'xpack.securitySolution.case.allCases.noTagsAvailable', + { + defaultMessage: 'No tags available', + } +); + +export const NO_REPORTERS_AVAILABLE = i18n.translate( + 'xpack.securitySolution.case.caseView.noReportersAvailable', + { + defaultMessage: 'No reporters available.', + } +); + +export const COMMENTS = i18n.translate('xpack.securitySolution.case.allCases.comments', { + defaultMessage: 'Comments', +}); + +export const TAGS_HELP = i18n.translate( + 'xpack.securitySolution.case.createCase.fieldTagsHelpText', + { + defaultMessage: + 'Type one or more custom identifying tags for this case. Press enter after each tag to begin a new one.', + } +); + +export const NO_TAGS = i18n.translate('xpack.securitySolution.case.caseView.noTags', { + defaultMessage: 'No tags are currently assigned to this case.', +}); + +export const TITLE_REQUIRED = i18n.translate( + 'xpack.securitySolution.case.createCase.titleFieldRequiredError', + { + defaultMessage: 'A title is required.', + } +); + +export const CONFIGURE_CASES_PAGE_TITLE = i18n.translate( + 'xpack.securitySolution.case.configureCases.headerTitle', + { + defaultMessage: 'Configure cases', + } +); + +export const CONFIGURE_CASES_BUTTON = i18n.translate( + 'xpack.securitySolution.case.configureCasesButton', + { + defaultMessage: 'Edit external connection', + } +); + +export const ADD_COMMENT = i18n.translate( + 'xpack.securitySolution.case.caseView.comment.addComment', + { + defaultMessage: 'Add comment', + } +); + +export const ADD_COMMENT_HELP_TEXT = i18n.translate( + 'xpack.securitySolution.case.caseView.comment.addCommentHelpText', + { + defaultMessage: 'Add a new comment...', + } +); + +export const SAVE = i18n.translate('xpack.securitySolution.case.caseView.description.save', { + defaultMessage: 'Save', +}); + +export const GO_TO_DOCUMENTATION = i18n.translate( + 'xpack.securitySolution.case.caseView.goToDocumentationButton', + { + defaultMessage: 'View documentation', + } +); + +export const CONNECTORS = i18n.translate('xpack.securitySolution.case.caseView.connectors', { + defaultMessage: 'External incident management system', +}); + +export const EDIT_CONNECTOR = i18n.translate('xpack.securitySolution.case.caseView.editConnector', { + defaultMessage: 'Change external incident management system', +}); diff --git a/x-pack/plugins/siem/public/common/components/add_filter_to_global_search_bar/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/add_filter_to_global_search_bar/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/add_filter_to_global_search_bar/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/helpers.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/add_filter_to_global_search_bar/helpers.test.tsx rename to x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/helpers.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/add_filter_to_global_search_bar/helpers.ts b/x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/helpers.ts similarity index 100% rename from x-pack/plugins/siem/public/common/components/add_filter_to_global_search_bar/helpers.ts rename to x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/helpers.ts diff --git a/x-pack/plugins/siem/public/common/components/add_filter_to_global_search_bar/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/add_filter_to_global_search_bar/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/index.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/add_filter_to_global_search_bar/index.tsx b/x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/add_filter_to_global_search_bar/index.tsx rename to x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/index.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/translations.ts b/x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/translations.ts new file mode 100644 index 0000000000000..c4f36bd7dd881 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/translations.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const FILTER_FOR_VALUE = i18n.translate( + 'xpack.securitySolution.add_filter_to_global_search_bar.filterForValueHoverAction', + { + defaultMessage: 'Filter for value', + } +); + +export const FILTER_OUT_VALUE = i18n.translate( + 'xpack.securitySolution.add_filter_to_global_search_bar.filterOutValueHoverAction', + { + defaultMessage: 'Filter out value', + } +); diff --git a/x-pack/plugins/siem/public/common/components/alerts_viewer/alerts_table.tsx b/x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx similarity index 97% rename from x-pack/plugins/siem/public/common/components/alerts_viewer/alerts_table.tsx rename to x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx index b19343a9f4a5c..bb6ba01821835 100644 --- a/x-pack/plugins/siem/public/common/components/alerts_viewer/alerts_table.tsx +++ b/x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx @@ -69,6 +69,7 @@ const AlertsTableComponent: React.FC = ({ endDate, startDate, pageFilters title: i18n.ALERTS_TABLE_TITLE, unit: i18n.UNIT, }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( { + const [defaultNumberFormat] = useUiSetting$(DEFAULT_NUMBER_FORMAT); + const getSubtitle = useCallback( + (totalCount: number) => + `${i18n.SHOWING}: ${numeral(totalCount).format(defaultNumberFormat)} ${i18n.UNIT( + totalCount + )}`, + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + const alertsHistogramConfigs: MatrixHisrogramConfigs = useMemo( + () => ({ + ...histogramConfigs, + subtitle: getSubtitle, + }), + [getSubtitle] + ); + useEffect(() => { + return () => { + if (deleteQuery) { + deleteQuery({ id: ID }); + } + }; + }, [deleteQuery]); + + return ( + <> + + + + ); +}; +AlertsView.displayName = 'AlertsView'; diff --git a/x-pack/plugins/security_solution/public/common/components/alerts_viewer/translations.ts b/x-pack/plugins/security_solution/public/common/components/alerts_viewer/translations.ts new file mode 100644 index 0000000000000..8403050a13114 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/alerts_viewer/translations.ts @@ -0,0 +1,67 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const ALERTS_DOCUMENT_TYPE = i18n.translate( + 'xpack.securitySolution.alertsView.alertsDocumentType', + { + defaultMessage: 'External alerts', + } +); + +export const TOTAL_COUNT_OF_ALERTS = i18n.translate( + 'xpack.securitySolution.alertsView.totalCountOfAlerts', + { + defaultMessage: 'external alerts match the search criteria', + } +); + +export const ALERTS_TABLE_TITLE = i18n.translate( + 'xpack.securitySolution.alertsView.alertsTableTitle', + { + defaultMessage: 'External alerts', + } +); + +export const ALERTS_GRAPH_TITLE = i18n.translate( + 'xpack.securitySolution.alertsView.alertsGraphTitle', + { + defaultMessage: 'External alert count', + } +); + +export const ALERTS_STACK_BY_MODULE = i18n.translate( + 'xpack.securitySolution.alertsView.alertsStackByOptions.module', + { + defaultMessage: 'module', + } +); + +export const SHOWING = i18n.translate('xpack.securitySolution.alertsView.showing', { + defaultMessage: 'Showing', +}); + +export const UNIT = (totalCount: number) => + i18n.translate('xpack.securitySolution.alertsView.unit', { + values: { totalCount }, + defaultMessage: `external {totalCount, plural, =1 {alert} other {alerts}}`, + }); + +export const ERROR_FETCHING_ALERTS_DATA = i18n.translate( + 'xpack.securitySolution.alertsView.errorFetchingAlertsData', + { + defaultMessage: 'Failed to query alerts data', + } +); + +export const CATEGORY = i18n.translate('xpack.securitySolution.alertsView.categoryLabel', { + defaultMessage: 'category', +}); + +export const MODULE = i18n.translate('xpack.securitySolution.alertsView.moduleLabel', { + defaultMessage: 'module', +}); diff --git a/x-pack/plugins/siem/public/common/components/alerts_viewer/types.ts b/x-pack/plugins/security_solution/public/common/components/alerts_viewer/types.ts similarity index 100% rename from x-pack/plugins/siem/public/common/components/alerts_viewer/types.ts rename to x-pack/plugins/security_solution/public/common/components/alerts_viewer/types.ts diff --git a/x-pack/plugins/security_solution/public/common/components/and_or_badge/__examples__/index.stories.tsx b/x-pack/plugins/security_solution/public/common/components/and_or_badge/__examples__/index.stories.tsx new file mode 100644 index 0000000000000..f939cf81d1bd3 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/and_or_badge/__examples__/index.stories.tsx @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { storiesOf } from '@storybook/react'; +import React from 'react'; +import { ThemeProvider } from 'styled-components'; +import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; +import { EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; + +import { AndOrBadge } from '..'; + +const sampleText = + 'Doggo ipsum i am bekom fat snoot wow such tempt waggy wags floofs, ruff heckin good boys and girls mlem. Ruff heckin good boys and girls mlem stop it fren borkf borking doggo very hand that feed shibe, you are doing me the shock big ol heck smol borking doggo with a long snoot for pats heckin good boys. You are doing me the shock smol borking doggo with a long snoot for pats wow very biscit, length boy. Doggo ipsum i am bekom fat snoot wow such tempt waggy wags floofs, ruff heckin good boys and girls mlem. Ruff heckin good boys and girls mlem stop it fren borkf borking doggo very hand that feed shibe, you are doing me the shock big ol heck smol borking doggo with a long snoot for pats heckin good boys.'; + +storiesOf('components/AndOrBadge', module) + .add('and', () => ( + ({ eui: euiLightVars, darkMode: true })}> + + + )) + .add('or', () => ( + ({ eui: euiLightVars, darkMode: true })}> + + + )) + .add('antennas', () => ( + ({ eui: euiLightVars, darkMode: true })}> + + + + + +

{sampleText}

+
+
+
+ )); diff --git a/x-pack/plugins/security_solution/public/common/components/and_or_badge/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/and_or_badge/index.test.tsx new file mode 100644 index 0000000000000..ed918a59a514a --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/and_or_badge/index.test.tsx @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { ThemeProvider } from 'styled-components'; +import { mount } from 'enzyme'; +import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; + +import { AndOrBadge } from './'; + +describe('AndOrBadge', () => { + test('it renders top and bottom antenna bars when "includeAntennas" is true', () => { + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('[data-test-subj="and-or-badge"]').at(0).text()).toEqual('AND'); + expect(wrapper.find('EuiFlexItem[data-test-subj="andOrBadgeBarTop"]')).toHaveLength(1); + expect(wrapper.find('EuiFlexItem[data-test-subj="andOrBadgeBarBottom"]')).toHaveLength(1); + }); + + test('it renders "and" when "type" is "and"', () => { + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('[data-test-subj="and-or-badge"]').at(0).text()).toEqual('AND'); + expect(wrapper.find('EuiFlexItem[data-test-subj="and-or-badge-bar"]')).toHaveLength(0); + }); + + test('it renders "or" when "type" is "or"', () => { + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('[data-test-subj="and-or-badge"]').at(0).text()).toEqual('OR'); + expect(wrapper.find('EuiFlexItem[data-test-subj="and-or-badge-bar"]')).toHaveLength(0); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/and_or_badge/index.tsx b/x-pack/plugins/security_solution/public/common/components/and_or_badge/index.tsx new file mode 100644 index 0000000000000..ba3f880d9757e --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/and_or_badge/index.tsx @@ -0,0 +1,108 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiFlexGroup, EuiBadge, EuiFlexItem } from '@elastic/eui'; +import React from 'react'; +import styled, { css } from 'styled-components'; + +import * as i18n from './translations'; + +const AndOrBadgeAntenna = styled(EuiFlexItem)` + ${({ theme }) => css` + background: ${theme.eui.euiColorLightShade}; + position: relative; + width: 2px; + &:after { + background: ${theme.eui.euiColorLightShade}; + content: ''; + height: 8px; + right: -4px; + position: absolute; + width: 9px; + clip-path: circle(); + } + &.topAndOrBadgeAntenna { + &:after { + top: -1px; + } + } + &.bottomAndOrBadgeAntenna { + &:after { + bottom: -1px; + } + } + &.euiFlexItem { + margin: 0 12px 0 0; + } + `} +`; + +const EuiFlexItemWrapper = styled(EuiFlexItem)` + &.euiFlexItem { + margin: 0 12px 0 0; + } +`; + +const RoundedBadge = (styled(EuiBadge)` + align-items: center; + border-radius: 100%; + display: inline-flex; + font-size: 9px; + height: 34px; + justify-content: center; + margin: 0 5px 0 5px; + padding: 7px 6px 4px 6px; + user-select: none; + width: 34px; + .euiBadge__content { + position: relative; + top: -1px; + } + .euiBadge__text { + text-overflow: clip; + } +` as unknown) as typeof EuiBadge; + +RoundedBadge.displayName = 'RoundedBadge'; + +export type AndOr = 'and' | 'or'; + +/** Displays AND / OR in a round badge */ +// Ref: https://github.com/elastic/eui/issues/1655 +export const AndOrBadge = React.memo<{ type: AndOr; includeAntennas?: boolean }>( + ({ type, includeAntennas = false }) => { + const getBadge = () => ( + + {type === 'and' ? i18n.AND : i18n.OR} + + ); + + const getBadgeWithAntennas = () => ( + + + {getBadge()} + + + ); + + return includeAntennas ? getBadgeWithAntennas() : getBadge(); + } +); + +AndOrBadge.displayName = 'AndOrBadge'; diff --git a/x-pack/plugins/security_solution/public/common/components/and_or_badge/translations.ts b/x-pack/plugins/security_solution/public/common/components/and_or_badge/translations.ts new file mode 100644 index 0000000000000..390652738363f --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/and_or_badge/translations.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const AND = i18n.translate('xpack.securitySolution.andOrBadge.and', { + defaultMessage: 'AND', +}); + +export const OR = i18n.translate('xpack.securitySolution.andOrBadge.or', { + defaultMessage: 'OR', +}); diff --git a/x-pack/plugins/siem/public/common/components/autocomplete_field/__examples__/index.stories.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete_field/__examples__/index.stories.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/autocomplete_field/__examples__/index.stories.tsx rename to x-pack/plugins/security_solution/public/common/components/autocomplete_field/__examples__/index.stories.tsx diff --git a/x-pack/plugins/siem/public/common/components/autocomplete_field/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/autocomplete_field/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/autocomplete_field/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/autocomplete_field/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/autocomplete_field/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete_field/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/autocomplete_field/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/autocomplete_field/index.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/autocomplete_field/index.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete_field/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/autocomplete_field/index.tsx rename to x-pack/plugins/security_solution/public/common/components/autocomplete_field/index.tsx diff --git a/x-pack/plugins/siem/public/common/components/autocomplete_field/suggestion_item.tsx b/x-pack/plugins/security_solution/public/common/components/autocomplete_field/suggestion_item.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/autocomplete_field/suggestion_item.tsx rename to x-pack/plugins/security_solution/public/common/components/autocomplete_field/suggestion_item.tsx diff --git a/x-pack/plugins/siem/public/common/components/charts/__snapshots__/areachart.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/charts/__snapshots__/areachart.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/charts/__snapshots__/areachart.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/charts/__snapshots__/areachart.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/charts/__snapshots__/barchart.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/charts/__snapshots__/barchart.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/charts/__snapshots__/barchart.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/charts/__snapshots__/barchart.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/charts/areachart.test.tsx b/x-pack/plugins/security_solution/public/common/components/charts/areachart.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/charts/areachart.test.tsx rename to x-pack/plugins/security_solution/public/common/components/charts/areachart.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/charts/areachart.tsx b/x-pack/plugins/security_solution/public/common/components/charts/areachart.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/charts/areachart.tsx rename to x-pack/plugins/security_solution/public/common/components/charts/areachart.tsx diff --git a/x-pack/plugins/siem/public/common/components/charts/barchart.test.tsx b/x-pack/plugins/security_solution/public/common/components/charts/barchart.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/charts/barchart.test.tsx rename to x-pack/plugins/security_solution/public/common/components/charts/barchart.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/charts/barchart.tsx b/x-pack/plugins/security_solution/public/common/components/charts/barchart.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/charts/barchart.tsx rename to x-pack/plugins/security_solution/public/common/components/charts/barchart.tsx diff --git a/x-pack/plugins/siem/public/common/components/charts/chart_place_holder.test.tsx b/x-pack/plugins/security_solution/public/common/components/charts/chart_place_holder.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/charts/chart_place_holder.test.tsx rename to x-pack/plugins/security_solution/public/common/components/charts/chart_place_holder.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/charts/chart_place_holder.tsx b/x-pack/plugins/security_solution/public/common/components/charts/chart_place_holder.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/charts/chart_place_holder.tsx rename to x-pack/plugins/security_solution/public/common/components/charts/chart_place_holder.tsx diff --git a/x-pack/plugins/siem/public/common/components/charts/common.test.tsx b/x-pack/plugins/security_solution/public/common/components/charts/common.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/charts/common.test.tsx rename to x-pack/plugins/security_solution/public/common/components/charts/common.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/charts/common.tsx b/x-pack/plugins/security_solution/public/common/components/charts/common.tsx similarity index 98% rename from x-pack/plugins/siem/public/common/components/charts/common.tsx rename to x-pack/plugins/security_solution/public/common/components/charts/common.tsx index 4858af4f4f257..155eaba876d45 100644 --- a/x-pack/plugins/siem/public/common/components/charts/common.tsx +++ b/x-pack/plugins/security_solution/public/common/components/charts/common.tsx @@ -101,6 +101,7 @@ const theme: PartialTheme = { export const useTheme = () => { const isDarkMode = useUiSetting(DEFAULT_DARK_MODE); const defaultTheme = isDarkMode ? DARK_THEME : LIGHT_THEME; + // eslint-disable-next-line react-hooks/exhaustive-deps const themeValue = useMemo(() => mergeWithDefaultTheme(theme, defaultTheme), []); return themeValue; diff --git a/x-pack/plugins/siem/public/common/components/charts/draggable_legend.test.tsx b/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/charts/draggable_legend.test.tsx rename to x-pack/plugins/security_solution/public/common/components/charts/draggable_legend.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/charts/draggable_legend.tsx b/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/charts/draggable_legend.tsx rename to x-pack/plugins/security_solution/public/common/components/charts/draggable_legend.tsx diff --git a/x-pack/plugins/siem/public/common/components/charts/draggable_legend_item.test.tsx b/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend_item.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/charts/draggable_legend_item.test.tsx rename to x-pack/plugins/security_solution/public/common/components/charts/draggable_legend_item.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/charts/draggable_legend_item.tsx b/x-pack/plugins/security_solution/public/common/components/charts/draggable_legend_item.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/charts/draggable_legend_item.tsx rename to x-pack/plugins/security_solution/public/common/components/charts/draggable_legend_item.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/charts/translation.ts b/x-pack/plugins/security_solution/public/common/components/charts/translation.ts new file mode 100644 index 0000000000000..68b90af65aefa --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/charts/translation.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const ALL_VALUES_ZEROS_TITLE = i18n.translate( + 'xpack.securitySolution.chart.dataAllValuesZerosTitle', + { + defaultMessage: 'All values returned zero', + } +); + +export const DATA_NOT_AVAILABLE_TITLE = i18n.translate( + 'xpack.securitySolution.chart.dataNotAvailableTitle', + { + defaultMessage: 'Chart Data Not Available', + } +); + +export const ALL_OTHERS = i18n.translate('xpack.securitySolution.chart.allOthersGroupingLabel', { + defaultMessage: 'All others', +}); diff --git a/x-pack/plugins/siem/public/common/components/drag_and_drop/__snapshots__/drag_drop_context_wrapper.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/__snapshots__/drag_drop_context_wrapper.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/drag_and_drop/__snapshots__/drag_drop_context_wrapper.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/drag_and_drop/__snapshots__/drag_drop_context_wrapper.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/drag_and_drop/__snapshots__/draggable_wrapper.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/__snapshots__/draggable_wrapper.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/drag_and_drop/__snapshots__/draggable_wrapper.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/drag_and_drop/__snapshots__/draggable_wrapper.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/drag_and_drop/__snapshots__/droppable_wrapper.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/__snapshots__/droppable_wrapper.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/drag_and_drop/__snapshots__/droppable_wrapper.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/drag_and_drop/__snapshots__/droppable_wrapper.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/drag_and_drop/drag_drop_context.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/drag_drop_context.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/drag_and_drop/drag_drop_context.tsx rename to x-pack/plugins/security_solution/public/common/components/drag_and_drop/drag_drop_context.tsx diff --git a/x-pack/plugins/siem/public/common/components/drag_and_drop/drag_drop_context_wrapper.test.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/drag_drop_context_wrapper.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/drag_and_drop/drag_drop_context_wrapper.test.tsx rename to x-pack/plugins/security_solution/public/common/components/drag_and_drop/drag_drop_context_wrapper.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/drag_and_drop/drag_drop_context_wrapper.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/drag_drop_context_wrapper.tsx similarity index 99% rename from x-pack/plugins/siem/public/common/components/drag_and_drop/drag_drop_context_wrapper.tsx rename to x-pack/plugins/security_solution/public/common/components/drag_and_drop/drag_drop_context_wrapper.tsx index c33677e41db0e..32f05e7c837a7 100644 --- a/x-pack/plugins/siem/public/common/components/drag_and_drop/drag_drop_context_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/drag_drop_context_wrapper.tsx @@ -126,6 +126,7 @@ export const DragDropContextWrapperComponent = React.memo( () => () => { unRegisterProvider(); }, + // eslint-disable-next-line react-hooks/exhaustive-deps [] ); diff --git a/x-pack/plugins/siem/public/common/components/drag_and_drop/draggable_wrapper_hover_content.test.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/drag_and_drop/draggable_wrapper_hover_content.test.tsx rename to x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/drag_and_drop/draggable_wrapper_hover_content.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.tsx similarity index 97% rename from x-pack/plugins/siem/public/common/components/drag_and_drop/draggable_wrapper_hover_content.tsx rename to x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.tsx index 998d18291f638..4eeefdbe2fca0 100644 --- a/x-pack/plugins/siem/public/common/components/drag_and_drop/draggable_wrapper_hover_content.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper_hover_content.tsx @@ -63,6 +63,7 @@ const DraggableWrapperHoverContentComponent: React.FC = ({ onFilterAdded(); } } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [field, value, filterManager, onFilterAdded]); const filterOutValue = useCallback(() => { @@ -77,6 +78,7 @@ const DraggableWrapperHoverContentComponent: React.FC = ({ onFilterAdded(); } } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [field, value, filterManager, onFilterAdded]); return ( diff --git a/x-pack/plugins/siem/public/common/components/drag_and_drop/droppable_wrapper.test.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/drag_and_drop/droppable_wrapper.test.tsx rename to x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/drag_and_drop/droppable_wrapper.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/drag_and_drop/droppable_wrapper.tsx rename to x-pack/plugins/security_solution/public/common/components/drag_and_drop/droppable_wrapper.tsx diff --git a/x-pack/plugins/siem/public/common/components/drag_and_drop/helpers.test.ts b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.test.ts similarity index 99% rename from x-pack/plugins/siem/public/common/components/drag_and_drop/helpers.test.ts rename to x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.test.ts index be58381fbca1b..afdfde6e08224 100644 --- a/x-pack/plugins/siem/public/common/components/drag_and_drop/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.test.ts @@ -960,7 +960,7 @@ describe('helpers', () => { }, ], }, - type: 'x-pack/siem/local/timeline/UPDATE_PROVIDERS', + type: 'x-pack/security_solution/local/timeline/UPDATE_PROVIDERS', }); }); @@ -981,7 +981,7 @@ describe('helpers', () => { payload: { id: 'hosts-table-hostName-ENDPOINT-W-0-01', }, - type: 'x-pack/siem/local/drag_and_drop/NO_PROVIDER_FOUND', + type: 'x-pack/security_solution/local/drag_and_drop/NO_PROVIDER_FOUND', }); }); }); diff --git a/x-pack/plugins/siem/public/common/components/drag_and_drop/helpers.ts b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts similarity index 100% rename from x-pack/plugins/siem/public/common/components/drag_and_drop/helpers.ts rename to x-pack/plugins/security_solution/public/common/components/drag_and_drop/helpers.ts diff --git a/x-pack/plugins/siem/public/common/components/drag_and_drop/provider_container.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/provider_container.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/drag_and_drop/provider_container.tsx rename to x-pack/plugins/security_solution/public/common/components/drag_and_drop/provider_container.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/translations.ts b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/translations.ts new file mode 100644 index 0000000000000..574b2c190e1db --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/translations.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const ADD_TO_TIMELINE = i18n.translate('xpack.securitySolution.dragAndDrop.addToTimeline', { + defaultMessage: 'Add to timeline investigation', +}); + +export const COPY_TO_CLIPBOARD = i18n.translate( + 'xpack.securitySolution.dragAndDrop.copyToClipboardTooltip', + { + defaultMessage: 'Copy to Clipboard', + } +); + +export const FIELD = i18n.translate('xpack.securitySolution.dragAndDrop.fieldLabel', { + defaultMessage: 'Field', +}); + +export const FILTER_FOR_VALUE = i18n.translate( + 'xpack.securitySolution.dragAndDrop.filterForValueHoverAction', + { + defaultMessage: 'Filter for value', + } +); + +export const FILTER_OUT_VALUE = i18n.translate( + 'xpack.securitySolution.dragAndDrop.filterOutValueHoverAction', + { + defaultMessage: 'Filter out value', + } +); + +export const CLOSE = i18n.translate('xpack.securitySolution.dragAndDrop.closeButtonLabel', { + defaultMessage: 'Close', +}); + +export const SHOW_TOP = (fieldName: string) => + i18n.translate('xpack.securitySolution.overview.showTopTooltip', { + values: { fieldName }, + defaultMessage: `Show top {fieldName}`, + }); diff --git a/x-pack/plugins/siem/public/common/components/draggables/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/draggables/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/draggables/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/draggables/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/draggables/field_badge/index.tsx b/x-pack/plugins/security_solution/public/common/components/draggables/field_badge/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/draggables/field_badge/index.tsx rename to x-pack/plugins/security_solution/public/common/components/draggables/field_badge/index.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/draggables/field_badge/translations.ts b/x-pack/plugins/security_solution/public/common/components/draggables/field_badge/translations.ts new file mode 100644 index 0000000000000..8d378c9a05a70 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/draggables/field_badge/translations.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const CATEGORY = i18n.translate('xpack.securitySolution.draggables.field.categoryLabel', { + defaultMessage: 'Category', +}); + +export const COPY_TO_CLIPBOARD = i18n.translate( + 'xpack.securitySolution.eventDetails.copyToClipboardTooltip', + { + defaultMessage: 'Copy to Clipboard', + } +); + +export const FIELD = i18n.translate('xpack.securitySolution.draggables.field.fieldLabel', { + defaultMessage: 'Field', +}); + +export const TYPE = i18n.translate('xpack.securitySolution.draggables.field.typeLabel', { + defaultMessage: 'Type', +}); + +export const VIEW_CATEGORY = i18n.translate( + 'xpack.securitySolution.draggables.field.viewCategoryTooltip', + { + defaultMessage: 'View Category', + } +); diff --git a/x-pack/plugins/siem/public/common/components/draggables/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/draggables/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/draggables/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/draggables/index.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/draggables/index.tsx b/x-pack/plugins/security_solution/public/common/components/draggables/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/draggables/index.tsx rename to x-pack/plugins/security_solution/public/common/components/draggables/index.tsx diff --git a/x-pack/plugins/siem/public/common/components/empty_page/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/empty_page/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/empty_page/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/empty_page/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/empty_page/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/empty_page/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/empty_page/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/empty_page/index.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/empty_page/index.tsx b/x-pack/plugins/security_solution/public/common/components/empty_page/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/empty_page/index.tsx rename to x-pack/plugins/security_solution/public/common/components/empty_page/index.tsx diff --git a/x-pack/plugins/siem/public/common/components/empty_value/__snapshots__/empty_value.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/empty_value/__snapshots__/empty_value.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/empty_value/__snapshots__/empty_value.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/empty_value/__snapshots__/empty_value.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/empty_value/empty_value.test.tsx b/x-pack/plugins/security_solution/public/common/components/empty_value/empty_value.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/empty_value/empty_value.test.tsx rename to x-pack/plugins/security_solution/public/common/components/empty_value/empty_value.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/empty_value/index.tsx b/x-pack/plugins/security_solution/public/common/components/empty_value/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/empty_value/index.tsx rename to x-pack/plugins/security_solution/public/common/components/empty_value/index.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/empty_value/translations.ts b/x-pack/plugins/security_solution/public/common/components/empty_value/translations.ts new file mode 100644 index 0000000000000..afcf21505103d --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/empty_value/translations.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const EMPTY_STRING = i18n.translate( + 'xpack.securitySolution.emptyString.emptyStringDescription', + { + defaultMessage: 'Empty String', + } +); diff --git a/x-pack/plugins/siem/public/common/components/endpoint/__snapshots__/link_to_app.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/endpoint/__snapshots__/link_to_app.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/endpoint/__snapshots__/link_to_app.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/endpoint/__snapshots__/link_to_app.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/endpoint/__snapshots__/page_view.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/endpoint/__snapshots__/page_view.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/endpoint/__snapshots__/page_view.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/endpoint/__snapshots__/page_view.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/endpoint/formatted_date_time.tsx b/x-pack/plugins/security_solution/public/common/components/endpoint/formatted_date_time.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/endpoint/formatted_date_time.tsx rename to x-pack/plugins/security_solution/public/common/components/endpoint/formatted_date_time.tsx diff --git a/x-pack/plugins/siem/public/common/components/endpoint/link_to_app.test.tsx b/x-pack/plugins/security_solution/public/common/components/endpoint/link_to_app.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/endpoint/link_to_app.test.tsx rename to x-pack/plugins/security_solution/public/common/components/endpoint/link_to_app.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/endpoint/link_to_app.tsx b/x-pack/plugins/security_solution/public/common/components/endpoint/link_to_app.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/endpoint/link_to_app.tsx rename to x-pack/plugins/security_solution/public/common/components/endpoint/link_to_app.tsx diff --git a/x-pack/plugins/siem/public/common/components/endpoint/page_view.test.tsx b/x-pack/plugins/security_solution/public/common/components/endpoint/page_view.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/endpoint/page_view.test.tsx rename to x-pack/plugins/security_solution/public/common/components/endpoint/page_view.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/endpoint/page_view.tsx b/x-pack/plugins/security_solution/public/common/components/endpoint/page_view.tsx similarity index 97% rename from x-pack/plugins/siem/public/common/components/endpoint/page_view.tsx rename to x-pack/plugins/security_solution/public/common/components/endpoint/page_view.tsx index 759274e3a4ffa..6fe15310fc88e 100644 --- a/x-pack/plugins/siem/public/common/components/endpoint/page_view.tsx +++ b/x-pack/plugins/security_solution/public/common/components/endpoint/page_view.tsx @@ -149,7 +149,9 @@ export const PageView = memo( )} )} - {tabs && {tabComponents}} + {tabComponents.length > 0 && ( + {tabComponents} + )} {bodyHeader && ( diff --git a/x-pack/plugins/siem/public/common/components/endpoint/route_capture.tsx b/x-pack/plugins/security_solution/public/common/components/endpoint/route_capture.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/endpoint/route_capture.tsx rename to x-pack/plugins/security_solution/public/common/components/endpoint/route_capture.tsx diff --git a/x-pack/plugins/siem/public/common/components/error_toast_dispatcher/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/error_toast_dispatcher/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/error_toast_dispatcher/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/error_toast_dispatcher/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/error_toast_dispatcher/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/error_toast_dispatcher/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/error_toast_dispatcher/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/error_toast_dispatcher/index.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/error_toast_dispatcher/index.tsx b/x-pack/plugins/security_solution/public/common/components/error_toast_dispatcher/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/error_toast_dispatcher/index.tsx rename to x-pack/plugins/security_solution/public/common/components/error_toast_dispatcher/index.tsx diff --git a/x-pack/plugins/siem/public/common/components/event_details/__snapshots__/event_details.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/event_details/__snapshots__/event_details.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/event_details/__snapshots__/event_details.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/event_details/__snapshots__/event_details.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/event_details/__snapshots__/json_view.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/event_details/__snapshots__/json_view.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/event_details/__snapshots__/json_view.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/event_details/__snapshots__/json_view.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/event_details/columns.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/event_details/columns.tsx rename to x-pack/plugins/security_solution/public/common/components/event_details/columns.tsx diff --git a/x-pack/plugins/siem/public/common/components/event_details/event_details.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/event_details/event_details.test.tsx rename to x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/event_details/event_details.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/event_details/event_details.tsx rename to x-pack/plugins/security_solution/public/common/components/event_details/event_details.tsx diff --git a/x-pack/plugins/siem/public/common/components/event_details/event_fields_browser.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/event_details/event_fields_browser.test.tsx rename to x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/event_details/event_fields_browser.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/event_details/event_fields_browser.tsx rename to x-pack/plugins/security_solution/public/common/components/event_details/event_fields_browser.tsx diff --git a/x-pack/plugins/siem/public/common/components/event_details/event_id.ts b/x-pack/plugins/security_solution/public/common/components/event_details/event_id.ts similarity index 100% rename from x-pack/plugins/siem/public/common/components/event_details/event_id.ts rename to x-pack/plugins/security_solution/public/common/components/event_details/event_id.ts diff --git a/x-pack/plugins/siem/public/common/components/event_details/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/helpers.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/event_details/helpers.test.tsx rename to x-pack/plugins/security_solution/public/common/components/event_details/helpers.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/event_details/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/helpers.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/event_details/helpers.tsx rename to x-pack/plugins/security_solution/public/common/components/event_details/helpers.tsx diff --git a/x-pack/plugins/siem/public/common/components/event_details/json_view.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/json_view.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/event_details/json_view.test.tsx rename to x-pack/plugins/security_solution/public/common/components/event_details/json_view.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/event_details/json_view.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/json_view.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/event_details/json_view.tsx rename to x-pack/plugins/security_solution/public/common/components/event_details/json_view.tsx diff --git a/x-pack/plugins/siem/public/common/components/event_details/stateful_event_details.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/stateful_event_details.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/event_details/stateful_event_details.tsx rename to x-pack/plugins/security_solution/public/common/components/event_details/stateful_event_details.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/translations.ts b/x-pack/plugins/security_solution/public/common/components/event_details/translations.ts new file mode 100644 index 0000000000000..19e71e0f37da6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/event_details/translations.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const TABLE = i18n.translate('xpack.securitySolution.eventDetails.table', { + defaultMessage: 'Table', +}); + +export const JSON_VIEW = i18n.translate('xpack.securitySolution.eventDetails.jsonView', { + defaultMessage: 'JSON View', +}); + +export const FIELD = i18n.translate('xpack.securitySolution.eventDetails.field', { + defaultMessage: 'Field', +}); + +export const VALUE = i18n.translate('xpack.securitySolution.eventDetails.value', { + defaultMessage: 'Value', +}); + +export const DESCRIPTION = i18n.translate('xpack.securitySolution.eventDetails.description', { + defaultMessage: 'Description', +}); + +export const BLANK = i18n.translate('xpack.securitySolution.eventDetails.blank', { + defaultMessage: ' ', +}); + +export const PLACEHOLDER = i18n.translate( + 'xpack.securitySolution.eventDetails.filter.placeholder', + { + defaultMessage: 'Filter by Field, Value, or Description...', + } +); + +export const COPY_TO_CLIPBOARD = i18n.translate( + 'xpack.securitySolution.eventDetails.copyToClipboard', + { + defaultMessage: 'Copy to Clipboard', + } +); + +export const TOGGLE_COLUMN_TOOLTIP = i18n.translate( + 'xpack.securitySolution.eventDetails.toggleColumnTooltip', + { + defaultMessage: 'Toggle column', + } +); diff --git a/x-pack/plugins/siem/public/common/components/event_details/types.ts b/x-pack/plugins/security_solution/public/common/components/event_details/types.ts similarity index 100% rename from x-pack/plugins/siem/public/common/components/event_details/types.ts rename to x-pack/plugins/security_solution/public/common/components/event_details/types.ts diff --git a/x-pack/plugins/siem/public/common/components/events_viewer/default_headers.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/default_headers.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/events_viewer/default_headers.tsx rename to x-pack/plugins/security_solution/public/common/components/events_viewer/default_headers.tsx diff --git a/x-pack/plugins/siem/public/common/components/events_viewer/default_model.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/default_model.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/events_viewer/default_model.tsx rename to x-pack/plugins/security_solution/public/common/components/events_viewer/default_model.tsx diff --git a/x-pack/plugins/siem/public/common/components/events_viewer/event_details_width_context.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/event_details_width_context.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/events_viewer/event_details_width_context.tsx rename to x-pack/plugins/security_solution/public/common/components/events_viewer/event_details_width_context.tsx diff --git a/x-pack/plugins/siem/public/common/components/events_viewer/events_viewer.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/events_viewer/events_viewer.test.tsx rename to x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/events_viewer/events_viewer.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx similarity index 98% rename from x-pack/plugins/siem/public/common/components/events_viewer/events_viewer.tsx rename to x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx index d0bd87188e541..6b4baac0ff26c 100644 --- a/x-pack/plugins/siem/public/common/components/events_viewer/events_viewer.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx @@ -103,9 +103,11 @@ const EventsViewerComponent: React.FC = ({ } = useManageTimeline(); useEffect(() => { setIsTimelineLoading({ id, isLoading: isQueryLoading }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [isQueryLoading]); useEffect(() => { setTimelineFilterManager({ id, filterManager }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [filterManager]); const { queryFields, title, unit } = useMemo(() => getManageTimelineById(id), [ diff --git a/x-pack/plugins/siem/public/common/components/events_viewer/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/events_viewer/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx new file mode 100644 index 0000000000000..9f1d71108e2f1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx @@ -0,0 +1,210 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback, useMemo, useEffect } from 'react'; +import { connect, ConnectedProps } from 'react-redux'; +import deepEqual from 'fast-deep-equal'; + +import { DEFAULT_INDEX_KEY } from '../../../../common/constants'; +import { inputsModel, inputsSelectors, State } from '../../store'; +import { inputsActions } from '../../store/actions'; +import { timelineSelectors, timelineActions } from '../../../timelines/store/timeline'; +import { + ColumnHeaderOptions, + SubsetTimelineModel, + TimelineModel, +} from '../../../timelines/store/timeline/model'; +import { OnChangeItemsPerPage } from '../../../timelines/components/timeline/events'; +import { Filter } from '../../../../../../../src/plugins/data/public'; +import { useUiSetting } from '../../lib/kibana'; +import { EventsViewer } from './events_viewer'; +import { useFetchIndexPatterns } from '../../../alerts/containers/detection_engine/rules/fetch_index_patterns'; +import { InspectButtonContainer } from '../inspect'; + +export interface OwnProps { + defaultIndices?: string[]; + defaultModel: SubsetTimelineModel; + end: number; + id: string; + start: number; + headerFilterGroup?: React.ReactNode; + pageFilters?: Filter[]; + utilityBar?: (refetch: inputsModel.Refetch, totalCount: number) => React.ReactNode; +} + +type Props = OwnProps & PropsFromRedux; + +const StatefulEventsViewerComponent: React.FC = ({ + createTimeline, + columns, + dataProviders, + deletedEventIds, + defaultIndices, + deleteEventQuery, + end, + filters, + headerFilterGroup, + id, + isLive, + itemsPerPage, + itemsPerPageOptions, + kqlMode, + pageFilters, + query, + removeColumn, + start, + showCheckboxes, + showRowRenderers, + sort, + updateItemsPerPage, + upsertColumn, + utilityBar, +}) => { + const [{ browserFields, indexPatterns }] = useFetchIndexPatterns( + defaultIndices ?? useUiSetting(DEFAULT_INDEX_KEY) + ); + + useEffect(() => { + if (createTimeline != null) { + createTimeline({ id, columns, sort, itemsPerPage, showCheckboxes, showRowRenderers }); + } + return () => { + deleteEventQuery({ id, inputId: 'global' }); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const onChangeItemsPerPage: OnChangeItemsPerPage = useCallback( + (itemsChangedPerPage) => updateItemsPerPage({ id, itemsPerPage: itemsChangedPerPage }), + [id, updateItemsPerPage] + ); + + const toggleColumn = useCallback( + (column: ColumnHeaderOptions) => { + const exists = columns.findIndex((c) => c.id === column.id) !== -1; + + if (!exists && upsertColumn != null) { + upsertColumn({ + column, + id, + index: 1, + }); + } + + if (exists && removeColumn != null) { + removeColumn({ + columnId: column.id, + id, + }); + } + }, + [columns, id, upsertColumn, removeColumn] + ); + + const globalFilters = useMemo(() => [...filters, ...(pageFilters ?? [])], [filters, pageFilters]); + + return ( + + + + ); +}; + +const makeMapStateToProps = () => { + const getInputsTimeline = inputsSelectors.getTimelineSelector(); + const getGlobalQuerySelector = inputsSelectors.globalQuerySelector(); + const getGlobalFiltersQuerySelector = inputsSelectors.globalFiltersQuerySelector(); + const getEvents = timelineSelectors.getEventsByIdSelector(); + const mapStateToProps = (state: State, { id, defaultModel }: OwnProps) => { + const input: inputsModel.InputsRange = getInputsTimeline(state); + const events: TimelineModel = getEvents(state, id) ?? defaultModel; + const { + columns, + dataProviders, + deletedEventIds, + itemsPerPage, + itemsPerPageOptions, + kqlMode, + sort, + showCheckboxes, + showRowRenderers, + } = events; + + return { + columns, + dataProviders, + deletedEventIds, + filters: getGlobalFiltersQuerySelector(state), + id, + isLive: input.policy.kind === 'interval', + itemsPerPage, + itemsPerPageOptions, + kqlMode, + query: getGlobalQuerySelector(state), + sort, + showCheckboxes, + showRowRenderers, + }; + }; + return mapStateToProps; +}; + +const mapDispatchToProps = { + createTimeline: timelineActions.createTimeline, + deleteEventQuery: inputsActions.deleteOneQuery, + updateItemsPerPage: timelineActions.updateItemsPerPage, + removeColumn: timelineActions.removeColumn, + upsertColumn: timelineActions.upsertColumn, +}; + +const connector = connect(makeMapStateToProps, mapDispatchToProps); + +type PropsFromRedux = ConnectedProps; + +export const StatefulEventsViewer = connector( + React.memo( + StatefulEventsViewerComponent, + (prevProps, nextProps) => + prevProps.id === nextProps.id && + deepEqual(prevProps.columns, nextProps.columns) && + deepEqual(prevProps.dataProviders, nextProps.dataProviders) && + prevProps.deletedEventIds === nextProps.deletedEventIds && + prevProps.end === nextProps.end && + deepEqual(prevProps.filters, nextProps.filters) && + prevProps.isLive === nextProps.isLive && + prevProps.itemsPerPage === nextProps.itemsPerPage && + deepEqual(prevProps.itemsPerPageOptions, nextProps.itemsPerPageOptions) && + prevProps.kqlMode === nextProps.kqlMode && + deepEqual(prevProps.query, nextProps.query) && + deepEqual(prevProps.sort, nextProps.sort) && + prevProps.start === nextProps.start && + deepEqual(prevProps.pageFilters, nextProps.pageFilters) && + prevProps.showCheckboxes === nextProps.showCheckboxes && + prevProps.showRowRenderers === nextProps.showRowRenderers && + prevProps.start === nextProps.start && + prevProps.utilityBar === nextProps.utilityBar + ) +); diff --git a/x-pack/plugins/siem/public/common/components/events_viewer/mock.ts b/x-pack/plugins/security_solution/public/common/components/events_viewer/mock.ts similarity index 100% rename from x-pack/plugins/siem/public/common/components/events_viewer/mock.ts rename to x-pack/plugins/security_solution/public/common/components/events_viewer/mock.ts diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/translations.ts b/x-pack/plugins/security_solution/public/common/components/events_viewer/translations.ts new file mode 100644 index 0000000000000..9e553b8ca9d4f --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/translations.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const SHOWING = i18n.translate('xpack.securitySolution.eventsViewer.showingLabel', { + defaultMessage: 'Showing', +}); + +export const ERROR_FETCHING_EVENTS_DATA = i18n.translate( + 'xpack.securitySolution.eventsViewer.errorFetchingEventsData', + { + defaultMessage: 'Failed to query events data', + } +); + +export const EVENTS = i18n.translate('xpack.securitySolution.eventsViewer.eventsLabel', { + defaultMessage: 'Events', +}); + +export const LOADING_EVENTS = i18n.translate( + 'xpack.securitySolution.eventsViewer.footer.loadingEventsDataLabel', + { + defaultMessage: 'Loading Events', + } +); + +export const UNIT = (totalCount: number) => + i18n.translate('xpack.securitySolution.eventsViewer.unit', { + values: { totalCount }, + defaultMessage: `{totalCount, plural, =1 {event} other {events}}`, + }); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/__examples__/index.stories.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/__examples__/index.stories.tsx new file mode 100644 index 0000000000000..b6620ed103bc8 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/__examples__/index.stories.tsx @@ -0,0 +1,118 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { storiesOf } from '@storybook/react'; +import React from 'react'; +import { ThemeProvider } from 'styled-components'; +import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; + +import { ExceptionItem } from '../viewer'; +import { Operator } from '../types'; +import { getExceptionItemMock } from '../mocks'; + +storiesOf('components/exceptions', module) + .add('ExceptionItem/with os', () => { + const payload = getExceptionItemMock(); + payload.description = ''; + payload.comments = []; + payload.entries = [ + { + field: 'actingProcess.file.signer', + type: 'match', + operator: Operator.INCLUSION, + value: 'Elastic, N.V.', + }, + ]; + + return ( + ({ eui: euiLightVars, darkMode: false })}> + {}} + handleEdit={() => {}} + /> + + ); + }) + .add('ExceptionItem/with description', () => { + const payload = getExceptionItemMock(); + payload._tags = []; + payload.comments = []; + payload.entries = [ + { + field: 'actingProcess.file.signer', + type: 'match', + operator: Operator.INCLUSION, + value: 'Elastic, N.V.', + }, + ]; + + return ( + ({ eui: euiLightVars, darkMode: false })}> + {}} + handleEdit={() => {}} + /> + + ); + }) + .add('ExceptionItem/with comments', () => { + const payload = getExceptionItemMock(); + payload._tags = []; + payload.description = ''; + payload.entries = [ + { + field: 'actingProcess.file.signer', + type: 'match', + operator: Operator.INCLUSION, + value: 'Elastic, N.V.', + }, + ]; + + return ( + ({ eui: euiLightVars, darkMode: false })}> + {}} + handleEdit={() => {}} + /> + + ); + }) + .add('ExceptionItem/with nested entries', () => { + const payload = getExceptionItemMock(); + payload._tags = []; + payload.description = ''; + payload.comments = []; + + return ( + ({ eui: euiLightVars, darkMode: false })}> + {}} + handleEdit={() => {}} + /> + + ); + }) + .add('ExceptionItem/with everything', () => { + const payload = getExceptionItemMock(); + + return ( + ({ eui: euiLightVars, darkMode: false })}> + {}} + handleEdit={() => {}} + /> + + ); + }); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx new file mode 100644 index 0000000000000..223eabb0ea4ee --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx @@ -0,0 +1,467 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React from 'react'; +import { mount } from 'enzyme'; +import moment from 'moment-timezone'; + +import { + getOperatorType, + getExceptionOperatorSelect, + determineIfIsNested, + getFormattedEntries, + formatEntry, + getOperatingSystems, + getTagsInclude, + getDescriptionListContent, + getFormattedComments, +} from './helpers'; +import { + OperatorType, + Operator, + NestedExceptionEntry, + FormattedEntry, + DescriptionListItem, +} from './types'; +import { + isOperator, + isNotOperator, + isOneOfOperator, + isNotOneOfOperator, + isInListOperator, + isNotInListOperator, + existsOperator, + doesNotExistOperator, +} from './operators'; +import { getExceptionItemEntryMock, getExceptionItemMock } from './mocks'; + +describe('Exception helpers', () => { + beforeEach(() => { + moment.tz.setDefault('UTC'); + }); + + afterEach(() => { + moment.tz.setDefault('Browser'); + }); + + describe('#getOperatorType', () => { + test('returns operator type "match" if entry.type is "match"', () => { + const payload = getExceptionItemEntryMock(); + payload.type = 'match'; + const operatorType = getOperatorType(payload); + + expect(operatorType).toEqual(OperatorType.PHRASE); + }); + + test('returns operator type "match" if entry.type is "nested"', () => { + const payload = getExceptionItemEntryMock(); + payload.type = 'nested'; + const operatorType = getOperatorType(payload); + + expect(operatorType).toEqual(OperatorType.PHRASE); + }); + + test('returns operator type "match_any" if entry.type is "match_any"', () => { + const payload = getExceptionItemEntryMock(); + payload.type = 'match_any'; + const operatorType = getOperatorType(payload); + + expect(operatorType).toEqual(OperatorType.PHRASES); + }); + + test('returns operator type "list" if entry.type is "list"', () => { + const payload = getExceptionItemEntryMock(); + payload.type = 'list'; + const operatorType = getOperatorType(payload); + + expect(operatorType).toEqual(OperatorType.LIST); + }); + + test('returns operator type "exists" if entry.type is "exists"', () => { + const payload = getExceptionItemEntryMock(); + payload.type = 'exists'; + const operatorType = getOperatorType(payload); + + expect(operatorType).toEqual(OperatorType.EXISTS); + }); + }); + + describe('#getExceptionOperatorSelect', () => { + test('it returns "isOperator" when "operator" is "included" and operator type is "match"', () => { + const payload = getExceptionItemEntryMock(); + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(isOperator); + }); + + test('it returns "isNotOperator" when "operator" is "excluded" and operator type is "match"', () => { + const payload = getExceptionItemEntryMock(); + payload.operator = Operator.EXCLUSION; + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(isNotOperator); + }); + + test('it returns "isOneOfOperator" when "operator" is "included" and operator type is "match_any"', () => { + const payload = getExceptionItemEntryMock(); + payload.type = 'match_any'; + payload.operator = Operator.INCLUSION; + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(isOneOfOperator); + }); + + test('it returns "isNotOneOfOperator" when "operator" is "excluded" and operator type is "match_any"', () => { + const payload = getExceptionItemEntryMock(); + payload.type = 'match_any'; + payload.operator = Operator.EXCLUSION; + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(isNotOneOfOperator); + }); + + test('it returns "existsOperator" when "operator" is "included" and no operator type is provided', () => { + const payload = getExceptionItemEntryMock(); + payload.type = 'exists'; + payload.operator = Operator.INCLUSION; + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(existsOperator); + }); + + test('it returns "doesNotExistsOperator" when "operator" is "excluded" and no operator type is provided', () => { + const payload = getExceptionItemEntryMock(); + payload.type = 'exists'; + payload.operator = Operator.EXCLUSION; + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(doesNotExistOperator); + }); + + test('it returns "isInList" when "operator" is "included" and operator type is "list"', () => { + const payload = getExceptionItemEntryMock(); + payload.type = 'list'; + payload.operator = Operator.INCLUSION; + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(isInListOperator); + }); + + test('it returns "isNotInList" when "operator" is "excluded" and operator type is "list"', () => { + const payload = getExceptionItemEntryMock(); + payload.type = 'list'; + payload.operator = Operator.EXCLUSION; + const result = getExceptionOperatorSelect(payload); + + expect(result).toEqual(isNotInListOperator); + }); + }); + + describe('#determineIfIsNested', () => { + test('it returns true if type NestedExceptionEntry', () => { + const payload: NestedExceptionEntry = { + field: 'actingProcess.file.signer', + type: 'nested', + entries: [], + }; + const result = determineIfIsNested(payload); + + expect(result).toBeTruthy(); + }); + + test('it returns false if NOT type NestedExceptionEntry', () => { + const payload = getExceptionItemEntryMock(); + const result = determineIfIsNested(payload); + + expect(result).toBeFalsy(); + }); + }); + + describe('#getFormattedEntries', () => { + test('it returns empty array if no entries passed', () => { + const result = getFormattedEntries([]); + + expect(result).toEqual([]); + }); + + test('it formats nested entries as expected', () => { + const payload = [ + { + field: 'file.signature', + type: 'nested', + entries: [ + { + field: 'signer', + type: 'match', + operator: Operator.INCLUSION, + value: 'Evil', + }, + { + field: 'trusted', + type: 'match', + operator: Operator.INCLUSION, + value: 'true', + }, + ], + }, + ]; + const result = getFormattedEntries(payload); + const expected: FormattedEntry[] = [ + { + fieldName: 'file.signature', + operator: null, + value: null, + isNested: false, + }, + { + fieldName: 'file.signature.signer', + isNested: true, + operator: 'is', + value: 'Evil', + }, + { + fieldName: 'file.signature.trusted', + isNested: true, + operator: 'is', + value: 'true', + }, + ]; + expect(result).toEqual(expected); + }); + + test('it formats non-nested entries as expected', () => { + const payload = [ + { + field: 'actingProcess.file.signer', + type: 'match', + operator: Operator.INCLUSION, + value: 'Elastic, N.V.', + }, + { + field: 'actingProcess.file.signer', + type: 'match', + operator: Operator.EXCLUSION, + value: 'Global Signer', + }, + ]; + const result = getFormattedEntries(payload); + const expected: FormattedEntry[] = [ + { + fieldName: 'actingProcess.file.signer', + isNested: false, + operator: 'is', + value: 'Elastic, N.V.', + }, + { + fieldName: 'actingProcess.file.signer', + isNested: false, + operator: 'is not', + value: 'Global Signer', + }, + ]; + expect(result).toEqual(expected); + }); + + test('it formats a mix of nested and non-nested entries as expected', () => { + const payload = getExceptionItemMock(); + const result = getFormattedEntries(payload.entries); + const expected: FormattedEntry[] = [ + { + fieldName: 'actingProcess.file.signer', + isNested: false, + operator: 'is', + value: 'Elastic, N.V.', + }, + { + fieldName: 'host.name', + isNested: false, + operator: 'is not', + value: 'Global Signer', + }, + { + fieldName: 'file.signature', + isNested: false, + operator: null, + value: null, + }, + { + fieldName: 'file.signature.signer', + isNested: true, + operator: 'is', + value: 'Evil', + }, + { + fieldName: 'file.signature.trusted', + isNested: true, + operator: 'is', + value: 'true', + }, + ]; + expect(result).toEqual(expected); + }); + }); + + describe('#formatEntry', () => { + test('it formats an entry', () => { + const payload = getExceptionItemEntryMock(); + const formattedEntry = formatEntry({ isNested: false, item: payload }); + const expected: FormattedEntry = { + fieldName: 'actingProcess.file.signer', + isNested: false, + operator: 'is', + value: 'Elastic, N.V.', + }; + + expect(formattedEntry).toEqual(expected); + }); + + test('it formats a nested entry', () => { + const payload = getExceptionItemEntryMock(); + const formattedEntry = formatEntry({ isNested: true, parent: 'parent', item: payload }); + const expected: FormattedEntry = { + fieldName: 'parent.actingProcess.file.signer', + isNested: true, + operator: 'is', + value: 'Elastic, N.V.', + }; + + expect(formattedEntry).toEqual(expected); + }); + }); + + describe('#getOperatingSystems', () => { + test('it returns null if no operating system tag specified', () => { + const result = getOperatingSystems(['some tag', 'some other tag']); + + expect(result).toEqual(''); + }); + + test('it returns null if operating system tag malformed', () => { + const result = getOperatingSystems(['some tag', 'jibberos:mac,windows', 'some other tag']); + + expect(result).toEqual(''); + }); + + test('it returns formatted operating systems if space included in os tag', () => { + const result = getOperatingSystems(['some tag', 'os: mac', 'some other tag']); + + expect(result).toEqual('Mac'); + }); + + test('it returns formatted operating systems if multiple os tags specified', () => { + const result = getOperatingSystems(['some tag', 'os: mac', 'some other tag', 'os:windows']); + + expect(result).toEqual('Mac, Windows'); + }); + }); + + describe('#getTagsInclude', () => { + test('it returns a tuple of "false" and "null" if no matches found', () => { + const result = getTagsInclude({ tags: ['some', 'tags', 'here'], regex: /(no match)/ }); + + expect(result).toEqual([false, null]); + }); + + test('it returns a tuple of "true" and matching string if matches found', () => { + const result = getTagsInclude({ tags: ['some', 'tags', 'here'], regex: /(some)/ }); + + expect(result).toEqual([true, 'some']); + }); + }); + + describe('#getDescriptionListContent', () => { + test('it returns formatted description list with os if one is specified', () => { + const payload = getExceptionItemMock(); + payload.description = ''; + const result = getDescriptionListContent(payload); + const expected: DescriptionListItem[] = [ + { + description: 'Windows', + title: 'OS', + }, + { + description: 'April 23rd 2020 @ 00:19:13', + title: 'Date created', + }, + { + description: 'user_name', + title: 'Created by', + }, + ]; + + expect(result).toEqual(expected); + }); + + test('it returns formatted description list with a description if one specified', () => { + const payload = getExceptionItemMock(); + payload._tags = []; + payload.description = 'Im a description'; + const result = getDescriptionListContent(payload); + const expected: DescriptionListItem[] = [ + { + description: 'April 23rd 2020 @ 00:19:13', + title: 'Date created', + }, + { + description: 'user_name', + title: 'Created by', + }, + { + description: 'Im a description', + title: 'Comment', + }, + ]; + + expect(result).toEqual(expected); + }); + + test('it returns just user and date created if no other fields specified', () => { + const payload = getExceptionItemMock(); + payload._tags = []; + payload.description = ''; + const result = getDescriptionListContent(payload); + const expected: DescriptionListItem[] = [ + { + description: 'April 23rd 2020 @ 00:19:13', + title: 'Date created', + }, + { + description: 'user_name', + title: 'Created by', + }, + ]; + + expect(result).toEqual(expected); + }); + }); + + describe('#getFormattedComments', () => { + test('it returns formatted comment object with username and timestamp', () => { + const payload = getExceptionItemMock().comments; + const result = getFormattedComments(payload); + + expect(result[0].username).toEqual('user_name'); + expect(result[0].timestamp).toEqual('on Apr 23rd 2020 @ 00:19:13'); + }); + + test('it returns formatted timeline icon with comment users initial', () => { + const payload = getExceptionItemMock().comments; + const result = getFormattedComments(payload); + + const wrapper = mount(result[0].timelineIcon as React.ReactElement); + + expect(wrapper.text()).toEqual('U'); + }); + + test('it returns comment text', () => { + const payload = getExceptionItemMock().comments; + const result = getFormattedComments(payload); + + const wrapper = mount(result[0].children as React.ReactElement); + + expect(wrapper.text()).toEqual('Comment goes here'); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx new file mode 100644 index 0000000000000..bd22de636bf6c --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx @@ -0,0 +1,192 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { EuiText, EuiCommentProps, EuiAvatar } from '@elastic/eui'; +import { capitalize } from 'lodash'; +import moment from 'moment'; + +import * as i18n from './translations'; +import { + FormattedEntry, + OperatorType, + OperatorOption, + ExceptionEntry, + NestedExceptionEntry, + DescriptionListItem, + Comment, + ExceptionListItemSchema, +} from './types'; +import { EXCEPTION_OPERATORS, isOperator } from './operators'; + +/** + * Returns the operator type, may not need this if using io-ts types + * + * @param entry a single ExceptionItem entry + */ +export const getOperatorType = (entry: ExceptionEntry): OperatorType => { + switch (entry.type) { + case 'nested': + case 'match': + return OperatorType.PHRASE; + case 'match_any': + return OperatorType.PHRASES; + case 'list': + return OperatorType.LIST; + default: + return OperatorType.EXISTS; + } +}; + +/** + * Determines operator selection (is/is not/is one of, etc.) + * Default operator is "is" + * + * @param entry a single ExceptionItem entry + */ +export const getExceptionOperatorSelect = (entry: ExceptionEntry): OperatorOption => { + const operatorType = getOperatorType(entry); + const foundOperator = EXCEPTION_OPERATORS.find((operatorOption) => { + return entry.operator === operatorOption.operator && operatorType === operatorOption.type; + }); + + return foundOperator ?? isOperator; +}; + +export const determineIfIsNested = ( + tbd: ExceptionEntry | NestedExceptionEntry +): tbd is NestedExceptionEntry => { + if (tbd.type === 'nested') { + return true; + } + return false; +}; + +/** + * Formats ExceptionItem entries into simple field, operator, value + * for use in rendering items in table + * + * @param entries an ExceptionItem's entries + */ +export const getFormattedEntries = ( + entries: Array +): FormattedEntry[] => { + const formattedEntries = entries.map((entry) => { + if (determineIfIsNested(entry)) { + const parent = { fieldName: entry.field, operator: null, value: null, isNested: false }; + return entry.entries.reduce( + (acc, nestedEntry) => { + const formattedEntry = formatEntry({ + isNested: true, + parent: entry.field, + item: nestedEntry, + }); + return [...acc, { ...formattedEntry }]; + }, + [parent] + ); + } else { + return formatEntry({ isNested: false, item: entry }); + } + }); + + return formattedEntries.flat(); +}; + +/** + * Helper method for `getFormattedEntries` + */ +export const formatEntry = ({ + isNested, + parent, + item, +}: { + isNested: boolean; + parent?: string; + item: ExceptionEntry; +}): FormattedEntry => { + const operator = getExceptionOperatorSelect(item); + const operatorType = getOperatorType(item); + const value = operatorType === OperatorType.EXISTS ? null : item.value; + + return { + fieldName: isNested ? `${parent}.${item.field}` : item.field, + operator: operator.message, + value, + isNested, + }; +}; + +export const getOperatingSystems = (tags: string[]): string => { + const osMatches = tags + .filter((tag) => tag.startsWith('os:')) + .map((os) => capitalize(os.substring(3).trim())) + .join(', '); + + return osMatches; +}; + +export const getTagsInclude = ({ + tags, + regex, +}: { + tags: string[]; + regex: RegExp; +}): [boolean, string | null] => { + const matches: string[] | null = tags.join(';').match(regex); + const match = matches != null ? matches[1] : null; + return [matches != null, match]; +}; + +/** + * Formats ExceptionItem information for description list component + * + * @param exceptionItem an ExceptionItem + */ +export const getDescriptionListContent = ( + exceptionItem: ExceptionListItemSchema +): DescriptionListItem[] => { + const details = [ + { + title: i18n.OPERATING_SYSTEM, + value: getOperatingSystems(exceptionItem._tags), + }, + { + title: i18n.DATE_CREATED, + value: moment(exceptionItem.created_at).format('MMMM Do YYYY @ HH:mm:ss'), + }, + { + title: i18n.CREATED_BY, + value: exceptionItem.created_by, + }, + { + title: i18n.COMMENT, + value: exceptionItem.description, + }, + ]; + + return details.reduce((acc, { value, title }) => { + if (value != null && value.trim() !== '') { + return [...acc, { title, description: value }]; + } else { + return acc; + } + }, []); +}; + +/** + * Formats ExceptionItem.comments into EuiCommentList format + * + * @param comments ExceptionItem.comments + */ +export const getFormattedComments = (comments: Comment[]): EuiCommentProps[] => + comments.map((comment) => ({ + username: comment.user, + timestamp: moment(comment.timestamp).format('on MMM Do YYYY @ HH:mm:ss'), + event: i18n.COMMENT_EVENT, + timelineIcon: , + children: {comment.comment}, + })); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/mocks.ts b/x-pack/plugins/security_solution/public/common/components/exceptions/mocks.ts new file mode 100644 index 0000000000000..15aec3533b325 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/mocks.ts @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + Operator, + ExceptionListItemSchema, + ExceptionEntry, + NestedExceptionEntry, + FormattedEntry, +} from './types'; + +export const getExceptionItemEntryMock = (): ExceptionEntry => ({ + field: 'actingProcess.file.signer', + type: 'match', + operator: Operator.INCLUSION, + value: 'Elastic, N.V.', +}); + +export const getNestedExceptionItemEntryMock = (): NestedExceptionEntry => ({ + field: 'actingProcess.file.signer', + type: 'nested', + entries: [{ ...getExceptionItemEntryMock() }], +}); + +export const getFormattedEntryMock = (isNested = false): FormattedEntry => ({ + fieldName: 'host.name', + operator: 'is', + value: 'some name', + isNested, +}); + +export const getExceptionItemMock = (): ExceptionListItemSchema => ({ + id: 'uuid_here', + item_id: 'item-id', + created_at: '2020-04-23T00:19:13.289Z', + created_by: 'user_name', + list_id: 'test-exception', + tie_breaker_id: '77fd1909-6786-428a-a671-30229a719c1f', + updated_at: '2020-04-23T00:19:13.289Z', + updated_by: 'user_name', + namespace_type: 'single', + name: '', + description: 'This is a description', + comments: [ + { + user: 'user_name', + timestamp: '2020-04-23T00:19:13.289Z', + comment: 'Comment goes here', + }, + ], + _tags: ['os:windows'], + tags: [], + type: 'simple', + entries: [ + { + field: 'actingProcess.file.signer', + type: 'match', + operator: Operator.INCLUSION, + value: 'Elastic, N.V.', + }, + { + field: 'host.name', + type: 'match', + operator: Operator.EXCLUSION, + value: 'Global Signer', + }, + { + field: 'file.signature', + type: 'nested', + entries: [ + { + field: 'signer', + type: 'match', + operator: Operator.INCLUSION, + value: 'Evil', + }, + { + field: 'trusted', + type: 'match', + operator: Operator.INCLUSION, + value: 'true', + }, + ], + }, + ], +}); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/operators.ts b/x-pack/plugins/security_solution/public/common/components/exceptions/operators.ts new file mode 100644 index 0000000000000..19c726893e682 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/operators.ts @@ -0,0 +1,91 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; +import { OperatorOption, OperatorType, Operator } from './types'; + +export const isOperator: OperatorOption = { + message: i18n.translate('xpack.securitySolution.exceptions.isOperatorLabel', { + defaultMessage: 'is', + }), + value: 'is', + type: OperatorType.PHRASE, + operator: Operator.INCLUSION, +}; + +export const isNotOperator: OperatorOption = { + message: i18n.translate('xpack.securitySolution.exceptions.isNotOperatorLabel', { + defaultMessage: 'is not', + }), + value: 'is_not', + type: OperatorType.PHRASE, + operator: Operator.EXCLUSION, +}; + +export const isOneOfOperator: OperatorOption = { + message: i18n.translate('xpack.securitySolution.exceptions.isOneOfOperatorLabel', { + defaultMessage: 'is one of', + }), + value: 'is_one_of', + type: OperatorType.PHRASES, + operator: Operator.INCLUSION, +}; + +export const isNotOneOfOperator: OperatorOption = { + message: i18n.translate('xpack.securitySolution.exceptions.isNotOneOfOperatorLabel', { + defaultMessage: 'is not one of', + }), + value: 'is_not_one_of', + type: OperatorType.PHRASES, + operator: Operator.EXCLUSION, +}; + +export const existsOperator: OperatorOption = { + message: i18n.translate('xpack.securitySolution.exceptions.existsOperatorLabel', { + defaultMessage: 'exists', + }), + value: 'exists', + type: OperatorType.EXISTS, + operator: Operator.INCLUSION, +}; + +export const doesNotExistOperator: OperatorOption = { + message: i18n.translate('xpack.securitySolution.exceptions.doesNotExistOperatorLabel', { + defaultMessage: 'does not exist', + }), + value: 'does_not_exist', + type: OperatorType.EXISTS, + operator: Operator.EXCLUSION, +}; + +export const isInListOperator: OperatorOption = { + message: i18n.translate('xpack.securitySolution.exceptions.isInListOperatorLabel', { + defaultMessage: 'is in list', + }), + value: 'is_in_list', + type: OperatorType.LIST, + operator: Operator.INCLUSION, +}; + +export const isNotInListOperator: OperatorOption = { + message: i18n.translate('xpack.securitySolution.exceptions.isNotInListOperatorLabel', { + defaultMessage: 'is not in list', + }), + value: 'is_not_in_list', + type: OperatorType.LIST, + operator: Operator.EXCLUSION, +}; + +export const EXCEPTION_OPERATORS: OperatorOption[] = [ + isOperator, + isNotOperator, + isOneOfOperator, + isNotOneOfOperator, + existsOperator, + doesNotExistOperator, + isInListOperator, + isNotInListOperator, +]; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/translations.ts b/x-pack/plugins/security_solution/public/common/components/exceptions/translations.ts new file mode 100644 index 0000000000000..704849430daf9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/translations.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { i18n } from '@kbn/i18n'; + +export const EDIT = i18n.translate('xpack.securitySolution.exceptions.editButtonLabel', { + defaultMessage: 'Edit', +}); + +export const REMOVE = i18n.translate('xpack.securitySolution.exceptions.removeButtonLabel', { + defaultMessage: 'Remove', +}); + +export const COMMENTS_SHOW = (comments: number) => + i18n.translate('xpack.securitySolution.exceptions.showCommentsLabel', { + values: { comments }, + defaultMessage: 'Show ({comments}) {comments, plural, =1 {Comment} other {Comments}}', + }); + +export const COMMENTS_HIDE = (comments: number) => + i18n.translate('xpack.securitySolution.exceptions.hideCommentsLabel', { + values: { comments }, + defaultMessage: 'Hide ({comments}) {comments, plural, =1 {Comment} other {Comments}}', + }); + +export const DATE_CREATED = i18n.translate('xpack.securitySolution.exceptions.dateCreatedLabel', { + defaultMessage: 'Date created', +}); + +export const CREATED_BY = i18n.translate('xpack.securitySolution.exceptions.createdByLabel', { + defaultMessage: 'Created by', +}); + +export const COMMENT = i18n.translate('xpack.securitySolution.exceptions.commentLabel', { + defaultMessage: 'Comment', +}); + +export const COMMENT_EVENT = i18n.translate('xpack.securitySolution.exceptions.commentEventLabel', { + defaultMessage: 'added a comment', +}); + +export const OPERATING_SYSTEM = i18n.translate( + 'xpack.securitySolution.exceptions.operatingSystemLabel', + { + defaultMessage: 'OS', + } +); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/types.ts b/x-pack/plugins/security_solution/public/common/components/exceptions/types.ts new file mode 100644 index 0000000000000..e8393610e459d --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/types.ts @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { ReactNode } from 'react'; + +export interface OperatorOption { + message: string; + value: string; + operator: Operator; + type: OperatorType; +} + +export enum Operator { + INCLUSION = 'included', + EXCLUSION = 'excluded', +} + +export enum OperatorType { + NESTED = 'nested', + PHRASE = 'match', + PHRASES = 'match_any', + EXISTS = 'exists', + LIST = 'list', +} + +export interface FormattedEntry { + fieldName: string; + operator: string | null; + value: string | null; + isNested: boolean; +} + +export interface NestedExceptionEntry { + field: string; + type: string; + entries: ExceptionEntry[]; +} + +export interface ExceptionEntry { + field: string; + type: string; + operator: Operator; + value: string; +} + +export interface DescriptionListItem { + title: NonNullable; + description: NonNullable; +} + +export interface Comment { + user: string; + timestamp: string; + comment: string; +} + +// TODO: Delete once types are updated +export interface ExceptionListItemSchema { + _tags: string[]; + comments: Comment[]; + created_at: string; + created_by: string; + description?: string; + entries: Array; + id: string; + item_id: string; + list_id: string; + meta?: unknown; + name: string; + namespace_type: 'single' | 'agnostic'; + tags: string[]; + tie_breaker_id: string; + type: string; + updated_at: string; + updated_by: string; +} diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_details.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_details.test.tsx new file mode 100644 index 0000000000000..536d005c57b6e --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_details.test.tsx @@ -0,0 +1,226 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { ThemeProvider } from 'styled-components'; +import { mount } from 'enzyme'; +import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; +import moment from 'moment-timezone'; + +import { ExceptionDetails } from './exception_details'; +import { getExceptionItemMock } from '../mocks'; + +describe('ExceptionDetails', () => { + beforeEach(() => { + moment.tz.setDefault('UTC'); + }); + + afterEach(() => { + moment.tz.setDefault('Browser'); + }); + + test('it renders no comments button if no comments exist', () => { + const exceptionItem = getExceptionItemMock(); + exceptionItem.comments = []; + + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('[data-test-subj="exceptionsViewerItemCommentsBtn"]')).toHaveLength(0); + }); + + test('it renders comments button if comments exist', () => { + const exceptionItem = getExceptionItemMock(); + + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect( + wrapper.find('.euiButtonEmpty[data-test-subj="exceptionsViewerItemCommentsBtn"]') + ).toHaveLength(1); + }); + + test('it renders correct number of comments', () => { + const exceptionItem = getExceptionItemMock(); + + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('[data-test-subj="exceptionsViewerItemCommentsBtn"]').at(0).text()).toEqual( + 'Show (1) Comment' + ); + }); + + test('it renders comments plural if more than one', () => { + const exceptionItem = getExceptionItemMock(); + exceptionItem.comments = [ + { + user: 'user_1', + timestamp: '2020-04-23T00:19:13.289Z', + comment: 'Comment goes here', + }, + { + user: 'user_2', + timestamp: '2020-04-23T00:19:13.289Z', + comment: 'Comment goes here', + }, + ]; + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('[data-test-subj="exceptionsViewerItemCommentsBtn"]').at(0).text()).toEqual( + 'Show (2) Comments' + ); + }); + + test('it renders comments show text if "showComments" is false', () => { + const exceptionItem = getExceptionItemMock(); + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('[data-test-subj="exceptionsViewerItemCommentsBtn"]').at(0).text()).toEqual( + 'Show (1) Comment' + ); + }); + + test('it renders comments hide text if "showComments" is true', () => { + const exceptionItem = getExceptionItemMock(); + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('[data-test-subj="exceptionsViewerItemCommentsBtn"]').at(0).text()).toEqual( + 'Hide (1) Comment' + ); + }); + + test('it invokes "onCommentsClick" when comments button clicked', () => { + const mockOnCommentsClick = jest.fn(); + const exceptionItem = getExceptionItemMock(); + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + const commentsBtn = wrapper.find('[data-test-subj="exceptionsViewerItemCommentsBtn"]').at(0); + commentsBtn.simulate('click'); + + expect(mockOnCommentsClick).toHaveBeenCalledTimes(1); + }); + + test('it renders the operating system if one is specified in the exception item', () => { + const exceptionItem = getExceptionItemMock(); + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('EuiDescriptionListTitle').at(0).text()).toEqual('OS'); + expect(wrapper.find('EuiDescriptionListDescription').at(0).text()).toEqual('Windows'); + }); + + test('it renders the exception item creator', () => { + const exceptionItem = getExceptionItemMock(); + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('EuiDescriptionListTitle').at(1).text()).toEqual('Date created'); + expect(wrapper.find('EuiDescriptionListDescription').at(1).text()).toEqual( + 'April 23rd 2020 @ 00:19:13' + ); + }); + + test('it renders the exception item creation timestamp', () => { + const exceptionItem = getExceptionItemMock(); + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('EuiDescriptionListTitle').at(2).text()).toEqual('Created by'); + expect(wrapper.find('EuiDescriptionListDescription').at(2).text()).toEqual('user_name'); + }); + + test('it renders the description if one is included on the exception item', () => { + const exceptionItem = getExceptionItemMock(); + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('EuiDescriptionListTitle').at(3).text()).toEqual('Comment'); + expect(wrapper.find('EuiDescriptionListDescription').at(3).text()).toEqual( + 'This is a description' + ); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_details.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_details.tsx new file mode 100644 index 0000000000000..8745e80a21548 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_details.tsx @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiFlexItem, EuiFlexGroup, EuiDescriptionList, EuiButtonEmpty } from '@elastic/eui'; +import React, { useMemo } from 'react'; +import styled, { css } from 'styled-components'; +import { transparentize } from 'polished'; + +import { ExceptionListItemSchema } from '../types'; +import { getDescriptionListContent } from '../helpers'; +import * as i18n from '../translations'; + +const StyledExceptionDetails = styled(EuiFlexItem)` + ${({ theme }) => css` + background-color: ${transparentize(0.95, theme.eui.euiColorPrimary)}; + padding: ${theme.eui.euiSize}; + + .euiDescriptionList__title.listTitle--width { + width: 40%; + } + + .euiDescriptionList__description.listDescription--width { + width: 60%; + } + `} +`; + +const ExceptionDetailsComponent = ({ + showComments, + onCommentsClick, + exceptionItem, +}: { + showComments: boolean; + exceptionItem: ExceptionListItemSchema; + onCommentsClick: () => void; +}): JSX.Element => { + const descriptionList = useMemo(() => getDescriptionListContent(exceptionItem), [exceptionItem]); + + const commentsSection = useMemo((): JSX.Element => { + const { comments } = exceptionItem; + if (comments.length > 0) { + return ( + + {!showComments + ? i18n.COMMENTS_SHOW(comments.length) + : i18n.COMMENTS_HIDE(comments.length)} + + ); + } else { + return <>; + } + }, [showComments, onCommentsClick, exceptionItem]); + + return ( + + + + + + {commentsSection} + + + ); +}; + +ExceptionDetailsComponent.displayName = 'ExceptionDetailsComponent'; + +export const ExceptionDetails = React.memo(ExceptionDetailsComponent); + +ExceptionDetails.displayName = 'ExceptionDetails'; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_entries.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_entries.test.tsx new file mode 100644 index 0000000000000..e0c62f51d032a --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_entries.test.tsx @@ -0,0 +1,150 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { ThemeProvider } from 'styled-components'; +import { mount } from 'enzyme'; +import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; + +import { ExceptionEntries } from './exception_entries'; +import { getFormattedEntryMock } from '../mocks'; +import { getEmptyValue } from '../../empty_value'; + +describe('ExceptionEntries', () => { + test('it does NOT render the and badge if only one exception item entry exists', () => { + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('[data-test-subj="exceptionsViewerAndBadge"]')).toHaveLength(0); + }); + + test('it renders the and badge if more than one exception item exists', () => { + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('[data-test-subj="exceptionsViewerAndBadge"]')).toHaveLength(1); + }); + + test('it invokes "handlEdit" when edit button clicked', () => { + const mockHandleEdit = jest.fn(); + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + const editBtn = wrapper.find('[data-test-subj="exceptionsViewerEditBtn"] button').at(0); + editBtn.simulate('click'); + + expect(mockHandleEdit).toHaveBeenCalledTimes(1); + }); + + test('it invokes "handleDelete" when delete button clicked', () => { + const mockHandleDelete = jest.fn(); + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + const deleteBtn = wrapper.find('[data-test-subj="exceptionsViewerDeleteBtn"] button').at(0); + deleteBtn.simulate('click'); + + expect(mockHandleDelete).toHaveBeenCalledTimes(1); + }); + + test('it renders nested entry', () => { + const parentEntry = getFormattedEntryMock(); + parentEntry.operator = null; + parentEntry.value = null; + + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + const parentField = wrapper + .find('[data-test-subj="exceptionFieldNameCell"] .euiTableCellContent') + .at(0); + const parentOperator = wrapper + .find('[data-test-subj="exceptionFieldOperatorCell"] .euiTableCellContent') + .at(0); + const parentValue = wrapper + .find('[data-test-subj="exceptionFieldValueCell"] .euiTableCellContent') + .at(0); + + const nestedField = wrapper + .find('[data-test-subj="exceptionFieldNameCell"] .euiTableCellContent') + .at(1); + const nestedOperator = wrapper + .find('[data-test-subj="exceptionFieldOperatorCell"] .euiTableCellContent') + .at(1); + const nestedValue = wrapper + .find('[data-test-subj="exceptionFieldValueCell"] .euiTableCellContent') + .at(1); + + expect(parentField.text()).toEqual('host.name'); + expect(parentOperator.text()).toEqual(getEmptyValue()); + expect(parentValue.text()).toEqual(getEmptyValue()); + + expect(nestedField.exists('.euiToolTipAnchor')).toBeTruthy(); + expect(nestedField.text()).toEqual('host.name'); + expect(nestedOperator.text()).toEqual('is'); + expect(nestedValue.text()).toEqual('some name'); + }); + + test('it renders non-nested entries', () => { + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + const field = wrapper + .find('[data-test-subj="exceptionFieldNameCell"] .euiTableCellContent') + .at(0); + const operator = wrapper + .find('[data-test-subj="exceptionFieldOperatorCell"] .euiTableCellContent') + .at(0); + const value = wrapper + .find('[data-test-subj="exceptionFieldValueCell"] .euiTableCellContent') + .at(0); + + expect(field.exists('.euiToolTipAnchor')).toBeFalsy(); + expect(field.text()).toEqual('host.name'); + expect(operator.text()).toEqual('is'); + expect(value.text()).toEqual('some name'); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_entries.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_entries.tsx new file mode 100644 index 0000000000000..fa21d61b06ebe --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_entries.tsx @@ -0,0 +1,170 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiBasicTable, + EuiIconTip, + EuiFlexItem, + EuiFlexGroup, + EuiButton, + EuiTableFieldDataColumnType, +} from '@elastic/eui'; +import React, { useMemo } from 'react'; +import styled, { css } from 'styled-components'; +import { transparentize } from 'polished'; + +import { AndOrBadge } from '../../and_or_badge'; +import { getEmptyValue } from '../../empty_value'; +import * as i18n from '../translations'; +import { FormattedEntry } from '../types'; + +const EntriesDetails = styled(EuiFlexItem)` + padding: ${({ theme }) => theme.eui.euiSize}; +`; + +const StyledEditButton = styled(EuiButton)` + ${({ theme }) => css` + background-color: ${transparentize(0.9, theme.eui.euiColorPrimary)}; + border: none; + font-weight: ${theme.eui.euiFontWeightSemiBold}; + `} +`; + +const StyledRemoveButton = styled(EuiButton)` + ${({ theme }) => css` + background-color: ${transparentize(0.9, theme.eui.euiColorDanger)}; + border: none; + font-weight: ${theme.eui.euiFontWeightSemiBold}; + `} +`; + +const AndOrBadgeContainer = styled(EuiFlexItem)` + padding-top: ${({ theme }) => theme.eui.euiSizeXL}; +`; + +interface ExceptionEntriesComponentProps { + entries: FormattedEntry[]; + handleDelete: () => void; + handleEdit: () => void; +} + +const ExceptionEntriesComponent = ({ + entries, + handleDelete, + handleEdit, +}: ExceptionEntriesComponentProps): JSX.Element => { + const columns = useMemo( + (): Array> => [ + { + field: 'fieldName', + name: 'Field', + sortable: false, + truncateText: true, + 'data-test-subj': 'exceptionFieldNameCell', + width: '30%', + render: (value: string | null, data: FormattedEntry) => { + if (value != null && data.isNested) { + return ( + <> + + {value} + + ); + } else { + return value ?? getEmptyValue(); + } + }, + }, + { + field: 'operator', + name: 'Operator', + sortable: false, + truncateText: true, + 'data-test-subj': 'exceptionFieldOperatorCell', + width: '20%', + render: (value: string | null) => value ?? getEmptyValue(), + }, + { + field: 'value', + name: 'Value', + sortable: false, + truncateText: true, + 'data-test-subj': 'exceptionFieldValueCell', + width: '60%', + render: (values: string | string[] | null) => { + if (Array.isArray(values)) { + return ( + + {values.map((value) => { + return {value}; + })} + + ); + } else { + return values ?? getEmptyValue(); + } + }, + }, + ], + // eslint-disable-next-line react-hooks/exhaustive-deps + [entries] + ); + + return ( + + + + + {entries.length > 1 && ( + + + + )} + + + + + + + + + + {i18n.EDIT} + + + + + {i18n.REMOVE} + + + + + + + ); +}; + +ExceptionEntriesComponent.displayName = 'ExceptionEntriesComponent'; + +export const ExceptionEntries = React.memo(ExceptionEntriesComponent); + +ExceptionEntries.displayName = 'ExceptionEntries'; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx new file mode 100644 index 0000000000000..7d3b7195def80 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx @@ -0,0 +1,116 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { ThemeProvider } from 'styled-components'; +import { mount } from 'enzyme'; +import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; + +import { ExceptionItem } from './'; +import { getExceptionItemMock } from '../mocks'; + +describe('ExceptionItem', () => { + it('it renders ExceptionDetails and ExceptionEntries', () => { + const exceptionItem = getExceptionItemMock(); + + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('ExceptionDetails')).toHaveLength(1); + expect(wrapper.find('ExceptionEntries')).toHaveLength(1); + }); + + it('it invokes "handleEdit" when edit button clicked', () => { + const mockHandleEdit = jest.fn(); + const exceptionItem = getExceptionItemMock(); + + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + const editBtn = wrapper.find('[data-test-subj="exceptionsViewerEditBtn"] button').at(0); + editBtn.simulate('click'); + + expect(mockHandleEdit).toHaveBeenCalledTimes(1); + }); + + it('it invokes "handleDelete" when delete button clicked', () => { + const mockHandleDelete = jest.fn(); + const exceptionItem = getExceptionItemMock(); + + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + const editBtn = wrapper.find('[data-test-subj="exceptionsViewerDeleteBtn"] button').at(0); + editBtn.simulate('click'); + + expect(mockHandleDelete).toHaveBeenCalledTimes(1); + }); + + it('it renders comment accordion closed to begin with', () => { + const mockHandleDelete = jest.fn(); + const exceptionItem = getExceptionItemMock(); + + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('.euiAccordion-isOpen')).toHaveLength(0); + }); + + it('it renders comment accordion open when showComments is true', () => { + const mockHandleDelete = jest.fn(); + const exceptionItem = getExceptionItemMock(); + + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + const commentsBtn = wrapper + .find('.euiButtonEmpty[data-test-subj="exceptionsViewerItemCommentsBtn"]') + .at(0); + commentsBtn.simulate('click'); + + expect(wrapper.find('.euiAccordion-isOpen')).toHaveLength(1); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.tsx new file mode 100644 index 0000000000000..f4cdce62f56b3 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.tsx @@ -0,0 +1,99 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiPanel, + EuiFlexGroup, + EuiCommentProps, + EuiCommentList, + EuiAccordion, + EuiFlexItem, +} from '@elastic/eui'; +import React, { useEffect, useState, useMemo, useCallback } from 'react'; +import styled from 'styled-components'; + +import { ExceptionDetails } from './exception_details'; +import { ExceptionEntries } from './exception_entries'; +import { getFormattedEntries, getFormattedComments } from '../helpers'; +import { FormattedEntry, ExceptionListItemSchema } from '../types'; + +const MyFlexItem = styled(EuiFlexItem)` + &.comments--show { + padding: ${({ theme }) => theme.eui.euiSize}; + border-top: ${({ theme }) => `${theme.eui.euiBorderThin}`} + +`; + +interface ExceptionItemProps { + exceptionItem: ExceptionListItemSchema; + commentsAccordionId: string; + handleDelete: ({ id }: { id: string }) => void; + handleEdit: (item: ExceptionListItemSchema) => void; +} + +const ExceptionItemComponent = ({ + exceptionItem, + commentsAccordionId, + handleDelete, + handleEdit, +}: ExceptionItemProps): JSX.Element => { + const [entryItems, setEntryItems] = useState([]); + const [showComments, setShowComments] = useState(false); + + useEffect((): void => { + const formattedEntries = getFormattedEntries(exceptionItem.entries); + setEntryItems(formattedEntries); + }, [exceptionItem.entries]); + + const onDelete = useCallback((): void => { + handleDelete({ id: exceptionItem.id }); + }, [handleDelete, exceptionItem]); + + const onEdit = useCallback((): void => { + handleEdit(exceptionItem); + }, [handleEdit, exceptionItem]); + + const onCommentsClick = useCallback((): void => { + setShowComments(!showComments); + }, [setShowComments, showComments]); + + const formattedComments = useMemo((): EuiCommentProps[] => { + return getFormattedComments(exceptionItem.comments); + }, [exceptionItem]); + + return ( + + + + + + + + + + + + + + + + ); +}; + +ExceptionItemComponent.displayName = 'ExceptionItemComponent'; + +export const ExceptionItem = React.memo(ExceptionItemComponent); + +ExceptionItem.displayName = 'ExceptionItem'; diff --git a/x-pack/plugins/siem/public/common/components/external_link_icon/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/external_link_icon/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/external_link_icon/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/external_link_icon/index.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/external_link_icon/index.tsx b/x-pack/plugins/security_solution/public/common/components/external_link_icon/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/external_link_icon/index.tsx rename to x-pack/plugins/security_solution/public/common/components/external_link_icon/index.tsx diff --git a/x-pack/plugins/siem/public/common/components/filters_global/__snapshots__/filters_global.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/filters_global/__snapshots__/filters_global.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/filters_global/__snapshots__/filters_global.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/filters_global/__snapshots__/filters_global.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/filters_global/filters_global.test.tsx b/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/filters_global/filters_global.test.tsx rename to x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/filters_global/filters_global.tsx b/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/filters_global/filters_global.tsx rename to x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.tsx diff --git a/x-pack/plugins/siem/public/common/components/filters_global/index.tsx b/x-pack/plugins/security_solution/public/common/components/filters_global/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/filters_global/index.tsx rename to x-pack/plugins/security_solution/public/common/components/filters_global/index.tsx diff --git a/x-pack/plugins/siem/public/common/components/formatted_bytes/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/formatted_bytes/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/formatted_bytes/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/formatted_bytes/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/formatted_bytes/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/formatted_bytes/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/formatted_bytes/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/formatted_bytes/index.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/formatted_bytes/index.tsx b/x-pack/plugins/security_solution/public/common/components/formatted_bytes/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/formatted_bytes/index.tsx rename to x-pack/plugins/security_solution/public/common/components/formatted_bytes/index.tsx diff --git a/x-pack/plugins/siem/public/common/components/formatted_date/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/formatted_date/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/formatted_date/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/formatted_date/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/formatted_date/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/formatted_date/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/formatted_date/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/formatted_date/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/formatted_date/index.tsx b/x-pack/plugins/security_solution/public/common/components/formatted_date/index.tsx new file mode 100644 index 0000000000000..687d2a36da610 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/formatted_date/index.tsx @@ -0,0 +1,154 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import moment from 'moment-timezone'; +import React from 'react'; +import { FormattedRelative } from '@kbn/i18n/react'; + +import { useDateFormat, useTimeZone, useUiSetting$ } from '../../lib/kibana'; +import { getOrEmptyTagFromValue } from '../empty_value'; +import { LocalizedDateTooltip } from '../localized_date_tooltip'; +import { getMaybeDate } from './maybe_date'; + +export const PreferenceFormattedDate = React.memo<{ dateFormat?: string; value: Date }>( + /* eslint-disable-next-line react-hooks/rules-of-hooks */ + ({ value, dateFormat = useDateFormat() }) => ( + <>{moment.tz(value, useTimeZone()).format(dateFormat)} + ) +); + +PreferenceFormattedDate.displayName = 'PreferenceFormattedDate'; + +/** + * This function may be passed to `Array.find()` to locate the `P1DT` + * configuration (sub) setting, a string array that contains two entries + * like the following example: `['P1DT', 'YYYY-MM-DD']`. + */ +export const isP1DTFormatterSetting = (formatNameFormatterPair?: string[]) => + Array.isArray(formatNameFormatterPair) && + formatNameFormatterPair[0] === 'P1DT' && + formatNameFormatterPair.length === 2; + +/** + * Renders a date in `P1DT` format, e.g. `YYYY-MM-DD`, as specified by + * the `P1DT1` entry in the `dateFormat:scaled` Kibana Advanced setting. + * + * If the `P1DT` format is not specified in the `dateFormat:scaled` setting, + * the fallback format `YYYY-MM-DD` will be applied + */ +export const PreferenceFormattedP1DTDate = React.memo<{ value: Date }>(({ value }) => { + /** + * A fallback "format name / formatter" 2-tuple for the `P1DT` formatter, which is + * one of many such pairs expected to be contained in the `dateFormat:scaled` + * Kibana advanced setting. + */ + const FALLBACK_DATE_FORMAT_SCALED_P1DT = ['P1DT', 'YYYY-MM-DD']; + + // Read the 'dateFormat:scaled' Kibana Advanced setting, which contains 2-tuple sub-settings: + const [scaledDateFormatPreference] = useUiSetting$('dateFormat:scaled'); + + // attempt to find the nested `['P1DT', 'formatString']` setting + const maybeP1DTFormatter = Array.isArray(scaledDateFormatPreference) + ? scaledDateFormatPreference.find(isP1DTFormatterSetting) + : null; + + const p1dtFormat = + Array.isArray(maybeP1DTFormatter) && maybeP1DTFormatter.length === 2 + ? maybeP1DTFormatter[1] + : FALLBACK_DATE_FORMAT_SCALED_P1DT[1]; + + return ; +}); + +PreferenceFormattedP1DTDate.displayName = 'PreferenceFormattedP1DTDate'; + +/** + * Renders the specified date value in a format determined by the user's preferences, + * with a tooltip that renders: + * - the name of the field + * - a humanized relative date (e.g. 16 minutes ago) + * - a long representation of the date that includes the day of the week (e.g. Thursday, March 21, 2019 6:47pm) + * - the raw date value (e.g. 2019-03-22T00:47:46Z) + */ +export const FormattedDate = React.memo<{ + fieldName: string; + value?: string | number | null; + className?: string; +}>( + ({ value, fieldName, className = '' }): JSX.Element => { + if (value == null) { + return getOrEmptyTagFromValue(value); + } + const maybeDate = getMaybeDate(value); + return maybeDate.isValid() ? ( + + + + ) : ( + getOrEmptyTagFromValue(value) + ); + } +); + +FormattedDate.displayName = 'FormattedDate'; + +/** + * Renders the specified date value according to under/over one hour + * Under an hour = relative format + * Over an hour = in a format determined by the user's preferences, + * with a tooltip that renders: + * - the name of the field + * - a humanized relative date (e.g. 16 minutes ago) + * - a long representation of the date that includes the day of the week (e.g. Thursday, March 21, 2019 6:47pm) + * - the raw date value (e.g. 2019-03-22T00:47:46Z) + */ + +export const FormattedRelativePreferenceDate = ({ value }: { value?: string | number | null }) => { + if (value == null) { + return getOrEmptyTagFromValue(value); + } + const maybeDate = getMaybeDate(value); + if (!maybeDate.isValid()) { + return getOrEmptyTagFromValue(value); + } + const date = maybeDate.toDate(); + return ( + + {moment(date).add(1, 'hours').isBefore(new Date()) ? ( + + ) : ( + + )} + + ); +}; + +/** + * Renders a preceding label according to under/over one hour + */ + +export const FormattedRelativePreferenceLabel = ({ + value, + preferenceLabel, + relativeLabel, +}: { + value?: string | number | null; + preferenceLabel?: string | null; + relativeLabel?: string | null; +}) => { + if (value == null) { + return null; + } + const maybeDate = getMaybeDate(value); + if (!maybeDate.isValid()) { + return null; + } + return moment(maybeDate.toDate()).add(1, 'hours').isBefore(new Date()) ? ( + <>{preferenceLabel} + ) : ( + <>{relativeLabel} + ); +}; diff --git a/x-pack/plugins/siem/public/common/components/formatted_date/maybe_date.test.ts b/x-pack/plugins/security_solution/public/common/components/formatted_date/maybe_date.test.ts similarity index 100% rename from x-pack/plugins/siem/public/common/components/formatted_date/maybe_date.test.ts rename to x-pack/plugins/security_solution/public/common/components/formatted_date/maybe_date.test.ts diff --git a/x-pack/plugins/siem/public/common/components/formatted_date/maybe_date.ts b/x-pack/plugins/security_solution/public/common/components/formatted_date/maybe_date.ts similarity index 100% rename from x-pack/plugins/siem/public/common/components/formatted_date/maybe_date.ts rename to x-pack/plugins/security_solution/public/common/components/formatted_date/maybe_date.ts diff --git a/x-pack/plugins/siem/public/common/components/generic_downloader/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/generic_downloader/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/generic_downloader/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/generic_downloader/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/generic_downloader/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/generic_downloader/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/generic_downloader/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/generic_downloader/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/generic_downloader/index.tsx b/x-pack/plugins/security_solution/public/common/components/generic_downloader/index.tsx new file mode 100644 index 0000000000000..2e8d5f77afc83 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/generic_downloader/index.tsx @@ -0,0 +1,108 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useEffect, useRef } from 'react'; +import styled from 'styled-components'; +import { isFunction } from 'lodash/fp'; +import * as i18n from './translations'; + +import { ExportDocumentsProps } from '../../../alerts/containers/detection_engine/rules'; +import { useStateToaster, errorToToaster } from '../toasters'; + +const InvisibleAnchor = styled.a` + display: none; +`; + +export type ExportSelectedData = ({ + excludeExportDetails, + filename, + ids, + signal, +}: ExportDocumentsProps) => Promise; + +export interface GenericDownloaderProps { + filename: string; + ids?: string[]; + exportSelectedData: ExportSelectedData; + onExportSuccess?: (exportCount: number) => void; + onExportFailure?: () => void; +} + +/** + * Component for downloading Rules as an exported .ndjson file. Download will occur on each update to `rules` param + * + * @param filename of file to be downloaded + * @param payload Rule[] + * + */ + +export const GenericDownloaderComponent = ({ + exportSelectedData, + filename, + ids, + onExportSuccess, + onExportFailure, +}: GenericDownloaderProps) => { + const anchorRef = useRef(null); + const [, dispatchToaster] = useStateToaster(); + + useEffect(() => { + let isSubscribed = true; + const abortCtrl = new AbortController(); + + const exportData = async () => { + if (anchorRef && anchorRef.current && ids != null && ids.length > 0) { + try { + const exportResponse = await exportSelectedData({ + ids, + signal: abortCtrl.signal, + }); + + if (isSubscribed) { + // this is for supporting IE + if (isFunction(window.navigator.msSaveOrOpenBlob)) { + window.navigator.msSaveBlob(exportResponse); + } else { + const objectURL = window.URL.createObjectURL(exportResponse); + // These are safe-assignments as writes to anchorRef are isolated to exportData + anchorRef.current.href = objectURL; // eslint-disable-line require-atomic-updates + anchorRef.current.download = filename; // eslint-disable-line require-atomic-updates + anchorRef.current.click(); + window.URL.revokeObjectURL(objectURL); + } + + if (onExportSuccess != null) { + onExportSuccess(ids.length); + } + } + } catch (error) { + if (isSubscribed) { + if (onExportFailure != null) { + onExportFailure(); + } + errorToToaster({ title: i18n.EXPORT_FAILURE, error, dispatchToaster }); + } + } + } + }; + + exportData(); + + return () => { + isSubscribed = false; + abortCtrl.abort(); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [ids]); + + return ; +}; + +GenericDownloaderComponent.displayName = 'GenericDownloaderComponent'; + +export const GenericDownloader = React.memo(GenericDownloaderComponent); + +GenericDownloader.displayName = 'GenericDownloader'; diff --git a/x-pack/plugins/security_solution/public/common/components/generic_downloader/translations.ts b/x-pack/plugins/security_solution/public/common/components/generic_downloader/translations.ts new file mode 100644 index 0000000000000..867c908bbacd3 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/generic_downloader/translations.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const EXPORT_FAILURE = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.components.ruleDownloader.exportFailureTitle', + { + defaultMessage: 'Failed to export rules…', + } +); diff --git a/x-pack/plugins/siem/public/common/components/header_global/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/header_global/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/header_global/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/header_global/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/header_global/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/header_global/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/header_global/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/header_global/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/header_global/index.tsx b/x-pack/plugins/security_solution/public/common/components/header_global/index.tsx new file mode 100644 index 0000000000000..c9085b5953817 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/header_global/index.tsx @@ -0,0 +1,105 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink } from '@elastic/eui'; +import { pickBy } from 'lodash/fp'; +import React from 'react'; +import styled, { css } from 'styled-components'; + +import { useLocation } from 'react-router-dom'; +import { gutterTimeline } from '../../lib/helpers'; +import { navTabs } from '../../../app/home/home_navigations'; +import { SiemPageName } from '../../../app/types'; +import { getOverviewUrl } from '../link_to'; +import { MlPopover } from '../ml_popover/ml_popover'; +import { SiemNavigation } from '../navigation'; +import * as i18n from './translations'; +import { indicesExistOrDataTemporarilyUnavailable, WithSource } from '../../containers/source'; +import { ADD_DATA_PATH } from '../../../../common/constants'; + +const Wrapper = styled.header` + ${({ theme }) => css` + background: ${theme.eui.euiColorEmptyShade}; + border-bottom: ${theme.eui.euiBorderThin}; + padding: ${theme.eui.paddingSizes.m} ${gutterTimeline} ${theme.eui.paddingSizes.m} + ${theme.eui.paddingSizes.l}; + `} +`; +Wrapper.displayName = 'Wrapper'; + +const FlexItem = styled(EuiFlexItem)` + min-width: 0; +`; +FlexItem.displayName = 'FlexItem'; + +interface HeaderGlobalProps { + hideDetectionEngine?: boolean; +} +export const HeaderGlobal = React.memo(({ hideDetectionEngine = false }) => { + const currentLocation = useLocation(); + + return ( + + + + {({ indicesExist }) => ( + <> + + + + + + + + + + {indicesExistOrDataTemporarilyUnavailable(indicesExist) ? ( + key !== SiemPageName.detections, navTabs) + : navTabs + } + /> + ) : ( + key === SiemPageName.overview, navTabs)} + /> + )} + + + + + + + {indicesExistOrDataTemporarilyUnavailable(indicesExist) && + currentLocation.pathname.includes(`/${SiemPageName.detections}/`) && ( + + + + )} + + + + {i18n.BUTTON_ADD_DATA} + + + + + + )} + + + + ); +}); +HeaderGlobal.displayName = 'HeaderGlobal'; diff --git a/x-pack/plugins/security_solution/public/common/components/header_global/translations.ts b/x-pack/plugins/security_solution/public/common/components/header_global/translations.ts new file mode 100644 index 0000000000000..f67f665434a96 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/header_global/translations.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const SIEM = i18n.translate('xpack.securitySolution.headerGlobal.siem', { + defaultMessage: 'SIEM', +}); + +export const BUTTON_ADD_DATA = i18n.translate('xpack.securitySolution.headerGlobal.buttonAddData', { + defaultMessage: 'Add data', +}); diff --git a/x-pack/plugins/siem/public/common/components/header_page/__snapshots__/editable_title.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/header_page/__snapshots__/editable_title.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/header_page/__snapshots__/editable_title.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/header_page/__snapshots__/editable_title.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/header_page/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/header_page/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/header_page/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/header_page/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/header_page/__snapshots__/title.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/header_page/__snapshots__/title.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/header_page/__snapshots__/title.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/header_page/__snapshots__/title.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/header_page/editable_title.test.tsx b/x-pack/plugins/security_solution/public/common/components/header_page/editable_title.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/header_page/editable_title.test.tsx rename to x-pack/plugins/security_solution/public/common/components/header_page/editable_title.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/header_page/editable_title.tsx b/x-pack/plugins/security_solution/public/common/components/header_page/editable_title.tsx similarity index 98% rename from x-pack/plugins/siem/public/common/components/header_page/editable_title.tsx rename to x-pack/plugins/security_solution/public/common/components/header_page/editable_title.tsx index 0c6f7258d09dc..6f6c94a0b1124 100644 --- a/x-pack/plugins/siem/public/common/components/header_page/editable_title.tsx +++ b/x-pack/plugins/security_solution/public/common/components/header_page/editable_title.tsx @@ -57,6 +57,7 @@ const EditableTitleComponent: React.FC = ({ onSubmit(changedTitle); } setEditMode(false); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [changedTitle, title]); const handleOnChange = useCallback( diff --git a/x-pack/plugins/siem/public/common/components/header_page/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/header_page/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/header_page/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/header_page/index.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/header_page/index.tsx b/x-pack/plugins/security_solution/public/common/components/header_page/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/header_page/index.tsx rename to x-pack/plugins/security_solution/public/common/components/header_page/index.tsx diff --git a/x-pack/plugins/siem/public/common/components/header_page/title.test.tsx b/x-pack/plugins/security_solution/public/common/components/header_page/title.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/header_page/title.test.tsx rename to x-pack/plugins/security_solution/public/common/components/header_page/title.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/header_page/title.tsx b/x-pack/plugins/security_solution/public/common/components/header_page/title.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/header_page/title.tsx rename to x-pack/plugins/security_solution/public/common/components/header_page/title.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/header_page/translations.ts b/x-pack/plugins/security_solution/public/common/components/header_page/translations.ts new file mode 100644 index 0000000000000..43ad4b08d60a9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/header_page/translations.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const SAVE = i18n.translate('xpack.securitySolution.header.editableTitle.save', { + defaultMessage: 'Save', +}); + +export const CANCEL = i18n.translate('xpack.securitySolution.header.editableTitle.cancel', { + defaultMessage: 'Cancel', +}); + +export const EDIT_TITLE_ARIA = (title: string) => + i18n.translate('xpack.securitySolution.header.editableTitle.editButtonAria', { + values: { title }, + defaultMessage: 'You can edit {title} by clicking', + }); diff --git a/x-pack/plugins/siem/public/common/components/header_page/types.ts b/x-pack/plugins/security_solution/public/common/components/header_page/types.ts similarity index 100% rename from x-pack/plugins/siem/public/common/components/header_page/types.ts rename to x-pack/plugins/security_solution/public/common/components/header_page/types.ts diff --git a/x-pack/plugins/siem/public/common/components/header_section/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/header_section/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/header_section/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/header_section/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/header_section/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/header_section/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/header_section/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/header_section/index.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/header_section/index.tsx b/x-pack/plugins/security_solution/public/common/components/header_section/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/header_section/index.tsx rename to x-pack/plugins/security_solution/public/common/components/header_section/index.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/help_menu/index.tsx b/x-pack/plugins/security_solution/public/common/components/help_menu/index.tsx new file mode 100644 index 0000000000000..56f0c825aa59e --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/help_menu/index.tsx @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useEffect } from 'react'; +import { i18n } from '@kbn/i18n'; +import { useKibana } from '../../lib/kibana'; + +export const HelpMenu = React.memo(() => { + const { chrome, docLinks } = useKibana().services; + + useEffect(() => { + chrome.setHelpExtension({ + appName: i18n.translate('xpack.securitySolution.chrome.help.appName', { + defaultMessage: 'SIEM', + }), + links: [ + { + content: i18n.translate('xpack.securitySolution.chrome.helpMenu.documentation', { + defaultMessage: 'SIEM documentation', + }), + href: docLinks.links.siem.guide, + iconType: 'documents', + linkType: 'custom', + target: '_blank', + rel: 'noopener', + }, + { + content: i18n.translate('xpack.securitySolution.chrome.helpMenu.documentation.ecs', { + defaultMessage: 'ECS documentation', + }), + href: `${docLinks.ELASTIC_WEBSITE_URL}guide/en/ecs/current/index.html`, + iconType: 'documents', + linkType: 'custom', + target: '_blank', + rel: 'noopener', + }, + { + linkType: 'discuss', + href: 'https://discuss.elastic.co/c/siem', + target: '_blank', + rel: 'noopener', + }, + ], + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return null; +}); + +HelpMenu.displayName = 'HelpMenu'; diff --git a/x-pack/plugins/siem/public/common/components/import_data_modal/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/import_data_modal/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/import_data_modal/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/import_data_modal/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/import_data_modal/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/import_data_modal/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/import_data_modal/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/import_data_modal/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/import_data_modal/index.tsx b/x-pack/plugins/security_solution/public/common/components/import_data_modal/index.tsx new file mode 100644 index 0000000000000..a42628cecff8e --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/import_data_modal/index.tsx @@ -0,0 +1,177 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiButton, + EuiButtonEmpty, + EuiCheckbox, + // @ts-ignore no-exported-member + EuiFilePicker, + EuiModal, + EuiModalBody, + EuiModalFooter, + EuiModalHeader, + EuiModalHeaderTitle, + EuiOverlayMask, + EuiSpacer, + EuiText, +} from '@elastic/eui'; +import React, { useCallback, useState } from 'react'; + +import { + ImportDataResponse, + ImportDataProps, +} from '../../../alerts/containers/detection_engine/rules'; +import { + displayErrorToast, + displaySuccessToast, + useStateToaster, + errorToToaster, +} from '../toasters'; +import * as i18n from './translations'; + +interface ImportDataModalProps { + checkBoxLabel: string; + closeModal: () => void; + description: string; + errorMessage: string; + failedDetailed: (id: string, statusCode: number, message: string) => string; + importComplete: () => void; + importData: (arg: ImportDataProps) => Promise; + showCheckBox: boolean; + showModal: boolean; + submitBtnText: string; + subtitle: string; + successMessage: (totalCount: number) => string; + title: string; +} + +/** + * Modal component for importing Rules from a json file + */ +export const ImportDataModalComponent = ({ + checkBoxLabel, + closeModal, + description, + errorMessage, + failedDetailed, + importComplete, + importData, + showCheckBox = true, + showModal, + submitBtnText, + subtitle, + successMessage, + title, +}: ImportDataModalProps) => { + const [selectedFiles, setSelectedFiles] = useState(null); + const [isImporting, setIsImporting] = useState(false); + const [overwrite, setOverwrite] = useState(false); + const [, dispatchToaster] = useStateToaster(); + + const cleanupAndCloseModal = useCallback(() => { + setIsImporting(false); + setSelectedFiles(null); + closeModal(); + }, [setIsImporting, setSelectedFiles, closeModal]); + + const importDataCallback = useCallback(async () => { + if (selectedFiles != null) { + setIsImporting(true); + const abortCtrl = new AbortController(); + + try { + const importResponse = await importData({ + fileToImport: selectedFiles[0], + overwrite, + signal: abortCtrl.signal, + }); + + // TODO: Improve error toast details for better debugging failed imports + // e.g. When success == true && success_count === 0 that means no rules were overwritten, etc + if (importResponse.success) { + displaySuccessToast(successMessage(importResponse.success_count), dispatchToaster); + } + if (importResponse.errors.length > 0) { + const formattedErrors = importResponse.errors.map((e) => + failedDetailed(e.rule_id, e.error.status_code, e.error.message) + ); + displayErrorToast(errorMessage, formattedErrors, dispatchToaster); + } + + importComplete(); + cleanupAndCloseModal(); + } catch (error) { + cleanupAndCloseModal(); + errorToToaster({ title: errorMessage, error, dispatchToaster }); + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [selectedFiles, overwrite]); + + const handleCloseModal = useCallback(() => { + setSelectedFiles(null); + closeModal(); + }, [closeModal]); + + return ( + <> + {showModal && ( + + + + {title} + + + + +

{description}

+
+ + + { + setSelectedFiles(files && files.length > 0 ? files : null); + }} + display={'large'} + fullWidth={true} + isLoading={isImporting} + /> + + {showCheckBox && ( + setOverwrite(!overwrite)} + /> + )} +
+ + + {i18n.CANCEL_BUTTON} + + {submitBtnText} + + +
+
+ )} + + ); +}; + +ImportDataModalComponent.displayName = 'ImportDataModalComponent'; + +export const ImportDataModal = React.memo(ImportDataModalComponent); + +ImportDataModal.displayName = 'ImportDataModal'; diff --git a/x-pack/plugins/security_solution/public/common/components/import_data_modal/translations.ts b/x-pack/plugins/security_solution/public/common/components/import_data_modal/translations.ts new file mode 100644 index 0000000000000..1bd64d191167b --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/import_data_modal/translations.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const CANCEL_BUTTON = i18n.translate( + 'xpack.securitySolution.detectionEngine.components.importRuleModal.cancelTitle', + { + defaultMessage: 'Cancel', + } +); diff --git a/x-pack/plugins/siem/public/common/components/inspect/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/inspect/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/inspect/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/inspect/index.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/inspect/index.tsx b/x-pack/plugins/security_solution/public/common/components/inspect/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/inspect/index.tsx rename to x-pack/plugins/security_solution/public/common/components/inspect/index.tsx diff --git a/x-pack/plugins/siem/public/common/components/inspect/modal.test.tsx b/x-pack/plugins/security_solution/public/common/components/inspect/modal.test.tsx similarity index 87% rename from x-pack/plugins/siem/public/common/components/inspect/modal.test.tsx rename to x-pack/plugins/security_solution/public/common/components/inspect/modal.test.tsx index 153a1703059c2..3451ddacb6538 100644 --- a/x-pack/plugins/siem/public/common/components/inspect/modal.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/inspect/modal.test.tsx @@ -9,7 +9,8 @@ import { mount } from 'enzyme'; import React from 'react'; import { ThemeProvider } from 'styled-components'; -import { ModalInspectQuery } from './modal'; +import { NO_ALERT_INDEX } from '../../../../common/constants'; +import { ModalInspectQuery, formatIndexPatternRequested } from './modal'; const request = '{"index": ["auditbeat-*","filebeat-*","packetbeat-*","winlogbeat-*"],"allowNoIndices": true, "ignoreUnavailable": true, "body": { "aggregations": {"hosts": {"cardinality": {"field": "host.name" } }, "hosts_histogram": {"auto_date_histogram": {"field": "@timestamp","buckets": "6"},"aggs": { "count": {"cardinality": {"field": "host.name" }}}}}, "query": {"bool": {"filter": [{"range": { "@timestamp": {"gte": 1562290224506,"lte": 1562376624506 }}}]}}, "size": 0, "track_total_hits": false}}'; @@ -244,4 +245,31 @@ describe('Modal Inspect', () => { expect(closeModal).toHaveBeenCalled(); }); }); + + describe('formatIndexPatternRequested', () => { + test('Return specific messages to NO_ALERT_INDEX if we only have one index and we match the index name `NO_ALERT_INDEX`', () => { + const expected = formatIndexPatternRequested([NO_ALERT_INDEX]); + expect(expected).toEqual({'No alert index found'}); + }); + + test('Ignore NO_ALERT_INDEX if you have more than one indices', () => { + const expected = formatIndexPatternRequested([NO_ALERT_INDEX, 'indice-1']); + expect(expected).toEqual('indice-1'); + }); + + test('Happy path', () => { + const expected = formatIndexPatternRequested(['indice-1, indice-2']); + expect(expected).toEqual('indice-1, indice-2'); + }); + + test('Empty array with no indices', () => { + const expected = formatIndexPatternRequested([]); + expect(expected).toEqual('Sorry about that, something went wrong.'); + }); + + test('Undefined indices', () => { + const expected = formatIndexPatternRequested(undefined); + expect(expected).toEqual('Sorry about that, something went wrong.'); + }); + }); }); diff --git a/x-pack/plugins/siem/public/common/components/inspect/modal.tsx b/x-pack/plugins/security_solution/public/common/components/inspect/modal.tsx similarity index 92% rename from x-pack/plugins/siem/public/common/components/inspect/modal.tsx rename to x-pack/plugins/security_solution/public/common/components/inspect/modal.tsx index 1563c005af5b6..e9f7edf86d4ba 100644 --- a/x-pack/plugins/siem/public/common/components/inspect/modal.tsx +++ b/x-pack/plugins/security_solution/public/common/components/inspect/modal.tsx @@ -22,6 +22,7 @@ import numeral from '@elastic/numeral'; import React, { ReactNode } from 'react'; import styled from 'styled-components'; +import { NO_ALERT_INDEX } from '../../../../common/constants'; import * as i18n from './translations'; const DescriptionListStyled = styled(EuiDescriptionList)` @@ -88,6 +89,15 @@ const manageStringify = (object: Record | Response): string => } }; +export const formatIndexPatternRequested = (indices: string[] = []) => { + if (indices.length === 1 && indices[0] === NO_ALERT_INDEX) { + return {i18n.NO_ALERT_INDEX_FOUND}; + } + return indices.length > 0 + ? indices.filter((i) => i !== NO_ALERT_INDEX).join(', ') + : i18n.SOMETHING_WENT_WRONG; +}; + export const ModalInspectQuery = ({ closeModal, isShowing = false, @@ -113,7 +123,7 @@ export const ModalInspectQuery = ({ ), description: ( - {inspectRequest != null ? inspectRequest.index.join(', ') : i18n.SOMETHING_WENT_WRONG} + {formatIndexPatternRequested(inspectRequest?.index ?? [])} ), }, diff --git a/x-pack/plugins/security_solution/public/common/components/inspect/translations.ts b/x-pack/plugins/security_solution/public/common/components/inspect/translations.ts new file mode 100644 index 0000000000000..4a8da8050dd9a --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/inspect/translations.ts @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const INSPECT = i18n.translate('xpack.securitySolution.inspectDescription', { + defaultMessage: 'Inspect', +}); + +export const CLOSE = i18n.translate('xpack.securitySolution.inspect.modal.closeTitle', { + defaultMessage: 'Close', +}); + +export const SOMETHING_WENT_WRONG = i18n.translate( + 'xpack.securitySolution.inspect.modal.somethingWentWrongDescription', + { + defaultMessage: 'Sorry about that, something went wrong.', + } +); +export const INDEX_PATTERN = i18n.translate( + 'xpack.securitySolution.inspect.modal.indexPatternLabel', + { + defaultMessage: 'Index pattern', + } +); + +export const INDEX_PATTERN_DESC = i18n.translate( + 'xpack.securitySolution.inspect.modal.indexPatternDescription', + { + defaultMessage: + 'The index pattern that connected to the Elasticsearch indices. These indices can be configured in Kibana > Advanced Settings.', + } +); + +export const QUERY_TIME = i18n.translate('xpack.securitySolution.inspect.modal.queryTimeLabel', { + defaultMessage: 'Query time', +}); + +export const QUERY_TIME_DESC = i18n.translate( + 'xpack.securitySolution.inspect.modal.queryTimeDescription', + { + defaultMessage: + 'The time it took to process the query. Does not include the time to send the request or parse it in the browser.', + } +); + +export const REQUEST_TIMESTAMP = i18n.translate( + 'xpack.securitySolution.inspect.modal.reqTimestampLabel', + { + defaultMessage: 'Request timestamp', + } +); + +export const REQUEST_TIMESTAMP_DESC = i18n.translate( + 'xpack.securitySolution.inspect.modal.reqTimestampDescription', + { + defaultMessage: 'Time when the start of the request has been logged', + } +); + +export const NO_ALERT_INDEX_FOUND = i18n.translate( + 'xpack.securitySolution.inspect.modal.noAlertIndexFound', + { + defaultMessage: 'No alert index found', + } +); diff --git a/x-pack/plugins/siem/public/common/components/last_event_time/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/last_event_time/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/last_event_time/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/last_event_time/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/last_event_time/index.tsx b/x-pack/plugins/security_solution/public/common/components/last_event_time/index.tsx new file mode 100644 index 0000000000000..35a891c21aa8a --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/last_event_time/index.tsx @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiIcon, EuiLoadingSpinner, EuiToolTip } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import React, { memo } from 'react'; + +import { LastEventIndexKey } from '../../../graphql/types'; +import { useLastEventTimeQuery } from '../../containers/events/last_event_time'; +import { getEmptyTagValue } from '../empty_value'; +import { FormattedRelativePreferenceDate } from '../formatted_date'; + +export interface LastEventTimeProps { + hostName?: string; + indexKey: LastEventIndexKey; + ip?: string; +} + +export const LastEventTime = memo(({ hostName, indexKey, ip }) => { + const { loading, lastSeen, errorMessage } = useLastEventTimeQuery( + indexKey, + { hostName, ip }, + 'default' + ); + + if (errorMessage != null) { + return ( + + + + ); + } + + return ( + <> + {loading && } + {!loading && lastSeen != null && new Date(lastSeen).toString() === 'Invalid Date' + ? lastSeen + : !loading && + lastSeen != null && ( + , + }} + /> + )} + {!loading && lastSeen == null && getEmptyTagValue()} + + ); +}); + +LastEventTime.displayName = 'LastEventTime'; diff --git a/x-pack/plugins/siem/public/common/components/link_icon/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/link_icon/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/link_icon/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/link_icon/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/link_icon/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/link_icon/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/link_icon/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/link_icon/index.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/link_icon/index.tsx b/x-pack/plugins/security_solution/public/common/components/link_icon/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/link_icon/index.tsx rename to x-pack/plugins/security_solution/public/common/components/link_icon/index.tsx diff --git a/x-pack/plugins/siem/public/common/components/link_to/helpers.test.ts b/x-pack/plugins/security_solution/public/common/components/link_to/helpers.test.ts similarity index 100% rename from x-pack/plugins/siem/public/common/components/link_to/helpers.test.ts rename to x-pack/plugins/security_solution/public/common/components/link_to/helpers.test.ts diff --git a/x-pack/plugins/siem/public/common/components/link_to/helpers.ts b/x-pack/plugins/security_solution/public/common/components/link_to/helpers.ts similarity index 100% rename from x-pack/plugins/siem/public/common/components/link_to/helpers.ts rename to x-pack/plugins/security_solution/public/common/components/link_to/helpers.ts diff --git a/x-pack/plugins/siem/public/common/components/link_to/index.ts b/x-pack/plugins/security_solution/public/common/components/link_to/index.ts similarity index 100% rename from x-pack/plugins/siem/public/common/components/link_to/index.ts rename to x-pack/plugins/security_solution/public/common/components/link_to/index.ts diff --git a/x-pack/plugins/siem/public/common/components/link_to/link_to.tsx b/x-pack/plugins/security_solution/public/common/components/link_to/link_to.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/link_to/link_to.tsx rename to x-pack/plugins/security_solution/public/common/components/link_to/link_to.tsx diff --git a/x-pack/plugins/siem/public/common/components/link_to/redirect_to_case.tsx b/x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_case.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/link_to/redirect_to_case.tsx rename to x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_case.tsx diff --git a/x-pack/plugins/siem/public/common/components/link_to/redirect_to_detection_engine.tsx b/x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_detection_engine.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/link_to/redirect_to_detection_engine.tsx rename to x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_detection_engine.tsx diff --git a/x-pack/plugins/siem/public/common/components/link_to/redirect_to_hosts.tsx b/x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_hosts.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/link_to/redirect_to_hosts.tsx rename to x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_hosts.tsx diff --git a/x-pack/plugins/siem/public/common/components/link_to/redirect_to_management.tsx b/x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_management.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/link_to/redirect_to_management.tsx rename to x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_management.tsx diff --git a/x-pack/plugins/siem/public/common/components/link_to/redirect_to_network.tsx b/x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_network.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/link_to/redirect_to_network.tsx rename to x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_network.tsx diff --git a/x-pack/plugins/siem/public/common/components/link_to/redirect_to_overview.tsx b/x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_overview.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/link_to/redirect_to_overview.tsx rename to x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_overview.tsx diff --git a/x-pack/plugins/siem/public/common/components/link_to/redirect_to_timelines.tsx b/x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_timelines.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/link_to/redirect_to_timelines.tsx rename to x-pack/plugins/security_solution/public/common/components/link_to/redirect_to_timelines.tsx diff --git a/x-pack/plugins/siem/public/common/components/link_to/redirect_wrapper.tsx b/x-pack/plugins/security_solution/public/common/components/link_to/redirect_wrapper.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/link_to/redirect_wrapper.tsx rename to x-pack/plugins/security_solution/public/common/components/link_to/redirect_wrapper.tsx diff --git a/x-pack/plugins/siem/public/common/components/links/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/links/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/links/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/links/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/links/index.tsx b/x-pack/plugins/security_solution/public/common/components/links/index.tsx new file mode 100644 index 0000000000000..637f0d8d53057 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/links/index.tsx @@ -0,0 +1,313 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiLink, EuiToolTip, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import React, { useMemo } from 'react'; +import { isNil } from 'lodash/fp'; +import styled from 'styled-components'; + +import { IP_REPUTATION_LINKS_SETTING } from '../../../../common/constants'; +import { + DefaultFieldRendererOverflow, + DEFAULT_MORE_MAX_HEIGHT, +} from '../../../timelines/components/field_renderers/field_renderers'; +import { encodeIpv6 } from '../../lib/helpers'; +import { + getCaseDetailsUrl, + getHostDetailsUrl, + getIPDetailsUrl, + getCreateCaseUrl, +} from '../link_to'; +import { FlowTarget, FlowTargetSourceDest } from '../../../graphql/types'; +import { useUiSetting$ } from '../../lib/kibana'; +import { isUrlInvalid } from '../../utils/validators'; +import { ExternalLinkIcon } from '../external_link_icon'; +import { navTabs } from '../../../app/home/home_navigations'; +import { useGetUrlSearch } from '../navigation/use_get_url_search'; + +import * as i18n from './translations'; + +export const DEFAULT_NUMBER_OF_LINK = 5; + +// Internal Links +const HostDetailsLinkComponent: React.FC<{ children?: React.ReactNode; hostName: string }> = ({ + children, + hostName, +}) => ( + + {children ? children : hostName} + +); + +const whitelistUrlSchemes = ['http://', 'https://']; +export const ExternalLink = React.memo<{ + url: string; + children?: React.ReactNode; + idx?: number; + overflowIndexStart?: number; + allItemsLimit?: number; +}>( + ({ + url, + children, + idx, + overflowIndexStart = DEFAULT_NUMBER_OF_LINK, + allItemsLimit = DEFAULT_NUMBER_OF_LINK, + }) => { + const lastVisibleItemIndex = overflowIndexStart - 1; + const lastItemIndex = allItemsLimit - 1; + const lastIndexToShow = Math.max(0, Math.min(lastVisibleItemIndex, lastItemIndex)); + const inWhitelist = whitelistUrlSchemes.some((scheme) => url.indexOf(scheme) === 0); + return url && inWhitelist && !isUrlInvalid(url) && children ? ( + + + {children} + + {!isNil(idx) && idx < lastIndexToShow && } + + + ) : null; + } +); + +ExternalLink.displayName = 'ExternalLink'; + +export const HostDetailsLink = React.memo(HostDetailsLinkComponent); + +const IPDetailsLinkComponent: React.FC<{ + children?: React.ReactNode; + ip: string; + flowTarget?: FlowTarget | FlowTargetSourceDest; +}> = ({ children, ip, flowTarget = FlowTarget.source }) => ( + + {children ? children : ip} + +); + +export const IPDetailsLink = React.memo(IPDetailsLinkComponent); + +const CaseDetailsLinkComponent: React.FC<{ + children?: React.ReactNode; + detailName: string; + title?: string; +}> = ({ children, detailName, title }) => { + const search = useGetUrlSearch(navTabs.case); + + return ( + + {children ? children : detailName} + + ); +}; +export const CaseDetailsLink = React.memo(CaseDetailsLinkComponent); +CaseDetailsLink.displayName = 'CaseDetailsLink'; + +export const CreateCaseLink = React.memo<{ children: React.ReactNode }>(({ children }) => { + const search = useGetUrlSearch(navTabs.case); + return {children}; +}); + +CreateCaseLink.displayName = 'CreateCaseLink'; + +// External Links +export const GoogleLink = React.memo<{ children?: React.ReactNode; link: string }>( + ({ children, link }) => ( + + {children ? children : link} + + ) +); + +GoogleLink.displayName = 'GoogleLink'; + +export const PortOrServiceNameLink = React.memo<{ + children?: React.ReactNode; + portOrServiceName: number | string; +}>(({ children, portOrServiceName }) => ( + + {children ? children : portOrServiceName} + +)); + +PortOrServiceNameLink.displayName = 'PortOrServiceNameLink'; + +export const Ja3FingerprintLink = React.memo<{ + children?: React.ReactNode; + ja3Fingerprint: string; +}>(({ children, ja3Fingerprint }) => ( + + {children ? children : ja3Fingerprint} + +)); + +Ja3FingerprintLink.displayName = 'Ja3FingerprintLink'; + +export const CertificateFingerprintLink = React.memo<{ + children?: React.ReactNode; + certificateFingerprint: string; +}>(({ children, certificateFingerprint }) => ( + + {children ? children : certificateFingerprint} + +)); + +CertificateFingerprintLink.displayName = 'CertificateFingerprintLink'; + +enum DefaultReputationLink { + 'virustotal.com' = 'virustotal.com', + 'talosIntelligence.com' = 'talosIntelligence.com', +} + +export interface ReputationLinkSetting { + name: string; + url_template: string; +} + +function isDefaultReputationLink(name: string): name is DefaultReputationLink { + return ( + name === DefaultReputationLink['virustotal.com'] || + name === DefaultReputationLink['talosIntelligence.com'] + ); +} +const isReputationLink = ( + rowItem: string | ReputationLinkSetting +): rowItem is ReputationLinkSetting => + (rowItem as ReputationLinkSetting).url_template !== undefined && + (rowItem as ReputationLinkSetting).name !== undefined; + +export const Comma = styled('span')` + margin-right: 5px; + margin-left: 5px; + &::after { + content: ' ,'; + } +`; + +Comma.displayName = 'Comma'; + +const defaultNameMapping: Record = { + [DefaultReputationLink['virustotal.com']]: i18n.VIEW_VIRUS_TOTAL, + [DefaultReputationLink['talosIntelligence.com']]: i18n.VIEW_TALOS_INTELLIGENCE, +}; + +const ReputationLinkComponent: React.FC<{ + overflowIndexStart?: number; + allItemsLimit?: number; + showDomain?: boolean; + domain: string; + direction?: 'row' | 'column'; +}> = ({ + overflowIndexStart = DEFAULT_NUMBER_OF_LINK, + allItemsLimit = DEFAULT_NUMBER_OF_LINK, + showDomain = false, + domain, + direction = 'row', +}) => { + const [ipReputationLinksSetting] = useUiSetting$( + IP_REPUTATION_LINKS_SETTING + ); + + const ipReputationLinks: ReputationLinkSetting[] = useMemo( + () => + ipReputationLinksSetting + ?.slice(0, allItemsLimit) + .filter( + ({ url_template, name }) => + !isNil(url_template) && !isNil(name) && !isUrlInvalid(url_template) + ) + .map(({ name, url_template }: { name: string; url_template: string }) => ({ + name: isDefaultReputationLink(name) ? defaultNameMapping[name] : name, + url_template: url_template.replace(`{{ip}}`, encodeURIComponent(domain)), + })), + // eslint-disable-next-line react-hooks/exhaustive-deps + [ipReputationLinksSetting, domain, defaultNameMapping, allItemsLimit] + ); + + return ipReputationLinks?.length > 0 ? ( +
+ + + {ipReputationLinks + ?.slice(0, overflowIndexStart) + .map(({ name, url_template: urlTemplate }: ReputationLinkSetting, id) => ( + + <>{showDomain ? domain : name ?? domain} + + ))} + + + + { + return ( + isReputationLink(rowItem) && ( + + <>{rowItem.name ?? domain} + + ) + ); + }} + moreMaxHeight={DEFAULT_MORE_MAX_HEIGHT} + overflowIndexStart={overflowIndexStart} + /> + + +
+ ) : null; +}; + +ReputationLinkComponent.displayName = 'ReputationLinkComponent'; + +export const ReputationLink = React.memo(ReputationLinkComponent); + +export const WhoIsLink = React.memo<{ children?: React.ReactNode; domain: string }>( + ({ children, domain }) => ( + + {children ? children : domain} + + ) +); + +WhoIsLink.displayName = 'WhoIsLink'; diff --git a/x-pack/plugins/security_solution/public/common/components/links/translations.ts b/x-pack/plugins/security_solution/public/common/components/links/translations.ts new file mode 100644 index 0000000000000..cf7db8bfa8161 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/links/translations.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export * from '../../../network/components/ip_overview/translations'; + +export const CASE_DETAILS_LINK_ARIA = (detailName: string) => + i18n.translate('xpack.securitySolution.case.caseTable.caseDetailsLinkAria', { + values: { detailName }, + defaultMessage: 'click to visit case with title {detailName}', + }); diff --git a/x-pack/plugins/siem/public/common/components/loader/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/loader/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/loader/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/loader/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/loader/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/loader/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/loader/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/loader/index.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/loader/index.tsx b/x-pack/plugins/security_solution/public/common/components/loader/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/loader/index.tsx rename to x-pack/plugins/security_solution/public/common/components/loader/index.tsx diff --git a/x-pack/plugins/siem/public/common/components/localized_date_tooltip/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/localized_date_tooltip/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/localized_date_tooltip/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/localized_date_tooltip/index.test.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/localized_date_tooltip/index.tsx b/x-pack/plugins/security_solution/public/common/components/localized_date_tooltip/index.tsx new file mode 100644 index 0000000000000..d8f8742cb4364 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/localized_date_tooltip/index.tsx @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; +import { FormattedRelative } from '@kbn/i18n/react'; +import moment from 'moment'; +import React from 'react'; + +export const LocalizedDateTooltip = React.memo<{ + children: React.ReactNode; + date: Date; + fieldName?: string; + className?: string; +}>(({ children, date, fieldName, className = '' }) => ( + + {fieldName != null ? ( + + {fieldName} + + ) : null} + + + + + {moment.utc(date).local().format('llll')} + + + {moment(date).format()} + + + } + > + <>{children} + +)); + +LocalizedDateTooltip.displayName = 'LocalizedDateTooltip'; diff --git a/x-pack/plugins/siem/public/common/components/markdown/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/markdown/__snapshots__/index.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/markdown/__snapshots__/index.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/markdown/__snapshots__/index.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/markdown/__snapshots__/markdown_hint.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/markdown/__snapshots__/markdown_hint.test.tsx.snap similarity index 100% rename from x-pack/plugins/siem/public/common/components/markdown/__snapshots__/markdown_hint.test.tsx.snap rename to x-pack/plugins/security_solution/public/common/components/markdown/__snapshots__/markdown_hint.test.tsx.snap diff --git a/x-pack/plugins/siem/public/common/components/markdown/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/markdown/index.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/markdown/index.test.tsx rename to x-pack/plugins/security_solution/public/common/components/markdown/index.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/markdown/index.tsx b/x-pack/plugins/security_solution/public/common/components/markdown/index.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/markdown/index.tsx rename to x-pack/plugins/security_solution/public/common/components/markdown/index.tsx diff --git a/x-pack/plugins/siem/public/common/components/markdown/markdown_hint.test.tsx b/x-pack/plugins/security_solution/public/common/components/markdown/markdown_hint.test.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/markdown/markdown_hint.test.tsx rename to x-pack/plugins/security_solution/public/common/components/markdown/markdown_hint.test.tsx diff --git a/x-pack/plugins/siem/public/common/components/markdown/markdown_hint.tsx b/x-pack/plugins/security_solution/public/common/components/markdown/markdown_hint.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/markdown/markdown_hint.tsx rename to x-pack/plugins/security_solution/public/common/components/markdown/markdown_hint.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/markdown/translations.ts b/x-pack/plugins/security_solution/public/common/components/markdown/translations.ts new file mode 100644 index 0000000000000..98d2e7d47b3fb --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/markdown/translations.ts @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const MARKDOWN_HINT_HEADING = i18n.translate( + 'xpack.securitySolution.markdown.hint.headingLabel', + { + defaultMessage: '# heading', + } +); + +export const MARKDOWN_HINT_BOLD = i18n.translate('xpack.securitySolution.markdown.hint.boldLabel', { + defaultMessage: '**bold**', +}); + +export const MARKDOWN_HINT_ITALICS = i18n.translate( + 'xpack.securitySolution.markdown.hint.italicsLabel', + { + defaultMessage: '_italics_', + } +); + +export const MARKDOWN_HINT_CODE = i18n.translate('xpack.securitySolution.markdown.hint.codeLabel', { + defaultMessage: '`code`', +}); + +export const MARKDOWN_HINT_URL = i18n.translate('xpack.securitySolution.markdown.hint.urlLabel', { + defaultMessage: '[link](url)', +}); + +export const MARKDOWN_HINT_BULLET = i18n.translate( + 'xpack.securitySolution.markdown.hint.bulletLabel', + { + defaultMessage: '* bullet', + } +); + +export const MARKDOWN_HINT_PREFORMATTED = i18n.translate( + 'xpack.securitySolution.markdown.hint.preformattedLabel', + { + defaultMessage: '```preformatted```', + } +); + +export const MARKDOWN_HINT_QUOTE = i18n.translate( + 'xpack.securitySolution.markdown.hint.quoteLabel', + { + defaultMessage: '>quote', + } +); + +export const MARKDOWN_HINT_STRIKETHROUGH = i18n.translate( + 'xpack.securitySolution.markdown.hint.strikethroughLabel', + { + defaultMessage: 'strikethrough', + } +); + +export const MARKDOWN_HINT_IMAGE_URL = i18n.translate( + 'xpack.securitySolution.markdown.hint.imageUrlLabel', + { + defaultMessage: '![image](url)', + } +); + +export const TIMELINE_ID = (timelineId: string) => + i18n.translate('xpack.securitySolution.markdown.toolTip.timelineId', { + defaultMessage: 'Timeline id: { timelineId }', + values: { + timelineId, + }, + }); diff --git a/x-pack/plugins/siem/public/common/components/markdown_editor/constants.ts b/x-pack/plugins/security_solution/public/common/components/markdown_editor/constants.ts similarity index 100% rename from x-pack/plugins/siem/public/common/components/markdown_editor/constants.ts rename to x-pack/plugins/security_solution/public/common/components/markdown_editor/constants.ts diff --git a/x-pack/plugins/siem/public/common/components/markdown_editor/form.tsx b/x-pack/plugins/security_solution/public/common/components/markdown_editor/form.tsx similarity index 100% rename from x-pack/plugins/siem/public/common/components/markdown_editor/form.tsx rename to x-pack/plugins/security_solution/public/common/components/markdown_editor/form.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/markdown_editor/index.tsx b/x-pack/plugins/security_solution/public/common/components/markdown_editor/index.tsx new file mode 100644 index 0000000000000..d92952992d997 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/markdown_editor/index.tsx @@ -0,0 +1,169 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiFlexGroup, + EuiFlexItem, + EuiLink, + EuiPanel, + EuiTabbedContent, + EuiTextArea, +} from '@elastic/eui'; +import React, { useMemo, useCallback, ChangeEvent } from 'react'; +import styled, { css } from 'styled-components'; + +import { Markdown } from '../markdown'; +import * as i18n from './translations'; +import { MARKDOWN_HELP_LINK } from './constants'; + +const TextArea = styled(EuiTextArea)` + width: 100%; +`; + +const Container = styled(EuiPanel)` + ${({ theme }) => css` + padding: 0; + background: ${theme.eui.euiColorLightestShade}; + position: relative; + .markdown-tabs-header { + position: absolute; + top: ${theme.eui.euiSizeS}; + right: ${theme.eui.euiSizeS}; + z-index: ${theme.eui.euiZContentMenu}; + } + .euiTab { + padding: 10px; + } + .markdown-tabs { + width: 100%; + } + .markdown-tabs-footer { + height: 41px; + padding: 0 ${theme.eui.euiSizeM}; + .euiLink { + font-size: ${theme.eui.euiSizeM}; + } + } + .euiFormRow__labelWrapper { + position: absolute; + top: -${theme.eui.euiSizeL}; + } + .euiFormErrorText { + padding: 0 ${theme.eui.euiSizeM}; + } + `} +`; + +const MarkdownContainer = styled(EuiPanel)` + min-height: 150px; + overflow: auto; +`; + +export interface CursorPosition { + start: number; + end: number; +} + +/** An input for entering a new case description */ +export const MarkdownEditor = React.memo<{ + bottomRightContent?: React.ReactNode; + topRightContent?: React.ReactNode; + content: string; + isDisabled?: boolean; + onChange: (description: string) => void; + onClickTimeline?: (timelineId: string) => void; + onCursorPositionUpdate?: (cursorPosition: CursorPosition) => void; + placeholder?: string; +}>( + ({ + bottomRightContent, + topRightContent, + content, + isDisabled = false, + onChange, + onClickTimeline, + placeholder, + onCursorPositionUpdate, + }) => { + const handleOnChange = useCallback( + (evt: ChangeEvent) => { + onChange(evt.target.value); + }, + [onChange] + ); + + const setCursorPosition = (e: React.ChangeEvent) => { + if (onCursorPositionUpdate) { + onCursorPositionUpdate({ + start: e!.target!.selectionStart ?? 0, + end: e!.target!.selectionEnd ?? 0, + }); + } + return false; + }; + + const tabs = useMemo( + () => [ + { + id: 'comment', + name: i18n.MARKDOWN, + content: ( +